< 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(ProjNode* limit_check_proj, Node* cmp_limit, Node* bol) {
+  Node* new_predicate_proj = create_new_if_for_predicate(limit_check_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(limit_check_proj, 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(limit_check_proj, 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 >