summaryrefslogtreecommitdiff
path: root/compiler/optimizing/builder.cc
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2022-06-24 11:16:35 +0100
committer Santiago Aboy Solanes <solanes@google.com> 2022-10-10 09:55:22 +0000
commit8efb1a62b67fd1e6866a4b7e465afc11770bb082 (patch)
tree1f7a9ee46d064b801ce596aaea010f4aafba3aea /compiler/optimizing/builder.cc
parent841a69822d8a8cd04159575957367eeca2fbd1b2 (diff)
Compiler implementation of try catch inlining
Notable changes: 1) Wiring of the graph now allows for inlinees graph ending in TryBoundary, or Goto in some special cases. 2) Building a graph with try catch for inlining may add an extra Goto block. 3) Oat version bump. 4) Reduced kMaximumNumberOfCumulatedDexRegisters from 32 to 20. Bug: 227283224 Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: Ic2fd956de24b72d1de29b4cd3d0b2a1ddab231d8
Diffstat (limited to 'compiler/optimizing/builder.cc')
-rw-r--r--compiler/optimizing/builder.cc53
1 files changed, 51 insertions, 2 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index e7826bbba3..b28c2d9592 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -96,7 +96,50 @@ bool HGraphBuilder::SkipCompilation(size_t number_of_branches) {
return false;
}
-GraphAnalysisResult HGraphBuilder::BuildGraph() {
+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() {
+ if (graph_->GetExitBlock() == nullptr) return;
+
+ bool added_block = false;
+ for (size_t pred = 0, size = graph_->GetExitBlock()->GetPredecessors().size(); pred < size;
+ ++pred) {
+ HBasicBlock* predecessor = graph_->GetExitBlock()->GetPredecessors()[pred];
+ if (NeedsExtraGotoBlock(predecessor)) {
+ added_block = true;
+ graph_->SplitEdge(predecessor, graph_->GetExitBlock())
+ ->AddInstruction(new (graph_->GetAllocator()) HGoto(predecessor->GetDexPc()));
+ }
+ }
+
+ // TODO(solanes): Avoid recomputing the full dominator tree by manually updating the relevant
+ // information (loop information, dominance, try catch information).
+ if (added_block) {
+ DCHECK(!graph_->HasIrreducibleLoops())
+ << "Recomputing loop information in graphs with irreducible loops "
+ << "is unsupported, as it could lead to loop header changes";
+ graph_->ClearLoopInformation();
+ graph_->ClearDominanceInformation();
+ graph_->BuildDominatorTree();
+ }
+}
+
+GraphAnalysisResult HGraphBuilder::BuildGraph(bool build_for_inline) {
DCHECK(code_item_accessor_.HasCodeItem());
DCHECK(graph_->GetBlocks().empty());
@@ -147,7 +190,13 @@ GraphAnalysisResult HGraphBuilder::BuildGraph() {
return kAnalysisInvalidBytecode;
}
- // 5) Type the graph and eliminate dead/redundant phis.
+ // 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.
return ssa_builder.BuildSsa();
}