< prev index next >

src/hotspot/share/opto/split_if.cpp

Print this page

        

@@ -287,19 +287,21 @@
 // We must be at the merge point which post-dominates 'new_false' and
 // 'new_true'.  Figure out which edges into the RegionNode eventually lead up
 // to false and which to true.  Put in a PhiNode to merge values; plug in
 // the appropriate false-arm or true-arm values.  If some path leads to the
 // original IF, then insert a Phi recursively.
-Node *PhaseIdealLoop::spinup( Node *iff_dom, Node *new_false, Node *new_true, Node *use_blk, Node *def, small_cache *cache ) {
+Node *PhaseIdealLoop::spinup( Node *iff_dom, Node *new_false, Node *new_true, Node *use_blk, Node *def, small_cache *cache, Node* old_region ) {
   if (use_blk->is_top())        // Handle dead uses
     return use_blk;
   Node *prior_n = (Node*)((intptr_t)0xdeadbeef);
   Node *n = use_blk;            // Get path input
   assert( use_blk != iff_dom, "" );
-  // Here's the "spinup" the dominator tree loop.  Do a cache-check
-  // along the way, in case we've come this way before.
-  while( n != iff_dom ) {       // Found post-dominating point?
+  // Here's the "spinup" the dominator tree loop: walk up the dominator tree until
+  // hitting either the old IfFalse, the old IfTrue, old If, or old merge point Region.
+  // (Old If is already lazily replaced with "region_dom", but old Region is not.)
+  // Do a cache-check along the way, in case we've come this way before.
+  while( n != iff_dom && n != old_region) { // Found post-dominating point?
     prior_n = n;
     n = idom(n);                // Search higher
     Node *s = cache->probe( prior_n ); // Check cache
     if( s ) return s;           // Cache hit!
   }

@@ -323,11 +325,11 @@
 
       // Need a Phi here
       phi_post = PhiNode::make_blank(prior_n, def);
       // Search for both true and false on all paths till find one.
       for( uint i = 1; i < phi_post->req(); i++ ) // For all paths
-        phi_post->init_req( i, spinup( iff_dom, new_false, new_true, prior_n->in(i), def, cache ) );
+        phi_post->init_req( i, spinup( iff_dom, new_false, new_true, prior_n->in(i), def, cache, old_region ) );
       Node *t = _igvn.hash_find_insert(phi_post);
       if( t ) {                 // See if we already have this one
         // phi_post will not be used, so kill it
         _igvn.remove_dead_node(phi_post);
         phi_post->destruct();

@@ -342,11 +344,11 @@
   prior_n = (Node*)((intptr_t)0xdeadbeef);  // Reset IDOM walk
   n = use_blk;                  // Get path input
   // Spin-up the idom tree again, basically doing path-compression.
   // Insert cache entries along the way, so that if we ever hit this
   // point in the IDOM tree again we'll stop immediately on a cache hit.
-  while( n != iff_dom ) {       // Found post-dominating point?
+  while( n != iff_dom && n != old_region ) {       // Found post-dominating point?
     prior_n = n;
     n = idom(n);                // Search higher
     cache->lru_insert( prior_n, phi_post ); // Fill cache
   } // End of while not gone high enough
 

@@ -403,18 +405,20 @@
 //
 // If the use is along the pre-split-CFG true branch, then the new use will
 // be from the post-split-CFG true merge point.  Vice-versa for the false
 // path.  Some uses will be along both paths; then we sink the use to the
 // post-dominating location; we may need to insert a Phi there.
-void PhaseIdealLoop::handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true, Node *old_false, Node *old_true ) {
+void PhaseIdealLoop::handle_use( Node *use, Node *def, small_cache *cache, Node *region_dom, Node *new_false, Node *new_true,
+                                 Node *old_false, Node *old_true, Node* old_region ) {
 
   Node *use_blk = find_use_block(use,def,old_false,new_false,old_true,new_true);
   if( !use_blk ) return;        // He's dead, Jim
 
   // Walk up the dominator tree until I hit either the old IfFalse, the old
-  // IfTrue or the old If.  Insert Phis where needed.
-  Node *new_def = spinup( region_dom, new_false, new_true, use_blk, def, cache );
+  // IfTrue, old If, or old merge point Region.  Insert Phis where needed.
+  // (Old If is already lazily replaced with "region_dom".)
+  Node *new_def = spinup( region_dom, new_false, new_true, use_blk, def, cache, old_region );
 
   // Found where this USE goes.  Re-point him.
   uint i;
   for( i = 0; i < use->req(); i++ )
     if( use->in(i) == def )

@@ -548,18 +552,18 @@
         // Compute the new DEF for this USE.  New DEF depends on the path
         // taken from the original DEF to the USE.  The new DEF may be some
         // collection of PHI's merging values from different paths.  The Phis
         // inserted depend only on the location of the USE.  We use a
         // 2-element cache to handle multiple uses from the same block.
-        handle_use(use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true);
+        handle_use(use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true, region);
       } // End of while phi has uses
       // Remove the dead Phi
       _igvn.remove_dead_node( phi );
     } else {
       assert(phi->in(0) == region, "Inconsistent graph");
       // Random memory op guarded by Region.  Compute new DEF for USE.
-      handle_use(phi, region, &region_cache, region_dom, new_false, new_true, old_false, old_true);
+      handle_use(phi, region, &region_cache, region_dom, new_false, new_true, old_false, old_true, region);
     }
     // Every path above deletes a use of the region, except for the region
     // self-cycle (which is needed by handle_use calling find_use_block
     // calling get_ctrl calling get_ctrl_no_update looking for dead
     // regions).  So roll back the DUIterator innards.
< prev index next >