From 69293b075b620448b1c86b0f993c2681c60f3529 Mon Sep 17 00:00:00 2001 From: Santiago Aboy Solanes Date: Thu, 8 Dec 2022 19:10:57 +0000 Subject: Move adding extra goto blocks to InlineInto There are some cases in which we need to add extra goto blocks when inlining to avoid critical edges. The `TryBoundary` of `kind:exit` instructions will always have more than one successor (normal flow and exceptional flow). If its normal flow successor has more than one predecessor, we would be introducing a critical edge. We can avoid the critical edge in InlineInto instead of doing it in the builder which helps decoupling those two stages as well as simplifying surrounding code. We also have the benefit of adding the extra goto blocks only when necessary. Bug: 227283224 Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: Ibe21623c94c798f7cea60ff892064e63a38a787a --- compiler/optimizing/builder.cc | 58 ++---------------------------------------- 1 file changed, 2 insertions(+), 56 deletions(-) (limited to 'compiler/optimizing/builder.cc') diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc index c9609e0bda..9e871c41bc 100644 --- a/compiler/optimizing/builder.cc +++ b/compiler/optimizing/builder.cc @@ -96,55 +96,7 @@ bool HGraphBuilder::SkipCompilation(size_t number_of_branches) { return false; } -static bool NeedsExtraGotoBlock(HBasicBlock* block) { - if (!block->IsSingleTryBoundary()) { - return false; - } - - const HTryBoundary* boundary = block->GetLastInstruction()->AsTryBoundary(); - DCHECK(boundary->GetNormalFlowSuccessor()->IsExitBlock()); - DCHECK(!boundary->IsEntry()); - - const HInstruction* last_instruction = block->GetSinglePredecessor()->GetLastInstruction(); - DCHECK(last_instruction->IsReturn() || - last_instruction->IsReturnVoid() || - last_instruction->IsThrow()); - - return !last_instruction->IsThrow(); -} - -void HGraphBuilder::MaybeAddExtraGotoBlocks() { - HBasicBlock* exit = graph_->GetExitBlock(); - if (exit == nullptr) { - return; - } - - for (size_t pred = 0, size = exit->GetPredecessors().size(); pred < size; ++pred) { - HBasicBlock* predecessor = exit->GetPredecessors()[pred]; - if (NeedsExtraGotoBlock(predecessor)) { - HBasicBlock* new_goto = graph_->SplitEdgeAndUpdateRPO(predecessor, exit); - new_goto->AddInstruction(new (graph_->GetAllocator()) HGoto(predecessor->GetDexPc())); - if (predecessor->IsInLoop()) { - new_goto->SetLoopInformation(predecessor->GetLoopInformation()); - } - - // Update domination chain - if (!predecessor->GetDominatedBlocks().empty()) { - DCHECK_EQ(predecessor->GetDominatedBlocks().size(), 1u); - DCHECK_EQ(predecessor->GetDominatedBlocks()[0], exit); - new_goto->AddDominatedBlock(exit); - predecessor->RemoveDominatedBlock(exit); - exit->SetDominator(new_goto); - } - - DCHECK(predecessor->GetDominatedBlocks().empty()); - predecessor->AddDominatedBlock(new_goto); - new_goto->SetDominator(predecessor); - } - } -} - -GraphAnalysisResult HGraphBuilder::BuildGraph(bool build_for_inline) { +GraphAnalysisResult HGraphBuilder::BuildGraph() { DCHECK(code_item_accessor_.HasCodeItem()); DCHECK(graph_->GetBlocks().empty()); @@ -195,13 +147,7 @@ GraphAnalysisResult HGraphBuilder::BuildGraph(bool build_for_inline) { return kAnalysisInvalidBytecode; } - // 5) When inlining, we want to add a Goto block if we have Return/ReturnVoid->TryBoundary->Exit - // since we will have Return/ReturnVoid->TryBoundary->`continue to normal execution` once inlined. - if (build_for_inline) { - MaybeAddExtraGotoBlocks(); - } - - // 6) Type the graph and eliminate dead/redundant phis. + // 5) Type the graph and eliminate dead/redundant phis. return ssa_builder.BuildSsa(); } -- cgit v1.2.3-59-g8ed1b