diff options
Diffstat (limited to 'compiler/optimizing/nodes.cc')
-rw-r--r-- | compiler/optimizing/nodes.cc | 35 |
1 files changed, 15 insertions, 20 deletions
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc index 85d0fe7245..8491c24b23 100644 --- a/compiler/optimizing/nodes.cc +++ b/compiler/optimizing/nodes.cc @@ -2893,19 +2893,8 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) { HInstruction* last = predecessor->GetLastInstruction(); // At this point we might either have: - // A) Return/ReturnVoid/Throw as the last instruction - // B) `Return/ReturnVoid->TryBoundary->Goto` as the last instruction chain - // C) `Return/ReturnVoid->Goto` as the last instruction chain. This exists when we added the - // extra Goto because we had a TryBoundary which we could eliminate in DCE after - // substituting arguments. - // D) `Throw->TryBoundary` as the last instruction chain - - const bool saw_goto = last->IsGoto(); - if (saw_goto) { - DCHECK(predecessor->IsSingleGoto()); - predecessor = predecessor->GetSinglePredecessor(); - last = predecessor->GetLastInstruction(); - } + // A) Return/ReturnVoid/Throw as the last instruction, or + // B) `Return/ReturnVoid/Throw->TryBoundary` as the last instruction chain const bool saw_try_boundary = last->IsTryBoundary(); if (saw_try_boundary) { @@ -2915,14 +2904,7 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) { last = predecessor->GetLastInstruction(); } - // Check that if we have an instruction chain, it is one of the allowed ones. - DCHECK_IMPLIES(saw_goto, last->IsReturnVoid() || last->IsReturn()); - if (last->IsThrow()) { - // The chain `Throw->TryBoundary` is allowed but not `Throw->TryBoundary->Goto` since that - // would mean a Goto will point to exit after ReplaceSuccessor. - DCHECK(!saw_goto); - if (at->IsTryBlock()) { DCHECK(!saw_try_boundary) << "We don't support inlining of try blocks into try blocks."; // Create a TryBoundary of kind:exit and point it to the Exit block. @@ -2982,6 +2964,19 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) { } predecessor->AddInstruction(new (allocator) HGoto(last->GetDexPc())); predecessor->RemoveInstruction(last); + + if (saw_try_boundary) { + predecessor = to->GetPredecessors()[pred]; + DCHECK(predecessor->EndsWithTryBoundary()); + DCHECK_EQ(predecessor->GetNormalSuccessors().size(), 1u); + if (predecessor->GetSuccessors()[0]->GetPredecessors().size() > 1) { + outer_graph->SplitCriticalEdge(predecessor, to); + rerun_dominance = true; + if (predecessor->GetLoopInformation() != nullptr) { + rerun_loop_analysis = true; + } + } + } } } if (rerun_loop_analysis) { |