Update domination tree when removing tries, if the catch doesn't exit
When eliminating the unnecessary try and its catch block we turn the
TryBoundary instructions into Goto instructions. If one of these
instructions is pointing to the exit block, we use its single
predecessor instead. If this TryBoundary-turned-into-Goto instruction
was the only one pointing to the Exit, we also have to update the dominators.
Bug: 260387991
Fixes: 260387991
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Test: dex2oat compiling the app in the bug
Change-Id: If05b60e81b2441c4c2235ffad7649813b98d3d69
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index 4c7dd62..410ef0a 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -555,13 +555,22 @@
DisconnectHandlersAndUpdateTryBoundary(block, any_handler_in_loop);
if (block->GetSingleSuccessor()->IsExitBlock()) {
- // `predecessor` used to be a single exit TryBoundary that got turned into a Goto. It
+ // `block` used to be a single exit TryBoundary that got turned into a Goto. It
// is now pointing to the exit which we don't allow. To fix it, we disconnect
- // `predecessor` from its predecessor and RemoveDeadBlocks will remove it from the
+ // `block` from its predecessor and RemoveDeadBlocks will remove it from the
// graph.
DCHECK(block->IsSingleGoto());
HBasicBlock* predecessor = block->GetSinglePredecessor();
predecessor->ReplaceSuccessor(block, graph_->GetExitBlock());
+
+ if (!block->GetDominatedBlocks().empty()) {
+ // Update domination tree if `block` dominates a block to keep the graph consistent.
+ DCHECK_EQ(block->GetDominatedBlocks().size(), 1u);
+ DCHECK_EQ(graph_->GetExitBlock()->GetDominator(), block);
+ predecessor->AddDominatedBlock(graph_->GetExitBlock());
+ graph_->GetExitBlock()->SetDominator(predecessor);
+ block->RemoveDominatedBlock(graph_->GetExitBlock());
+ }
}
}
}