changeset 2445:f879eafd5835

7042327: assert(opaq->outcnt() == 1 && opaq->in(1) == limit) Summary: Separate limit by Opaque2 node when calculating new limit for unrolled loop. Reviewed-by: never
author kvn
date Thu, 05 May 2011 21:06:14 -0700
parents 37e4df3c8952
children 942e888897bc d4c1fbc3de95
files src/share/vm/opto/ifnode.cpp src/share/vm/opto/loopTransform.cpp
diffstat 2 files changed, 25 insertions(+), 16 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/ifnode.cpp	Wed May 04 22:41:17 2011 -0700
+++ b/src/share/vm/opto/ifnode.cpp	Thu May 05 21:06:14 2011 -0700
@@ -546,6 +546,7 @@
   Node *new_bol = gvn->transform( new (gvn->C, 2) BoolNode( new_cmp, bol->as_Bool()->_test._test ) );
   igvn->hash_delete( iff );
   iff->set_req_X( 1, new_bol, igvn );
+  igvn->_worklist.push( iff );
 }
 
 //------------------------------up_one_dom-------------------------------------
--- a/src/share/vm/opto/loopTransform.cpp	Wed May 04 22:41:17 2011 -0700
+++ b/src/share/vm/opto/loopTransform.cpp	Thu May 05 21:06:14 2011 -0700
@@ -1229,6 +1229,19 @@
         new_limit = _igvn.intcon(limit->get_int() - stride_con);
         set_ctrl(new_limit, C->root());
       } else {
+        // Limit is not constant.
+        {
+          // Separate limit by Opaque node in case it is an incremented
+          // variable from previous loop to avoid using pre-incremented
+          // value which could increase register pressure.
+          // Otherwise reorg_offsets() optimization will create a separate
+          // Opaque node for each use of trip-counter and as result
+          // zero trip guard limit will be different from loop limit.
+          assert(has_ctrl(opaq), "should have it");
+          Node* opaq_ctrl = get_ctrl(opaq);
+          limit = new (C, 2) Opaque2Node( C, limit );
+          register_new_node( limit, opaq_ctrl );
+        }
         if (stride_con > 0 && ((limit_type->_lo - stride_con) < limit_type->_lo) ||
                    stride_con < 0 && ((limit_type->_hi - stride_con) > limit_type->_hi)) {
           // No underflow.
@@ -1278,24 +1291,19 @@
         register_new_node(new_limit, ctrl);
       }
       assert(new_limit != NULL, "");
-      if (limit->outcnt() == 2) {
-        // Replace old limit if it is used only in loop tests.
-        _igvn.replace_node(limit, new_limit);
-      } else {
-        // Replace in loop test.
-        _igvn.hash_delete(cmp);
-        cmp->set_req(2, new_limit);
+      // Replace in loop test.
+      _igvn.hash_delete(cmp);
+      cmp->set_req(2, new_limit);
 
-        // Step 3: Find the min-trip test guaranteed before a 'main' loop.
-        // Make it a 1-trip test (means at least 2 trips).
+      // Step 3: Find the min-trip test guaranteed before a 'main' loop.
+      // Make it a 1-trip test (means at least 2 trips).
 
-        // Guard test uses an 'opaque' node which is not shared.  Hence I
-        // can edit it's inputs directly.  Hammer in the new limit for the
-        // minimum-trip guard.
-        assert(opaq->outcnt() == 1, "");
-        _igvn.hash_delete(opaq);
-        opaq->set_req(1, new_limit);
-      }
+      // Guard test uses an 'opaque' node which is not shared.  Hence I
+      // can edit it's inputs directly.  Hammer in the new limit for the
+      // minimum-trip guard.
+      assert(opaq->outcnt() == 1, "");
+      _igvn.hash_delete(opaq);
+      opaq->set_req(1, new_limit);
     }
 
     // Adjust max trip count. The trip count is intentionally rounded