diff options
Diffstat (limited to 'compiler/optimizing')
-rw-r--r-- | compiler/optimizing/dead_code_elimination.cc | 40 | ||||
-rw-r--r-- | compiler/optimizing/graph_visualizer.cc | 10 |
2 files changed, 37 insertions, 13 deletions
diff --git a/compiler/optimizing/dead_code_elimination.cc b/compiler/optimizing/dead_code_elimination.cc index 1dc10948cc..d808f2ca3a 100644 --- a/compiler/optimizing/dead_code_elimination.cc +++ b/compiler/optimizing/dead_code_elimination.cc @@ -209,6 +209,9 @@ static bool RemoveNonNullControlDependences(HBasicBlock* block, HBasicBlock* thr // // B1 // / \ +// | instr_1 +// | ... +// | instr_n // | foo() // always throws // \ goto B2 // \ / @@ -218,6 +221,9 @@ static bool RemoveNonNullControlDependences(HBasicBlock* block, HBasicBlock* thr // // B1 // / \ +// | instr_1 +// | ... +// | instr_n // | foo() // | goto Exit // | | @@ -227,10 +233,6 @@ static bool RemoveNonNullControlDependences(HBasicBlock* block, HBasicBlock* thr // 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 @@ bool HDeadCodeElimination::SimplifyAlwaysThrows() { // 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 716fee4d3e..4a6ee13005 100644 --- a/compiler/optimizing/graph_visualizer.cc +++ b/compiler/optimizing/graph_visualizer.cc @@ -586,6 +586,10 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor { 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 @@ class HGraphVisualizerPrinter : public HGraphDelegateVisitor { 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; |