Allow to sink code within its try block
Bug: 226143661
Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b
Change-Id: Ie1edc849d8b6db670987cca2206299ab5a4e9d01
diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc
index 0f336a2..c14ad9c 100644
--- a/compiler/optimizing/code_sinking.cc
+++ b/compiler/optimizing/code_sinking.cc
@@ -222,10 +222,14 @@
// TODO(solanes): Here we could do something similar to the loop above and move to the first
// dominator, which is not a try block, instead of just returning nullptr. If we do so, we have
// to also make sure we are not in a loop.
- // TODO(solanes): Alternatively, we could split the try block at the try boundary having two
- // blocks: A and B. Block B would have the try boundary (and xhandler) and therefore block A
- // would be the target block available to move the instruction.
- return nullptr;
+
+ if (instruction->GetBlock()->IsTryBlock() &&
+ instruction->GetBlock()->GetTryCatchInformation()->GetTryEntry().GetId() ==
+ target_block->GetTryCatchInformation()->GetTryEntry().GetId()) {
+ // Sink within the same try block is allowed.
+ } else {
+ return nullptr;
+ }
}
// Find insertion position. No need to filter anymore, as we have found a
diff --git a/test/639-checker-code-sinking/src/Main.java b/test/639-checker-code-sinking/src/Main.java
index 361806a..bd50fa6 100644
--- a/test/639-checker-code-sinking/src/Main.java
+++ b/test/639-checker-code-sinking/src/Main.java
@@ -395,6 +395,7 @@
assertEquals(456, testSinkToCatchBlock());
assertEquals(456, testDoNotSinkToTry());
assertEquals(456, testDoNotSinkToCatchInsideTry());
+ assertEquals(456, testSinkWithinTryBlock());
}
/// CHECK-START: int Main.testSinkToCatchBlock() code_sinking (before)
@@ -488,6 +489,27 @@
return 456;
}
+ /// CHECK-START: int Main.testSinkWithinTryBlock() code_sinking (before)
+ /// CHECK: <<ObjLoadClass:l\d+>> LoadClass class_name:java.lang.Object
+ /// CHECK: NewInstance [<<ObjLoadClass>>]
+ /// CHECK: If
+
+ /// CHECK-START: int Main.testSinkWithinTryBlock() code_sinking (after)
+ /// CHECK: If
+ /// CHECK: <<ObjLoadClass:l\d+>> LoadClass class_name:java.lang.Object
+ /// CHECK: NewInstance [<<ObjLoadClass>>]
+ private static int testSinkWithinTryBlock() {
+ try {
+ Object o = new Object();
+ if (doEarlyReturn) {
+ throw new Error(o.toString());
+ }
+ } catch (Error e) {
+ return 123;
+ }
+ return 456;
+ }
+
private static void assertEquals(int expected, int actual) {
if (expected != actual) {
throw new AssertionError("Expected: " + expected + ", Actual: " + actual);