< prev index next >

src/hotspot/share/opto/split_if.cpp

Print this page
rev 54013 : 8219448: split-if update_uses accesses stale idom data
Reviewed-by:


 506     // Check for splitting loop tails
 507     if( get_loop(iff)->tail() == ifp )
 508       get_loop(iff)->_tail = ifpx;
 509 
 510     // Replace in the graph with lazy-update mechanism
 511     new_iff->set_req(0, new_iff); // hook self so it does not go dead
 512     lazy_replace(ifp, ifpx);
 513     new_iff->set_req(0, region);
 514 
 515     // Record bits for later xforms
 516     if( ifp->Opcode() == Op_IfFalse ) {
 517       old_false = ifp;
 518       new_false = ifpx;
 519     } else {
 520       old_true = ifp;
 521       new_true = ifpx;
 522     }
 523   }
 524   _igvn.remove_dead_node(new_iff);
 525   // Lazy replace IDOM info with the region's dominator
 526   lazy_replace( iff, region_dom );


 527 
 528   // Now make the original merge point go dead, by handling all its uses.
 529   small_cache region_cache;
 530   // Preload some control flow in region-cache
 531   region_cache.lru_insert( new_false, new_false );
 532   region_cache.lru_insert( new_true , new_true  );
 533   // Now handle all uses of the splitting block
 534   for (DUIterator k = region->outs(); region->has_out(k); k++) {
 535     Node* phi = region->out(k);
 536     if (!phi->in(0)) {         // Dead phi?  Remove it
 537       _igvn.remove_dead_node(phi);
 538     } else if (phi == region) { // Found the self-reference
 539       continue;                 // No roll-back of DUIterator
 540     } else if (phi->is_Phi()) { // Expected common case: Phi hanging off of Region
 541       assert(phi->in(0) == region, "Inconsistent graph");
 542       // Need a per-def cache.  Phi represents a def, so make a cache
 543       small_cache phi_cache;
 544 
 545       // Inspect all Phi uses to make the Phi go dead
 546       for (DUIterator_Last lmin, l = phi->last_outs(lmin); l >= lmin; --l) {


 549         // taken from the original DEF to the USE.  The new DEF may be some
 550         // collection of PHI's merging values from different paths.  The Phis
 551         // inserted depend only on the location of the USE.  We use a
 552         // 2-element cache to handle multiple uses from the same block.
 553         handle_use(use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true);
 554       } // End of while phi has uses
 555       // Remove the dead Phi
 556       _igvn.remove_dead_node( phi );
 557     } else {
 558       assert(phi->in(0) == region, "Inconsistent graph");
 559       // Random memory op guarded by Region.  Compute new DEF for USE.
 560       handle_use(phi, region, &region_cache, region_dom, new_false, new_true, old_false, old_true);
 561     }
 562     // Every path above deletes a use of the region, except for the region
 563     // self-cycle (which is needed by handle_use calling find_use_block
 564     // calling get_ctrl calling get_ctrl_no_update looking for dead
 565     // regions).  So roll back the DUIterator innards.
 566     --k;
 567   } // End of while merge point has phis
 568 
 569   assert(region->outcnt() == 1, "Only self reference should remain"); // Just Self on the Region
 570   region->set_req(0, NULL);       // Break the self-cycle
 571 
 572   // Any leftover bits in the splitting block must not have depended on local
 573   // Phi inputs (these have already been split-up).  Hence it's safe to hoist
 574   // these guys to the dominating point.
 575   lazy_replace( region, region_dom );
 576 #ifndef PRODUCT
 577   if( VerifyLoopOptimizations ) verify();
 578 #endif
 579 }


 506     // Check for splitting loop tails
 507     if( get_loop(iff)->tail() == ifp )
 508       get_loop(iff)->_tail = ifpx;
 509 
 510     // Replace in the graph with lazy-update mechanism
 511     new_iff->set_req(0, new_iff); // hook self so it does not go dead
 512     lazy_replace(ifp, ifpx);
 513     new_iff->set_req(0, region);
 514 
 515     // Record bits for later xforms
 516     if( ifp->Opcode() == Op_IfFalse ) {
 517       old_false = ifp;
 518       new_false = ifpx;
 519     } else {
 520       old_true = ifp;
 521       new_true = ifpx;
 522     }
 523   }
 524   _igvn.remove_dead_node(new_iff);
 525   // Lazy replace IDOM info with the region's dominator
 526   lazy_replace(iff, region_dom);
 527   lazy_update(region, region_dom); // idom must be update before handle_uses
 528   region->set_req(0, NULL);        // Break the self-cycle. Required for lazy_update to work on region
 529 
 530   // Now make the original merge point go dead, by handling all its uses.
 531   small_cache region_cache;
 532   // Preload some control flow in region-cache
 533   region_cache.lru_insert( new_false, new_false );
 534   region_cache.lru_insert( new_true , new_true  );
 535   // Now handle all uses of the splitting block
 536   for (DUIterator k = region->outs(); region->has_out(k); k++) {
 537     Node* phi = region->out(k);
 538     if (!phi->in(0)) {         // Dead phi?  Remove it
 539       _igvn.remove_dead_node(phi);
 540     } else if (phi == region) { // Found the self-reference
 541       continue;                 // No roll-back of DUIterator
 542     } else if (phi->is_Phi()) { // Expected common case: Phi hanging off of Region
 543       assert(phi->in(0) == region, "Inconsistent graph");
 544       // Need a per-def cache.  Phi represents a def, so make a cache
 545       small_cache phi_cache;
 546 
 547       // Inspect all Phi uses to make the Phi go dead
 548       for (DUIterator_Last lmin, l = phi->last_outs(lmin); l >= lmin; --l) {


 551         // taken from the original DEF to the USE.  The new DEF may be some
 552         // collection of PHI's merging values from different paths.  The Phis
 553         // inserted depend only on the location of the USE.  We use a
 554         // 2-element cache to handle multiple uses from the same block.
 555         handle_use(use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true);
 556       } // End of while phi has uses
 557       // Remove the dead Phi
 558       _igvn.remove_dead_node( phi );
 559     } else {
 560       assert(phi->in(0) == region, "Inconsistent graph");
 561       // Random memory op guarded by Region.  Compute new DEF for USE.
 562       handle_use(phi, region, &region_cache, region_dom, new_false, new_true, old_false, old_true);
 563     }
 564     // Every path above deletes a use of the region, except for the region
 565     // self-cycle (which is needed by handle_use calling find_use_block
 566     // calling get_ctrl calling get_ctrl_no_update looking for dead
 567     // regions).  So roll back the DUIterator innards.
 568     --k;
 569   } // End of while merge point has phis
 570 
 571   _igvn.remove_dead_node(region);

 572 




 573 #ifndef PRODUCT
 574   if( VerifyLoopOptimizations ) verify();
 575 #endif
 576 }
< prev index next >