summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2022-12-06 18:13:10 +0000
committer Santiago Aboy Solanes <solanes@google.com> 2022-12-07 14:27:00 +0000
commit343b9d9e103e281a4c4c337edb83d23473e28bcc (patch)
tree43eaa2d050ba315fe83bcdb2c7e2f6272bf42073
parente3b4be4508b24b45596be5cd0262412770a13f6b (diff)
Allow inlining invokes that contain try catches into catch blocks
Since catch blocks are never considered try blocks, we can guarantee that its invokes are not inside a TryBoundary (which is the blocker for enabling inlining of try catch invokes inside try blocks). Bug: 227283224 Test: art/test/testrunner/testrunner.py --host --64 --optimizing -b Change-Id: I747e2e8c2515e36041ad3966ca6a6388ef7d91df
-rw-r--r--compiler/optimizing/inliner.cc16
-rw-r--r--compiler/optimizing/nodes.cc5
-rw-r--r--test/2241-checker-inline-try-catch/src/Main.java37
3 files changed, 39 insertions, 19 deletions
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index e8b9b583ba..3e3b2d46ca 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -1440,17 +1440,17 @@ bool HInliner::IsInliningSupported(const HInvoke* invoke_instruction,
<< " is not inlined because inlining try catches is disabled globally";
return false;
}
- const bool inlined_into_try_catch =
- // Direct parent is a try catch.
- invoke_instruction->GetBlock()->GetTryCatchInformation() != nullptr ||
- // Indirect parent is a try catch.
+ const bool disallowed_try_catch_inlining =
+ // Direct parent is a try block.
+ invoke_instruction->GetBlock()->IsTryBlock() ||
+ // Indirect parent disallows try catch inlining.
!try_catch_inlining_allowed_;
- if (inlined_into_try_catch) {
+ if (disallowed_try_catch_inlining) {
LOG_FAIL(stats_, MethodCompilationStat::kNotInlinedTryCatchCallee)
<< "Method " << method->PrettyMethod()
<< " is not inlined because it has a try catch and we are not supporting it for this"
<< " particular call. This is could be because e.g. it would be inlined inside another"
- << " try catch, we arrived here from TryInlinePolymorphicCall, etc.";
+ << " try block, we arrived here from TryInlinePolymorphicCall, etc.";
return false;
}
}
@@ -2139,8 +2139,8 @@ bool HInliner::TryBuildAndInlineHelper(HInvoke* invoke_instruction,
const bool try_catch_inlining_allowed_for_recursive_inline =
// It was allowed previously.
try_catch_inlining_allowed_ &&
- // The current invoke is not in a try or a catch.
- invoke_instruction->GetBlock()->GetTryCatchInformation() == nullptr;
+ // The current invoke is not a try block.
+ !invoke_instruction->GetBlock()->IsTryBlock();
RunOptimizations(callee_graph,
code_item,
dex_compilation_unit,
diff --git a/compiler/optimizing/nodes.cc b/compiler/optimizing/nodes.cc
index 4a0ec93663..270bb4fb86 100644
--- a/compiler/optimizing/nodes.cc
+++ b/compiler/optimizing/nodes.cc
@@ -2740,8 +2740,8 @@ void HGraph::UpdateLoopAndTryInformationOfNewBlock(HBasicBlock* block,
}
}
- DCHECK_IMPLIES(has_more_specific_try_catch_info, reference->GetTryCatchInformation() == nullptr)
- << "We don't allow to inline try catches inside of other try catches.";
+ DCHECK_IMPLIES(has_more_specific_try_catch_info, !reference->IsTryBlock())
+ << "We don't allow to inline try catches inside of other try blocks.";
// Update the TryCatchInformation, if we are not inlining a try catch.
if (!has_more_specific_try_catch_info) {
@@ -2832,6 +2832,7 @@ HInstruction* HGraph::InlineInto(HGraph* outer_graph, HInvoke* invoke) {
HBasicBlock* first = entry_block_->GetSuccessors()[0];
DCHECK(!first->IsInLoop());
+ DCHECK(first->GetTryCatchInformation() == nullptr);
at->MergeWithInlined(first);
exit_block_->ReplaceWith(to);
diff --git a/test/2241-checker-inline-try-catch/src/Main.java b/test/2241-checker-inline-try-catch/src/Main.java
index a76a99bd89..a80fbd7053 100644
--- a/test/2241-checker-inline-try-catch/src/Main.java
+++ b/test/2241-checker-inline-try-catch/src/Main.java
@@ -23,7 +23,8 @@ public class Main {
$noinline$testTryCatchFinally();
$noinline$testTryCatchFinallyDifferentInputs();
$noinline$testRecursiveTryCatch();
- $noinline$testDoNotInlineInsideTryOrCatch();
+ $noinline$testDoNotInlineInsideTryInlineInsideCatch();
+ $noinline$testInlineInsideNestedCatches();
$noinline$testBeforeAfterTryCatch();
$noinline$testDifferentTypes();
$noinline$testRawThrow();
@@ -88,28 +89,46 @@ public class Main {
$noinline$assertEquals(1, $inline$OOBTryCatchLevel4(numbers));
}
- // Tests that we don't inline inside outer tries or catches.
- /// CHECK-START: void Main.$noinline$testDoNotInlineInsideTryOrCatch() inliner (before)
- /// CHECK: InvokeStaticOrDirect method_name:Main.DoNotInlineOOBTryCatch
+ // Tests that we don't inline inside outer tries, but we do inline inside of catches.
+ /// CHECK-START: void Main.$noinline$testDoNotInlineInsideTryInlineInsideCatch() inliner (before)
/// CHECK: InvokeStaticOrDirect method_name:Main.DoNotInlineOOBTryCatch
+ /// CHECK: InvokeStaticOrDirect method_name:Main.$inline$OOBTryCatch
- /// CHECK-START: void Main.$noinline$testDoNotInlineInsideTryOrCatch() inliner (after)
- /// CHECK: InvokeStaticOrDirect method_name:Main.DoNotInlineOOBTryCatch
+ /// CHECK-START: void Main.$noinline$testDoNotInlineInsideTryInlineInsideCatch() inliner (after)
/// CHECK: InvokeStaticOrDirect method_name:Main.DoNotInlineOOBTryCatch
- private static void $noinline$testDoNotInlineInsideTryOrCatch() {
+ private static void $noinline$testDoNotInlineInsideTryInlineInsideCatch() {
int val = 0;
try {
int[] numbers = {};
val = DoNotInlineOOBTryCatch(numbers);
} catch (Exception ex) {
unreachable();
- // This is unreachable but we will still compile it so it works for checker purposes
+ // This is unreachable but we will still compile it so it works for checking that it inlines.
int[] numbers = {};
- DoNotInlineOOBTryCatch(numbers);
+ $inline$OOBTryCatch(numbers);
}
$noinline$assertEquals(1, val);
}
+ private static void $noinline$emptyMethod() {}
+
+ private static void $inline$testInlineInsideNestedCatches_inner() {
+ try {
+ $noinline$emptyMethod();
+ } catch (Exception ex) {
+ int[] numbers = {};
+ $noinline$assertEquals(1, $inline$OOBTryCatch(numbers));
+ }
+ }
+
+ private static void $noinline$testInlineInsideNestedCatches() {
+ try {
+ $noinline$emptyMethod();
+ } catch (Exception ex) {
+ $inline$testInlineInsideNestedCatches_inner();
+ }
+ }
+
// Tests that outer tries or catches don't affect as long as we are not inlining the inner
// try/catch inside of them.
private static void $noinline$testBeforeAfterTryCatch() {