diff options
-rw-r--r-- | compiler/optimizing/code_sinking.cc | 12 | ||||
-rw-r--r-- | test/639-checker-code-sinking/src/Main.java | 22 |
2 files changed, 30 insertions, 4 deletions
diff --git a/compiler/optimizing/code_sinking.cc b/compiler/optimizing/code_sinking.cc index 0f336a2b1d..c14ad9c95e 100644 --- a/compiler/optimizing/code_sinking.cc +++ b/compiler/optimizing/code_sinking.cc @@ -222,10 +222,14 @@ static HInstruction* FindIdealPosition(HInstruction* instruction, // 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 361806a91b..bd50fa639f 100644 --- a/test/639-checker-code-sinking/src/Main.java +++ b/test/639-checker-code-sinking/src/Main.java @@ -395,6 +395,7 @@ public class Main { assertEquals(456, testSinkToCatchBlock()); assertEquals(456, testDoNotSinkToTry()); assertEquals(456, testDoNotSinkToCatchInsideTry()); + assertEquals(456, testSinkWithinTryBlock()); } /// CHECK-START: int Main.testSinkToCatchBlock() code_sinking (before) @@ -488,6 +489,27 @@ public class Main { 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); |