Revert^2 "DCE SimplifyAlwaysThrowing optimizations"
This reverts commit 026a662dd6bef3e0e5a58478b764c4ddf662a5ec.
Reason for revert: after aosp/2055933 the inliner will return
true if it analyzed a method as "always throwing". This CL now
uses `after_inliner` instead of `after_gvn` and shouldn't make
the LUCI bots red.
Bug: 227316307
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: Icbc2678633c289ae6d066185e9b16e9c3674c8d0
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc
index 1dc1094..d808f2c 100644
--- a/compiler/optimizing/dead_code_elimination.cc
+++ b/compiler/optimizing/dead_code_elimination.cc
@@ -209,6 +209,9 @@
//
// B1
// / \
+// | instr_1
+// | ...
+// | instr_n
// | foo() // always throws
// \ goto B2
// \ /
@@ -218,6 +221,9 @@
//
// B1
// / \
+// | instr_1
+// | ...
+// | instr_n
// | foo()
// | goto Exit
// | |
@@ -227,10 +233,6 @@
// Removal of the never taken edge to B2 may expose
// other optimization opportunities, such as code sinking.
bool HDeadCodeElimination::SimplifyAlwaysThrows() {
- // Make sure exceptions go to exit.
- if (graph_->HasTryCatch()) {
- return false;
- }
HBasicBlock* exit = graph_->GetExitBlock();
if (exit == nullptr) {
return false;
@@ -240,15 +242,35 @@
// Order does not matter, just pick one.
for (HBasicBlock* block : graph_->GetReversePostOrder()) {
- HInstruction* first = block->GetFirstInstruction();
+ if (block->GetTryCatchInformation() != nullptr) {
+ // We don't want to perform the simplify always throws optimizations for throws inside of
+ // tries since those throws might not go to the exit block. We do that by checking the
+ // TryCatchInformation of the blocks.
+ //
+ // As a special case the `catch_block` is the first block of the catch and it has
+ // TryCatchInformation. Other blocks in the catch don't have try catch information (as long as
+ // they are not part of an outer try). Knowing if a `catch_block` is part of an outer try is
+ // possible by checking its successors, but other restrictions of the simplify always throws
+ // optimization will block `catch_block` nevertheless (e.g. only one predecessor) so it is not
+ // worth the effort.
+
+ // TODO(solanes): Maybe we can do a `goto catch` if inside of a try catch instead of going to
+ // the exit. If we do so, we have to take into account that we should go to the nearest valid
+ // catch i.e. one that would accept our exception type.
+ continue;
+ }
+
HInstruction* last = block->GetLastInstruction();
- // Ensure only one throwing instruction appears before goto.
- if (first->AlwaysThrows() &&
- first->GetNext() == last &&
+ HInstruction* prev = last->GetPrevious();
+ if (prev == nullptr) {
+ DCHECK_EQ(block->GetFirstInstruction(), block->GetLastInstruction());
+ continue;
+ }
+
+ if (prev->AlwaysThrows() &&
last->IsGoto() &&
block->GetPhis().IsEmpty() &&
block->GetPredecessors().size() == 1u) {
- DCHECK_EQ(block->GetSuccessors().size(), 1u);
HBasicBlock* pred = block->GetSinglePredecessor();
HBasicBlock* succ = block->GetSingleSuccessor();
// Ensure no computations are merged through throwing block.
diff --git a/compiler/optimizing/graph_visualizer.cc b/compiler/optimizing/graph_visualizer.cc
index 716fee4..4a6ee13 100644
--- a/compiler/optimizing/graph_visualizer.cc
+++ b/compiler/optimizing/graph_visualizer.cc
@@ -586,6 +586,10 @@
StartAttributeStream("kind") << (try_boundary->IsEntry() ? "entry" : "exit");
}
+ void VisitGoto(HGoto* instruction) override {
+ StartAttributeStream("target") << namer_.GetName(instruction->GetBlock()->GetSingleSuccessor());
+ }
+
void VisitDeoptimize(HDeoptimize* deoptimize) override {
StartAttributeStream("kind") << deoptimize->GetKind();
}
@@ -657,10 +661,8 @@
StartAttributeStream("dex_pc") << "n/a";
}
HBasicBlock* block = instruction->GetBlock();
- if (IsPass(kDebugDumpName)) {
- // Include block name for logcat use.
- StartAttributeStream("block") << namer_.GetName(block);
- }
+ StartAttributeStream("block") << namer_.GetName(block);
+
instruction->Accept(this);
if (instruction->HasEnvironment()) {
StringList envs;