Mercurial > hg > truffle
comparison src/share/vm/opto/split_if.cpp @ 3893:8805f8c1e23e
6591247: C2 cleans up the merge point too early during SplitIf
Summary: Remove region self reference last
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Sat, 27 Aug 2011 00:23:47 -0700 |
parents | 08eb13460b3a |
children | 5e990493719e |
comparison
equal
deleted
inserted
replaced
3892:baf763f388e6 | 3893:8805f8c1e23e |
---|---|
498 small_cache region_cache; | 498 small_cache region_cache; |
499 // Preload some control flow in region-cache | 499 // Preload some control flow in region-cache |
500 region_cache.lru_insert( new_false, new_false ); | 500 region_cache.lru_insert( new_false, new_false ); |
501 region_cache.lru_insert( new_true , new_true ); | 501 region_cache.lru_insert( new_true , new_true ); |
502 // Now handle all uses of the splitting block | 502 // Now handle all uses of the splitting block |
503 for (DUIterator_Last kmin, k = region->last_outs(kmin); k >= kmin; --k) { | 503 for (DUIterator k = region->outs(); region->has_out(k); k++) { |
504 Node* phi = region->last_out(k); | 504 Node* phi = region->out(k); |
505 if( !phi->in(0) ) { // Dead phi? Remove it | 505 if (!phi->in(0)) { // Dead phi? Remove it |
506 _igvn.remove_dead_node(phi); | 506 _igvn.remove_dead_node(phi); |
507 continue; | 507 } else if (phi == region) { // Found the self-reference |
508 } | 508 continue; // No roll-back of DUIterator |
509 assert( phi->in(0) == region, "" ); | 509 } else if (phi->is_Phi()) { // Expected common case: Phi hanging off of Region |
510 if( phi == region ) { // Found the self-reference | 510 assert(phi->in(0) == region, "Inconsistent graph"); |
511 phi->set_req(0, NULL); | |
512 continue; // Break the self-cycle | |
513 } | |
514 // Expected common case: Phi hanging off of Region | |
515 if( phi->is_Phi() ) { | |
516 // Need a per-def cache. Phi represents a def, so make a cache | 511 // Need a per-def cache. Phi represents a def, so make a cache |
517 small_cache phi_cache; | 512 small_cache phi_cache; |
518 | 513 |
519 // Inspect all Phi uses to make the Phi go dead | 514 // Inspect all Phi uses to make the Phi go dead |
520 for (DUIterator_Last lmin, l = phi->last_outs(lmin); l >= lmin; --l) { | 515 for (DUIterator_Last lmin, l = phi->last_outs(lmin); l >= lmin; --l) { |
522 // Compute the new DEF for this USE. New DEF depends on the path | 517 // Compute the new DEF for this USE. New DEF depends on the path |
523 // taken from the original DEF to the USE. The new DEF may be some | 518 // taken from the original DEF to the USE. The new DEF may be some |
524 // collection of PHI's merging values from different paths. The Phis | 519 // collection of PHI's merging values from different paths. The Phis |
525 // inserted depend only on the location of the USE. We use a | 520 // inserted depend only on the location of the USE. We use a |
526 // 2-element cache to handle multiple uses from the same block. | 521 // 2-element cache to handle multiple uses from the same block. |
527 handle_use( use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true ); | 522 handle_use(use, phi, &phi_cache, region_dom, new_false, new_true, old_false, old_true); |
528 } // End of while phi has uses | 523 } // End of while phi has uses |
529 | |
530 // Because handle_use might relocate region->_out, | |
531 // we must refresh the iterator. | |
532 k = region->last_outs(kmin); | |
533 | |
534 // Remove the dead Phi | 524 // Remove the dead Phi |
535 _igvn.remove_dead_node( phi ); | 525 _igvn.remove_dead_node( phi ); |
536 | |
537 } else { | 526 } else { |
527 assert(phi->in(0) == region, "Inconsistent graph"); | |
538 // Random memory op guarded by Region. Compute new DEF for USE. | 528 // Random memory op guarded by Region. Compute new DEF for USE. |
539 handle_use( phi, region, ®ion_cache, region_dom, new_false, new_true, old_false, old_true ); | 529 handle_use(phi, region, ®ion_cache, region_dom, new_false, new_true, old_false, old_true); |
540 } | 530 } |
541 | 531 // Every path above deletes a use of the region, except for the region |
532 // self-cycle (which is needed by handle_use calling find_use_block | |
533 // calling get_ctrl calling get_ctrl_no_update looking for dead | |
534 // regions). So roll back the DUIterator innards. | |
535 --k; | |
542 } // End of while merge point has phis | 536 } // End of while merge point has phis |
537 | |
538 assert(region->outcnt() == 1, "Only self reference should remain"); // Just Self on the Region | |
539 region->set_req(0, NULL); // Break the self-cycle | |
543 | 540 |
544 // Any leftover bits in the splitting block must not have depended on local | 541 // Any leftover bits in the splitting block must not have depended on local |
545 // Phi inputs (these have already been split-up). Hence it's safe to hoist | 542 // Phi inputs (these have already been split-up). Hence it's safe to hoist |
546 // these guys to the dominating point. | 543 // these guys to the dominating point. |
547 lazy_replace( region, region_dom ); | 544 lazy_replace( region, region_dom ); |