From 39fabd6bb6fcf7a712b370d3b6fd0ada83e2e5d8 Mon Sep 17 00:00:00 2001 From: David Brazdil Date: Mon, 26 Oct 2015 14:34:30 -0500 Subject: [PATCH] ART: Enable more passes under try/catch LICM, BCE, LSE are all safe under try/catch. Inliner and DCE need updating and will be enabled in follow-up CLs. Change-Id: I86db5f811257d5e765fea91666a2a2af0fb24ec3 --- compiler/optimizing/licm.cc | 3 ++ compiler/optimizing/nodes.cc | 8 +++++ compiler/optimizing/optimizing_compiler.cc | 56 ++++++++++++------------------ 3 files changed, 33 insertions(+), 34 deletions(-) diff --git a/compiler/optimizing/licm.cc b/compiler/optimizing/licm.cc index c38bbe347..27442d487 100644 --- a/compiler/optimizing/licm.cc +++ b/compiler/optimizing/licm.cc @@ -122,6 +122,9 @@ void LICM::Run() { if (instruction->NeedsEnvironment()) { UpdateLoopPhisIn(instruction->GetEnvironment(), loop_info); } + // Move instruction into the pre header. Note that this cannot move + // a throwing instruction out of its try block since these are hoisted + // only from the header block (and TryBoundary would start a new block). instruction->MoveBefore(pre_header->GetLastInstruction()); } else if (instruction->CanThrow()) { // If `instruction` can throw, we cannot move further instructions diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 348026551..4345d55e9 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -1129,6 +1129,14 @@ std::ostream& operator<<(std::ostream& os, const HInstruction::InstructionKind& } void HInstruction::MoveBefore(HInstruction* cursor) { + if (kIsDebugBuild && CanThrowIntoCatchBlock()) { + // Make sure we are not moving a throwing instruction out of its try block. + DCHECK(cursor->GetBlock()->IsTryBlock()); + const HTryBoundary& current_try = block_->GetTryCatchInformation()->GetTryEntry(); + const HTryBoundary& cursor_try = cursor->GetBlock()->GetTryCatchInformation()->GetTryEntry(); + DCHECK(cursor_try.HasSameExceptionHandlersAs(current_try)); + } + next_->previous_ = previous_; if (previous_ != nullptr) { previous_->next_ = next_; diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 6632f95eb..98acc3437 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -494,43 +494,31 @@ static void RunOptimizations(HGraph* graph, // TODO: Update passes incompatible with try/catch so we have the same // pipeline for all methods. - if (graph->HasTryCatch()) { - HOptimization* optimizations2[] = { - side_effects, - gvn, - dce2, - // The codegen has a few assumptions that only the instruction simplifier - // can satisfy. For example, the code generator does not expect to see a - // HTypeConversion from a type to the same type. - simplify4, - }; - - RunOptimizations(optimizations2, arraysize(optimizations2), pass_observer); - } else { + if (!graph->HasTryCatch()) { MaybeRunInliner(graph, codegen, driver, stats, dex_compilation_unit, pass_observer, handles); - - HOptimization* optimizations2[] = { - // BooleanSimplifier depends on the InstructionSimplifier removing - // redundant suspend checks to recognize empty blocks. - boolean_simplify, - fold2, // TODO: if we don't inline we can also skip fold2. - side_effects, - gvn, - licm, - induction, - bce, - simplify3, - lse, - dce2, - // The codegen has a few assumptions that only the instruction simplifier - // can satisfy. For example, the code generator does not expect to see a - // HTypeConversion from a type to the same type. - simplify4, - }; - - RunOptimizations(optimizations2, arraysize(optimizations2), pass_observer); } + HOptimization* optimizations2[] = { + // BooleanSimplifier depends on the InstructionSimplifier removing + // redundant suspend checks to recognize empty blocks. + boolean_simplify, + fold2, // TODO: if we don't inline we can also skip fold2. + side_effects, + gvn, + licm, + induction, + bce, + simplify3, + lse, + dce2, + // The codegen has a few assumptions that only the instruction simplifier + // can satisfy. For example, the code generator does not expect to see a + // HTypeConversion from a type to the same type. + simplify4, + }; + + RunOptimizations(optimizations2, arraysize(optimizations2), pass_observer); + RunArchOptimizations(driver->GetInstructionSet(), graph, stats, pass_observer); } -- 2.11.0