@@ -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
@@ -954,6 +945,46 @@ void PhaseCFG::fixup_flow() {
954945 } // End of for all blocks
955946}
956947
948+ void PhaseCFG::remove_unreachable_blocks () {
949+ ResourceMark rm;
950+ Block_List unreachable;
951+ // Initialize worklist of unreachable blocks to be removed.
952+ for (uint i = 0 ; i < number_of_blocks (); i++) {
953+ Block* block = get_block (i);
954+ assert (block->_pre_order == i, " Block::pre_order does not match block index" );
955+ if (block->is_trivially_unreachable ()) {
956+ unreachable.push (block);
957+ }
958+ }
959+ // Now remove all blocks that are transitively unreachable.
960+ while (unreachable.size () > 0 ) {
961+ Block* dead = unreachable.pop ();
962+ // When this code runs (after PhaseCFG::fixup_flow()), Block::_pre_order
963+ // does not contain pre-order but block-list indices. Ensure they stay
964+ // contiguous by decrementing _pre_order for all elements after 'dead'.
965+ // Block::_rpo does not contain valid reverse post-order indices anymore
966+ // (they are invalidated by block insertions in PhaseCFG::fixup_flow()),
967+ // so there is no need to update them.
968+ for (uint i = dead->_pre_order + 1 ; i < number_of_blocks (); i++) {
969+ get_block (i)->_pre_order --;
970+ }
971+ _blocks.remove (dead->_pre_order );
972+ _number_of_blocks--;
973+ // Update the successors' predecessor list and push new unreachable blocks.
974+ for (uint i = 0 ; i < dead->_num_succs ; i++) {
975+ Block* succ = dead->_succs [i];
976+ Node* head = succ->head ();
977+ for (int j = head->req () - 1 ; j >= 1 ; j--) {
978+ if (get_block_for_node (head->in (j)) == dead) {
979+ head->del_req (j);
980+ }
981+ }
982+ if (succ->is_trivially_unreachable ()) {
983+ unreachable.push (succ);
984+ }
985+ }
986+ }
987+ }
957988
958989// postalloc_expand: Expand nodes after register allocation.
959990//
0 commit comments