< 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, ®ion_cache, region_dom, new_false, new_true, old_false, old_true);
+ handle_use(phi, region, ®ion_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 >