@@ -151,6 +151,10 @@ bool Block::contains(const Node *n) const {
151151 return _nodes.contains (n);
152152}
153153
154+ bool Block::is_trivially_unreachable () const {
155+ return num_preds () <= 1 && !head ()->is_Root () && !head ()->is_Start ();
156+ }
157+
154158// Return empty status of a block. Empty blocks contain only the head, other
155159// ideal nodes, and an optional trailing goto.
156160int Block::is_Empty () const {
@@ -170,7 +174,7 @@ int Block::is_Empty() const {
170174 }
171175
172176 // Unreachable blocks are considered empty
173- if (num_preds () <= 1 ) {
177+ if (is_trivially_unreachable () ) {
174178 return success_result;
175179 }
176180
@@ -608,19 +612,6 @@ void PhaseCFG::convert_NeverBranch_to_Goto(Block *b) {
608612 for (int k = 1 ; dead->get_node (k)->is_Phi (); k++) {
609613 dead->get_node (k)->del_req (j);
610614 }
611- // If the fake exit block becomes unreachable, remove it from the block list.
612- if (dead->num_preds () == 1 ) {
613- for (uint i = 0 ; i < number_of_blocks (); i++) {
614- Block* block = get_block (i);
615- if (block == dead) {
616- _blocks.remove (i);
617- } else if (block->_pre_order > dead->_pre_order ) {
618- // Enforce contiguous pre-order indices (assumed by PhaseBlockLayout).
619- block->_pre_order --;
620- }
621- }
622- _number_of_blocks--;
623- }
624615}
625616
626617// Helper function to move block bx to the slot following b_index. Return
@@ -957,6 +948,46 @@ void PhaseCFG::fixup_flow() {
957948 } // End of for all blocks
958949}
959950
951+ void PhaseCFG::remove_unreachable_blocks () {
952+ ResourceMark rm;
953+ Block_List unreachable;
954+ // Initialize worklist of unreachable blocks to be removed.
955+ for (uint i = 0 ; i < number_of_blocks (); i++) {
956+ Block* block = get_block (i);
957+ assert (block->_pre_order == i, " Block::pre_order does not match block index" );
958+ if (block->is_trivially_unreachable ()) {
959+ unreachable.push (block);
960+ }
961+ }
962+ // Now remove all blocks that are transitively unreachable.
963+ while (unreachable.size () > 0 ) {
964+ Block* dead = unreachable.pop ();
965+ // When this code runs (after PhaseCFG::fixup_flow()), Block::_pre_order
966+ // does not contain pre-order but block-list indices. Ensure they stay
967+ // contiguous by decrementing _pre_order for all elements after 'dead'.
968+ // Block::_rpo does not contain valid reverse post-order indices anymore
969+ // (they are invalidated by block insertions in PhaseCFG::fixup_flow()),
970+ // so there is no need to update them.
971+ for (uint i = dead->_pre_order + 1 ; i < number_of_blocks (); i++) {
972+ get_block (i)->_pre_order --;
973+ }
974+ _blocks.remove (dead->_pre_order );
975+ _number_of_blocks--;
976+ // Update the successors' predecessor list and push new unreachable blocks.
977+ for (uint i = 0 ; i < dead->_num_succs ; i++) {
978+ Block* succ = dead->_succs [i];
979+ Node* head = succ->head ();
980+ for (int j = head->req () - 1 ; j >= 1 ; j--) {
981+ if (get_block_for_node (head->in (j)) == dead) {
982+ head->del_req (j);
983+ }
984+ }
985+ if (succ->is_trivially_unreachable ()) {
986+ unreachable.push (succ);
987+ }
988+ }
989+ }
990+ }
960991
961992// postalloc_expand: Expand nodes after register allocation.
962993//
0 commit comments