summaryrefslogtreecommitdiff
path: root/compiler/optimizing/code_sinking.cc
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2023-02-21 16:28:39 +0000
committer Santiago Aboy Solanes <solanes@google.com> 2023-02-24 14:06:12 +0000
commit3b17ccb6deb7015fa3859319d3711c5ff11aecbb (patch)
tree1067886531b4f913a799afde8b9571ab566f6e95 /compiler/optimizing/code_sinking.cc
parentbc50ac127d01149be8fd7af7d31f33fc237c7b0f (diff)
Don't consider TryBoundary instruction as uncommon branches
We can construct a graph that ends with Return -> TryBoundary -> Exit. We don't want to consider that path as an uncommon branch. Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: Ia02beeca36f2e43a4b3bd49c253fc161d8307924
Diffstat (limited to 'compiler/optimizing/code_sinking.cc')
-rw-r--r--compiler/optimizing/code_sinking.cc17
1 files changed, 17 insertions, 0 deletions
diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc
index e7a4389ed2..76885ec0a6 100644
--- a/compiler/optimizing/code_sinking.cc
+++ b/compiler/optimizing/code_sinking.cc
@@ -37,6 +37,23 @@ bool CodeSinking::Run() {
// as an indicator of an uncommon branch.
for (HBasicBlock* exit_predecessor : exit->GetPredecessors()) {
HInstruction* last = exit_predecessor->GetLastInstruction();
+
+ // TryBoundary instructions are sometimes inserted between the last instruction (e.g. Throw,
+ // Return) and Exit. We don't want to use that instruction for our "uncommon branch" heuristic
+ // because they are not as good an indicator as throwing branches, so we skip them and fetch the
+ // actual last instruction.
+ if (last->IsTryBoundary()) {
+ // We have an exit try boundary. Fetch the previous instruction.
+ DCHECK(!last->AsTryBoundary()->IsEntry());
+ if (last->GetPrevious() == nullptr) {
+ DCHECK(exit_predecessor->IsSingleTryBoundary());
+ exit_predecessor = exit_predecessor->GetSinglePredecessor();
+ last = exit_predecessor->GetLastInstruction();
+ } else {
+ last = last->GetPrevious();
+ }
+ }
+
// Any predecessor of the exit that does not return, throws an exception.
if (!last->IsReturn() && !last->IsReturnVoid()) {
SinkCodeToUncommonBranch(exit_predecessor);