src/share/vm/opto/loopnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
5091921 Cdiff src/share/vm/opto/loopnode.cpp
src/share/vm/opto/loopnode.cpp
Print this page
*** 204,214 ****
cl_prob = 1.0 - cl_prob;
}
// Get backedge compare
Node *cmp = test->in(1);
int cmp_op = cmp->Opcode();
! if( cmp_op != Op_CmpI )
return false; // Avoid pointer & float compares
// Find the trip-counter increment & limit. Limit must be loop invariant.
Node *incr = cmp->in(1);
Node *limit = cmp->in(2);
--- 204,214 ----
cl_prob = 1.0 - cl_prob;
}
// Get backedge compare
Node *cmp = test->in(1);
int cmp_op = cmp->Opcode();
! if (cmp_op != Op_CmpI)
return false; // Avoid pointer & float compares
// Find the trip-counter increment & limit. Limit must be loop invariant.
Node *incr = cmp->in(1);
Node *limit = cmp->in(2);
*** 257,267 ****
xphi = stride;
stride = tmp;
}
// Stride must be constant
int stride_con = stride->get_int();
! assert(stride_con != 0, "missed some peephole opt");
if (!xphi->is_Phi())
return false; // Too much math on the trip counter
if (phi_incr != NULL && phi_incr != xphi)
return false;
--- 257,268 ----
xphi = stride;
stride = tmp;
}
// Stride must be constant
int stride_con = stride->get_int();
! if (stride_con == 0)
! return false; // missed some peephole opt
if (!xphi->is_Phi())
return false; // Too much math on the trip counter
if (phi_incr != NULL && phi_incr != xphi)
return false;
*** 317,327 ****
// Odd stride
bt == BoolTest::ne && stride_con != 1 && stride_con != -1 ||
// Count down loop rolls through MAXINT
(bt == BoolTest::le || bt == BoolTest::lt) && stride_con < 0 ||
// Count up loop rolls through MININT
! (bt == BoolTest::ge || bt == BoolTest::gt) && stride_con > 0 ) {
return false; // Bail out
}
const TypeInt* init_t = gvn->type(init_trip)->is_int();
const TypeInt* limit_t = gvn->type(limit)->is_int();
--- 318,328 ----
// Odd stride
bt == BoolTest::ne && stride_con != 1 && stride_con != -1 ||
// Count down loop rolls through MAXINT
(bt == BoolTest::le || bt == BoolTest::lt) && stride_con < 0 ||
// Count up loop rolls through MININT
! (bt == BoolTest::ge || bt == BoolTest::gt) && stride_con > 0) {
return false; // Bail out
}
const TypeInt* init_t = gvn->type(init_trip)->is_int();
const TypeInt* limit_t = gvn->type(limit)->is_int();
*** 339,354 ****
// =================================================
// ---- SUCCESS! Found A Trip-Counted Loop! -----
//
assert(x->Opcode() == Op_Loop, "regular loops only");
C->print_method("Before CountedLoop", 3);
! #ifndef PRODUCT
! if (TraceLoopOpts) {
! tty->print("Counted ");
loop->dump_head();
}
#endif
// If compare points to incr, we are ok. Otherwise the compare
// can directly point to the phi; in this case adjust the compare so that
// it points to the incr by adjusting the limit.
if (cmp->in(1) == phi || cmp->in(2) == phi)
limit = gvn->transform(new (C, 3) AddINode(limit,stride));
--- 340,480 ----
// =================================================
// ---- SUCCESS! Found A Trip-Counted Loop! -----
//
assert(x->Opcode() == Op_Loop, "regular loops only");
C->print_method("Before CountedLoop", 3);
!
! Node *hook = new (C, 6) Node(6);
!
! if (LoopLimitCheck) {
!
! // ===================================================
! // Generate loop limit check to avoid integer overflow
! // in cases like next (cyclic loops):
! //
! // for (i=0; i <= max_jint; i++) {}
! // for (i=0; i < max_jint; i+=2) {}
! //
! //
! // Limit check predicate depends on the loop test:
! //
! // for(;i != limit; i++) --> limit <= (max_jint)
! // for(;i < limit; i+=stride) --> limit <= (max_jint - stride + 1)
! // for(;i <= limit; i+=stride) --> limit <= (max_jint - stride )
! //
!
! // Check if limit is excluded to do more precise int overflow check.
! bool incl_limit = (bt == BoolTest::le || bt == BoolTest::ge);
! int stride_m = stride_con - (incl_limit ? 0 : (stride_con > 0 ? 1 : -1));
!
! // If compare points directly to the phi we need to adjust
! // the compare so that it points to the incr. Limit have
! // to be adjusted to keep trip count the same and the
! // adjusted limit should be checked for int overflow.
! if (phi_incr != NULL) {
! stride_m += stride_con;
! }
!
! if (limit->is_Con()) {
! int limit_con = limit->get_int();
! if ((stride_con > 0 && limit_con > (max_jint - stride_m)) ||
! (stride_con < 0 && limit_con < (min_jint - stride_m))) {
! // Bailout: it could be integer overflow.
! return false;
! }
! } else if ((stride_con > 0 && limit_t->_hi <= (max_jint - stride_m)) ||
! (stride_con < 0 && limit_t->_lo >= (min_jint - stride_m))) {
! // Limit's type may satisfy the condition, for example,
! // when it is an array length.
! } else {
! // Generate loop's limit check.
! // Loop limit check predicate should be near the loop.
! ProjNode *limit_check_proj = find_predicate_insertion_point(init_control, Deoptimization::Reason_loop_limit_check);
! if (!limit_check_proj) {
! // The limit check predicate is not generated if this method trapped here before.
! #ifdef ASSERT
! if (TraceLoopLimitCheck) {
! tty->print("missing loop limit check:");
loop->dump_head();
+ x->dump(1);
}
#endif
+ return false;
+ }
+
+ IfNode* check_iff = limit_check_proj->in(0)->as_If();
+ Node* cmp_limit;
+ Node* bol;
+
+ if (stride_con > 0) {
+ cmp_limit = new (C, 3) CmpINode(limit, _igvn.intcon(max_jint - stride_m));
+ bol = new (C, 2) BoolNode(cmp_limit, BoolTest::le);
+ } else {
+ cmp_limit = new (C, 3) CmpINode(limit, _igvn.intcon(min_jint - stride_m));
+ bol = new (C, 2) BoolNode(cmp_limit, BoolTest::ge);
+ }
+ cmp_limit = _igvn.register_new_node_with_optimizer(cmp_limit);
+ bol = _igvn.register_new_node_with_optimizer(bol);
+ set_subtree_ctrl(bol);
+
+ // Replace condition in original predicate but preserve Opaque node
+ // so that previous predicates could be found.
+ assert(check_iff->in(1)->Opcode() == Op_Conv2B &&
+ check_iff->in(1)->in(1)->Opcode() == Op_Opaque1, "");
+ Node* opq = check_iff->in(1)->in(1);
+ _igvn.hash_delete(opq);
+ opq->set_req(1, bol);
+ // Update ctrl.
+ set_ctrl(opq, check_iff->in(0));
+ set_ctrl(check_iff->in(1), check_iff->in(0));
+
+ #ifndef PRODUCT
+ // report that the loop predication has been actually performed
+ // for this loop
+ if (TraceLoopLimitCheck) {
+ tty->print_cr("Counted Loop Limit Check generated:");
+ debug_only( bol->dump(2); )
+ }
+ #endif
+ }
+
+ if (phi_incr != NULL) {
+ // If compare points directly to the phi we need to adjust
+ // the compare so that it points to the incr. Limit have
+ // to be adjusted to keep trip count the same and we
+ // should avoid int overflow.
+ //
+ // i = init; do {} while(i++ < limit);
+ // is converted to
+ // i = init; do {} while(++i < limit+1);
+ //
+ limit = gvn->transform(new (C, 3) AddINode(limit, stride));
+ }
+
+ // Now we need to canonicalize loop condition.
+ if (bt == BoolTest::ne) {
+ assert(stride_con == 1 || stride_con == -1, "simple increment only");
+ bt = (stride_con > 0) ? BoolTest::lt : BoolTest::gt;
+ }
+
+ if (incl_limit) {
+ // The limit check guaranties that 'limit <= (max_jint - stride)' so
+ // we can convert 'i <= limit' to 'i < limit+1' since stride != 0.
+ //
+ Node* one = (stride_con > 0) ? gvn->intcon( 1) : gvn->intcon(-1);
+ limit = gvn->transform(new (C, 3) AddINode(limit, one));
+ if (bt == BoolTest::le)
+ bt = BoolTest::lt;
+ else if (bt == BoolTest::ge)
+ bt = BoolTest::gt;
+ else
+ ShouldNotReachHere();
+ }
+ set_subtree_ctrl( limit );
+
+ } else { // LoopLimitCheck
+
// If compare points to incr, we are ok. Otherwise the compare
// can directly point to the phi; in this case adjust the compare so that
// it points to the incr by adjusting the limit.
if (cmp->in(1) == phi || cmp->in(2) == phi)
limit = gvn->transform(new (C, 3) AddINode(limit,stride));
*** 357,367 ****
// Final value for iterator should be: trip_count * stride + init_trip.
Node *one_p = gvn->intcon( 1);
Node *one_m = gvn->intcon(-1);
Node *trip_count = NULL;
- Node *hook = new (C, 6) Node(6);
switch( bt ) {
case BoolTest::eq:
ShouldNotReachHere();
case BoolTest::ne: // Ahh, the case we desire
if (stride_con == 1)
--- 483,492 ----
*** 439,448 ****
--- 564,575 ----
hook->init_req(5, span);
limit = gvn->transform(new (C, 3) AddINode(span,init_trip));
set_subtree_ctrl( limit );
+ } // LoopLimitCheck
+
// Check for SafePoint on backedge and remove
Node *sfpt = x->in(LoopNode::LoopBackControl);
if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
lazy_replace( sfpt, iftrue );
loop->_tail = iftrue;
*** 529,555 ****
lazy_replace( x, l );
set_idom(l, init_control, dom_depth(x));
// Check for immediately preceding SafePoint and remove
Node *sfpt2 = le->in(0);
! if( sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2))
lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
// Free up intermediate goo
_igvn.remove_dead_node(hook);
#ifdef ASSERT
assert(l->is_valid_counted_loop(), "counted loop shape is messed up");
assert(l == loop->_head && l->phi() == phi && l->loopexit() == lex, "" );
#endif
C->print_method("After CountedLoop", 3);
return true;
}
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node.
// Attempt to convert into a counted-loop.
Node *LoopNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (!can_be_counted_loop(phase)) {
--- 656,726 ----
lazy_replace( x, l );
set_idom(l, init_control, dom_depth(x));
// Check for immediately preceding SafePoint and remove
Node *sfpt2 = le->in(0);
! if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2))
lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
// Free up intermediate goo
_igvn.remove_dead_node(hook);
#ifdef ASSERT
assert(l->is_valid_counted_loop(), "counted loop shape is messed up");
assert(l == loop->_head && l->phi() == phi && l->loopexit() == lex, "" );
#endif
+ #ifndef PRODUCT
+ if (TraceLoopOpts) {
+ tty->print("Counted ");
+ loop->dump_head();
+ }
+ #endif
C->print_method("After CountedLoop", 3);
return true;
}
+ //----------------------exact_limit-------------------------------------------
+ Node* PhaseIdealLoop::exact_limit( IdealLoopTree *loop ) {
+ assert(loop->_head->is_CountedLoop(), "");
+ CountedLoopNode *cl = loop->_head->as_CountedLoop();
+ if (!LoopLimitCheck || ABS(cl->stride_con()) == 1 ||
+ cl->limit()->Opcode() == Op_LoopLimit) {
+ // Old code has exact limit (it could be incorrect in case of int overflow).
+ // Loop limit is exact with stride == 1. And loop may already have exact limit.
+ return cl->limit();
+ }
+ Node *limit = NULL;
+ #ifdef ASSERT
+ BoolTest::mask bt = cl->loopexit()->test_trip();
+ assert(bt == BoolTest::lt || bt == BoolTest::gt, "canonical test is expected");
+ #endif
+ if (cl->has_exact_trip_count()) {
+ // Simple case: loop has constant boundaries.
+ // Use longs to avoid integer overflow.
+ int stride_con = cl->stride_con();
+ long init_con = cl->init_trip()->get_int();
+ long limit_con = cl->limit()->get_int();
+ julong trip_cnt = cl->trip_count();
+ long final_con = init_con + trip_cnt*stride_con;
+ final_con -= stride_con;
+ int final_int = (int)final_con;
+ // The final value should be in integer range since the loop
+ // is counted and the limit was checked for overflow.
+ assert(final_con == (long)final_int, "final value should be integer");
+ limit = _igvn.intcon(final_int);
+ } else {
+ // Create new LoopLimit node to get exact limit (final iv value).
+ limit = new (C, 4) LoopLimitNode(C, cl->init_trip(), cl->limit(), cl->stride());
+ register_new_node(limit, cl->in(LoopNode::EntryControl));
+ }
+ assert(limit != NULL, "sanity");
+ return limit;
+ }
+
//------------------------------Ideal------------------------------------------
// Return a node which is more "ideal" than the current node.
// Attempt to convert into a counted-loop.
Node *LoopNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if (!can_be_counted_loop(phase)) {
*** 570,596 ****
//------------------------------dump_spec--------------------------------------
// Dump special per-node info
#ifndef PRODUCT
void CountedLoopNode::dump_spec(outputStream *st) const {
LoopNode::dump_spec(st);
! if( stride_is_con() ) {
st->print("stride: %d ",stride_con());
- } else {
- st->print("stride: not constant ");
}
! if( is_pre_loop () ) st->print("pre of N%d" , _main_idx );
! if( is_main_loop() ) st->print("main of N%d", _idx );
! if( is_post_loop() ) st->print("post of N%d", _main_idx );
}
#endif
//=============================================================================
int CountedLoopEndNode::stride_con() const {
return stride()->bottom_type()->is_int()->get_con();
}
//----------------------match_incr_with_optional_truncation--------------------
// Match increment with optional truncation:
// CHAR: (i+1)&0x7fff, BYTE: ((i+1)<<8)>>8, or SHORT: ((i+1)<<16)>>16
// Return NULL for failure. Success returns the increment node.
Node* CountedLoopNode::match_incr_with_optional_truncation(
--- 741,874 ----
//------------------------------dump_spec--------------------------------------
// Dump special per-node info
#ifndef PRODUCT
void CountedLoopNode::dump_spec(outputStream *st) const {
LoopNode::dump_spec(st);
! if (stride_is_con()) {
st->print("stride: %d ",stride_con());
}
! if (is_pre_loop ()) st->print("pre of N%d" , _main_idx);
! if (is_main_loop()) st->print("main of N%d", _idx);
! if (is_post_loop()) st->print("post of N%d", _main_idx);
}
#endif
//=============================================================================
int CountedLoopEndNode::stride_con() const {
return stride()->bottom_type()->is_int()->get_con();
}
+ //=============================================================================
+ //------------------------------Value-----------------------------------------
+ const Type *LoopLimitNode::Value( PhaseTransform *phase ) const {
+ const Type* init_t = phase->type(in(Init));
+ const Type* limit_t = phase->type(in(Limit));
+ const Type* stride_t = phase->type(in(Stride));
+ // Either input is TOP ==> the result is TOP
+ if (init_t == Type::TOP) return Type::TOP;
+ if (limit_t == Type::TOP) return Type::TOP;
+ if (stride_t == Type::TOP) return Type::TOP;
+ int stride_con = stride_t->is_int()->get_con();
+ if (stride_con == 1)
+ return NULL; // Identity
+
+ if (init_t->is_int()->is_con() && limit_t->is_int()->is_con()) {
+ // Use longs to avoid integer overflow.
+ long init_con = init_t->is_int()->get_con();
+ long limit_con = limit_t->is_int()->get_con();
+ int stride_m = stride_con - (stride_con > 0 ? 1 : -1);
+ long trip_count = (limit_con - init_con + stride_m)/stride_con;
+ long final_con = init_con + stride_con*trip_count;
+ int final_int = (int)final_con;
+ // The final value should be in integer range since the loop
+ // is counted and the limit was checked for overflow.
+ assert(final_con == (long)final_int, "final value should be integer");
+ return TypeInt::make(final_int);
+ }
+
+ return bottom_type(); // TypeInt::INT
+ }
+
+ //------------------------------Ideal------------------------------------------
+ // Return a node which is more "ideal" than the current node.
+ Node *LoopLimitNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+ if (phase->type(in(Init)) == Type::TOP ||
+ phase->type(in(Limit)) == Type::TOP ||
+ phase->type(in(Stride)) == Type::TOP)
+ return NULL; // Dead
+
+ int stride_con = phase->type(in(Stride))->is_int()->get_con();
+ if (stride_con == 1)
+ return NULL; // Identity
+
+ if (in(Init)->is_Con() && in(Limit)->is_Con())
+ return NULL; // Value
+
+ // Delay following optimizations until all loop optimizations
+ // done to keep Ideal graph simple.
+ if (!can_reshape || phase->C->major_progress())
+ return NULL;
+
+ const TypeInt* init_t = phase->type(in(Init) )->is_int();
+ const TypeInt* limit_t = phase->type(in(Limit))->is_int();
+ int stride_p;
+ long lim, ini;
+ julong max;
+ if (stride_con > 0) {
+ stride_p = stride_con;
+ lim = limit_t->_hi;
+ ini = init_t->_lo;
+ max = (julong)max_jint;
+ } else {
+ stride_p = -stride_con;
+ lim = init_t->_hi;
+ ini = limit_t->_lo;
+ max = (julong)min_jint;
+ }
+ julong range = lim - ini + stride_p;
+ if (range <= max) {
+ // Convert to integer expression if it is not overflow.
+ Node* stride_m = phase->intcon(stride_con - (stride_con > 0 ? 1 : -1));
+ Node *range = phase->transform(new (phase->C, 3) SubINode(in(Limit), in(Init)));
+ Node *bias = phase->transform(new (phase->C, 3) AddINode(range, stride_m));
+ Node *trip = phase->transform(new (phase->C, 3) DivINode(0, bias, in(Stride)));
+ Node *span = phase->transform(new (phase->C, 3) MulINode(trip, in(Stride)));
+ return new (phase->C, 3) AddINode(span, in(Init)); // exact limit
+ }
+
+ if (is_power_of_2(stride_p) || // divisor is 2^n
+ !Matcher::has_match_rule(Op_LoopLimit)) { // or no specialized Mach node?
+ // Convert to long expression to avoid integer overflow
+ // and let igvn optimizer convert this division.
+ //
+ Node* init = phase->transform( new (phase->C, 2) ConvI2LNode(in(Init)));
+ Node* limit = phase->transform( new (phase->C, 2) ConvI2LNode(in(Limit)));
+ Node* stride = phase->longcon(stride_con);
+ Node* stride_m = phase->longcon(stride_con - (stride_con > 0 ? 1 : -1));
+
+ Node *range = phase->transform(new (phase->C, 3) SubLNode(limit, init));
+ Node *bias = phase->transform(new (phase->C, 3) AddLNode(range, stride_m));
+ Node *trip = phase->transform(new (phase->C, 3) DivLNode(0, bias, stride));
+ Node *span = phase->transform(new (phase->C, 3) MulLNode(trip, stride));
+ Node *exact = phase->transform(new (phase->C, 3) AddLNode(span, init));
+ return new (phase->C, 2) ConvL2INode(exact); // exact limit
+ }
+
+ return NULL; // No progress
+ }
+
+ //------------------------------Identity---------------------------------------
+ // If stride == 1 return limit node.
+ Node *LoopLimitNode::Identity( PhaseTransform *phase ) {
+ int stride_con = phase->type(in(Stride))->is_int()->get_con();
+ if (stride_con == 1 || stride_con == -1)
+ return in(Limit);
+ return this;
+ }
+
+ //=============================================================================
//----------------------match_incr_with_optional_truncation--------------------
// Match increment with optional truncation:
// CHAR: (i+1)&0x7fff, BYTE: ((i+1)<<8)>>8, or SHORT: ((i+1)<<16)>>16
// Return NULL for failure. Success returns the increment node.
Node* CountedLoopNode::match_incr_with_optional_truncation(
*** 868,878 ****
Node *ctl = _head->in(LoopNode::EntryControl);
Node *outer = new (phase->C, 3) LoopNode( ctl, _head->in(outer_idx) );
outer = igvn.register_new_node_with_optimizer(outer, _head);
phase->set_created_loop_node();
! Node* pred = phase->clone_loop_predicates(ctl, outer);
// Outermost loop falls into '_head' loop
_head->set_req(LoopNode::EntryControl, pred);
_head->del_req(outer_idx);
// Split all the Phis up between '_head' loop and 'outer' loop.
for (DUIterator_Fast jmax, j = _head->fast_outs(jmax); j < jmax; j++) {
--- 1146,1156 ----
Node *ctl = _head->in(LoopNode::EntryControl);
Node *outer = new (phase->C, 3) LoopNode( ctl, _head->in(outer_idx) );
outer = igvn.register_new_node_with_optimizer(outer, _head);
phase->set_created_loop_node();
! Node* pred = phase->clone_loop_predicates(ctl, outer, true);
// Outermost loop falls into '_head' loop
_head->set_req(LoopNode::EntryControl, pred);
_head->del_req(outer_idx);
// Split all the Phis up between '_head' loop and 'outer' loop.
for (DUIterator_Fast jmax, j = _head->fast_outs(jmax); j < jmax; j++) {
*** 1438,1450 ****
void IdealLoopTree::dump_head( ) const {
for (uint i=0; i<_nest; i++)
tty->print(" ");
tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
if (_irreducible) tty->print(" IRREDUCIBLE");
if (UseLoopPredicate) {
! Node* entry = PhaseIdealLoop::find_predicate_insertion_point(_head->in(LoopNode::EntryControl),
! Deoptimization::Reason_predicate);
if (entry != NULL) {
tty->print(" predicated");
}
}
if (_head->is_CountedLoop()) {
--- 1716,1735 ----
void IdealLoopTree::dump_head( ) const {
for (uint i=0; i<_nest; i++)
tty->print(" ");
tty->print("Loop: N%d/N%d ",_head->_idx,_tail->_idx);
if (_irreducible) tty->print(" IRREDUCIBLE");
+ Node* entry = _head->in(LoopNode::EntryControl);
+ if (LoopLimitCheck) {
+ Node* predicate = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_loop_limit_check);
+ if (predicate != NULL ) {
+ tty->print(" limit_check");
+ entry = entry->in(0)->in(0);
+ }
+ }
if (UseLoopPredicate) {
! entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
if (entry != NULL) {
tty->print(" predicated");
}
}
if (_head->is_CountedLoop()) {
*** 1526,1549 ****
if (loop->_head->is_Loop() &&
!loop->_irreducible &&
!loop->tail()->is_top()) {
LoopNode* lpn = loop->_head->as_Loop();
Node* entry = lpn->in(LoopNode::EntryControl);
! Node* predicate_proj = find_predicate(entry);
if (predicate_proj != NULL ) { // right pattern that can be used by loop predication
assert(entry->in(0)->in(1)->in(1)->Opcode() == Op_Opaque1, "must be");
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
}
}
if (loop->_next) { // sibling
collect_potentially_useful_predicates(loop->_next, useful_predicates);
}
}
//------------------------eliminate_useless_predicates-----------------------------
// Eliminate all inserted predicates if they could not be used by loop predication.
void PhaseIdealLoop::eliminate_useless_predicates() {
if (C->predicate_count() == 0)
return; // no predicate left
Unique_Node_List useful_predicates; // to store useful predicates
--- 1811,1841 ----
if (loop->_head->is_Loop() &&
!loop->_irreducible &&
!loop->tail()->is_top()) {
LoopNode* lpn = loop->_head->as_Loop();
Node* entry = lpn->in(LoopNode::EntryControl);
! Node* predicate_proj = find_predicate(entry); // loop_limit_check first
if (predicate_proj != NULL ) { // right pattern that can be used by loop predication
assert(entry->in(0)->in(1)->in(1)->Opcode() == Op_Opaque1, "must be");
useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
+ entry = entry->in(0)->in(0);
}
+ predicate_proj = find_predicate(entry); // Predicate
+ if (predicate_proj != NULL ) {
+ useful_predicates.push(entry->in(0)->in(1)->in(1)); // good one
}
+ }
if (loop->_next) { // sibling
collect_potentially_useful_predicates(loop->_next, useful_predicates);
}
}
//------------------------eliminate_useless_predicates-----------------------------
// Eliminate all inserted predicates if they could not be used by loop predication.
+ // Note: it will also eliminates loop limits check predicate since it also uses
+ // Opaque1 node (see Parse::add_predicate()).
void PhaseIdealLoop::eliminate_useless_predicates() {
if (C->predicate_count() == 0)
return; // no predicate left
Unique_Node_List useful_predicates; // to store useful predicates
*** 1729,1739 ****
}
// Some parser-inserted loop predicates could never be used by loop
// predication or they were moved away from loop during some optimizations.
// For example, peeling. Eliminate them before next loop optimizations.
! if (UseLoopPredicate) {
eliminate_useless_predicates();
}
// clear out the dead code
while(_deadlist.size()) {
--- 2021,2031 ----
}
// Some parser-inserted loop predicates could never be used by loop
// predication or they were moved away from loop during some optimizations.
// For example, peeling. Eliminate them before next loop optimizations.
! if (UseLoopPredicate || LoopLimitCheck) {
eliminate_useless_predicates();
}
// clear out the dead code
while(_deadlist.size()) {
src/share/vm/opto/loopnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File