< prev index next >
src/hotspot/share/opto/loopnode.cpp
Print this page
@@ -322,10 +322,35 @@
set_idom(outer_l, init_control, dom_depth(init_control)+1);
return outer_ilt;
}
+void PhaseIdealLoop::insert_loop_limit_check(Node* init_control, Node* cmp_limit, Node* bol) {
+ Node* new_predicate_proj = create_new_if_for_predicate(init_control->as_Proj(), NULL,
+ Deoptimization::Reason_loop_limit_check,
+ Op_If);
+ Node* iff = new_predicate_proj->in(0);
+ assert(iff->Opcode() == Op_If, "bad graph shape");
+ Node* conv = iff->in(1);
+ assert(conv->Opcode() == Op_Conv2B, "bad graph shape");
+ Node* opaq = conv->in(1);
+ assert(opaq->Opcode() == Op_Opaque1, "bad graph shape");
+ cmp_limit = _igvn.register_new_node_with_optimizer(cmp_limit);
+ bol = _igvn.register_new_node_with_optimizer(bol);
+ set_subtree_ctrl(bol);
+ _igvn.replace_input_of(iff, 1, bol);
+
+#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
+}
+
//------------------------------is_counted_loop--------------------------------
bool PhaseIdealLoop::is_counted_loop(Node* x, IdealLoopTree*& loop) {
PhaseGVN *gvn = &_igvn;
// Counted loop head must be a good RegionNode with only 3 not NULL
@@ -538,11 +563,11 @@
jlong init_p = (jlong)init_t->_hi + stride_con;
if (init_p < (jlong)min_jint || init_p < (jlong)limit_t->_lo)
return false; // cyclic loop or this loop trips only once
}
- if (phi_incr != NULL) {
+ if (phi_incr != NULL && bt != BoolTest::ne) {
// check if there is a possiblity of IV overflowing after the first increment
if (stride_con > 0) {
if (init_t->_hi > max_jint - stride_con) {
return false;
}
@@ -629,32 +654,64 @@
bol = new BoolNode(cmp_limit, BoolTest::le);
} else {
cmp_limit = new CmpINode(limit, _igvn.intcon(min_jint - stride_m));
bol = new 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.replace_input_of(opq, 1, bol);
- // Update ctrl.
- set_ctrl(opq, check_iff->in(0));
- set_ctrl(check_iff->in(1), check_iff->in(0));
+ insert_loop_limit_check(init_control, cmp_limit, bol);
+ }
-#ifndef PRODUCT
- // report that the loop predication has been actually performed
- // for this loop
+ // Now we need to canonicalize loop condition.
+ if (bt == BoolTest::ne) {
+ assert(stride_con == 1 || stride_con == -1, "simple increment only");
+ if (stride_con > 0 && init_t->_hi < limit_t->_lo) {
+ // 'ne' can be replaced with 'lt' only when init < limit.
+ bt = BoolTest::lt;
+ } else if (stride_con < 0 && init_t->_lo > limit_t->_hi) {
+ // 'ne' can be replaced with 'gt' only when init > limit.
+ bt = BoolTest::gt;
+ } else {
+ 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_cr("Counted Loop Limit Check generated:");
- debug_only( bol->dump(2); )
+ 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();
+
+ if (!is_dominator(get_ctrl(limit), check_iff->in(0)) ||
+ !is_dominator(get_ctrl(init_trip), check_iff->in(0))) {
+ return false;
+ }
+
+ Node* cmp_limit;
+ Node* bol;
+
+ if (stride_con > 0) {
+ cmp_limit = new CmpINode(init_trip, limit);
+ bol = new BoolNode(cmp_limit, BoolTest::lt);
+ } else {
+ cmp_limit = new CmpINode(init_trip, limit);
+ bol = new BoolNode(cmp_limit, BoolTest::gt);
+ }
+
+ insert_loop_limit_check(init_control, cmp_limit, bol);
+
+ if (stride_con > 0) {
+ // 'ne' can be replaced with 'lt' only when init < limit.
+ bt = BoolTest::lt;
+ } else if (stride_con < 0) {
+ // 'ne' can be replaced with 'gt' only when init > limit.
+ bt = BoolTest::gt;
+ }
+ }
}
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
@@ -666,21 +723,10 @@
// i = init; do {} while(++i < limit+1);
//
limit = gvn->transform(new AddINode(limit, stride));
}
- // Now we need to canonicalize loop condition.
- if (bt == BoolTest::ne) {
- assert(stride_con == 1 || stride_con == -1, "simple increment only");
- // 'ne' can be replaced with 'lt' only when init < limit.
- if (stride_con > 0 && init_t->_hi < limit_t->_lo)
- bt = BoolTest::lt;
- // 'ne' can be replaced with 'gt' only when init > limit.
- if (stride_con < 0 && init_t->_lo > limit_t->_hi)
- bt = 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);
@@ -2402,11 +2448,11 @@
if (_irreducible) tty->print(" IRREDUCIBLE");
Node* entry = _head->is_Loop() ? _head->as_Loop()->skip_strip_mined(-1)->in(LoopNode::EntryControl) : _head->in(LoopNode::EntryControl);
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);
+ entry = PhaseIdealLoop::skip_loop_predicates(entry);
}
if (UseLoopPredicate) {
entry = PhaseIdealLoop::find_predicate_insertion_point(entry, Deoptimization::Reason_predicate);
if (entry != NULL) {
tty->print(" predicated");
< prev index next >