summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
author Santiago Aboy Solanes <solanes@google.com> 2024-11-14 15:09:41 +0000
committer Treehugger Robot <android-test-infra-autosubmit@system.gserviceaccount.com> 2024-11-21 12:39:22 +0000
commita21eb118c8c1e9d362b7465327f1fae8db48a572 (patch)
treee5542170e0de695c9dd491fa7b77a7deb73e28ae /compiler/optimizing/instruction_simplifier.cc
parent53d8174b0003eb22192aba21d54ca96947002151 (diff)
Allow the inliner to devirtualize intrinsics
To do so update: * TryReplaceStringBuilderAppend * Code paths relevant to previously InvokeVirtual that are now InvokeStaticOrDirect * checker tests. Bug: 369206455 Test: art/test/testrunner/testrunner.py --host --64 -b --optimizing Change-Id: I4d40980e416f3130d3c344c5f07b7b331deb5c97
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc53
1 files changed, 29 insertions, 24 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index 931050855c..703f6c77e8 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -2976,13 +2976,8 @@ void InstructionSimplifierVisitor::SimplifyReturnThis(HInvoke* invoke) {
// Helper method for StringBuffer escape analysis.
static bool NoEscapeForStringBufferReference(HInstruction* reference, HInstruction* user) {
- if (user->IsInvokeStaticOrDirect()) {
- // Any constructor on StringBuffer is okay.
- return user->AsInvokeStaticOrDirect()->GetResolvedMethod() != nullptr &&
- user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() &&
- user->InputAt(0) == reference;
- } else if (user->IsInvokeVirtual()) {
- switch (user->AsInvokeVirtual()->GetIntrinsic()) {
+ if (user->IsInvoke()) {
+ switch (user->AsInvoke()->GetIntrinsic()) {
case Intrinsics::kStringBufferLength:
case Intrinsics::kStringBufferToString:
DCHECK_EQ(user->InputAt(0), reference);
@@ -2996,6 +2991,14 @@ static bool NoEscapeForStringBufferReference(HInstruction* reference, HInstructi
break;
}
}
+
+ if (user->IsInvokeStaticOrDirect()) {
+ // Any constructor on StringBuffer is okay.
+ return user->AsInvokeStaticOrDirect()->GetResolvedMethod() != nullptr &&
+ user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() &&
+ user->InputAt(0) == reference;
+ }
+
return false;
}
@@ -3051,13 +3054,24 @@ static bool TryReplaceStringBuilderAppend(CodeGenerator* codegen, HInvoke* invok
return false;
}
}
- // Then we should see the arguments.
- if (user->IsInvokeVirtual()) {
- HInvokeVirtual* as_invoke_virtual = user->AsInvokeVirtual();
+
+ // Pattern match seeing arguments, then constructor, then constructor fence.
+ if (user->IsInvokeStaticOrDirect() &&
+ user->AsInvokeStaticOrDirect()->GetResolvedMethod() != nullptr &&
+ user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() &&
+ user->AsInvokeStaticOrDirect()->GetNumberOfArguments() == 1u) {
+ // After arguments, we should see the constructor.
+ // We accept only the constructor with no extra arguments.
+ DCHECK(!seen_constructor);
+ DCHECK(!seen_constructor_fence);
+ seen_constructor = true;
+ } else if (user->IsInvoke()) {
+ // The arguments.
+ HInvoke* as_invoke = user->AsInvoke();
DCHECK(!seen_constructor);
DCHECK(!seen_constructor_fence);
StringBuilderAppend::Argument arg;
- switch (as_invoke_virtual->GetIntrinsic()) {
+ switch (as_invoke->GetIntrinsic()) {
case Intrinsics::kStringBuilderAppendObject:
// TODO: Unimplemented, needs to call String.valueOf().
return false;
@@ -3089,7 +3103,7 @@ static bool TryReplaceStringBuilderAppend(CodeGenerator* codegen, HInvoke* invok
has_fp_args = true;
break;
case Intrinsics::kStringBuilderAppendCharSequence: {
- ReferenceTypeInfo rti = user->AsInvokeVirtual()->InputAt(1)->GetReferenceTypeInfo();
+ ReferenceTypeInfo rti = as_invoke->InputAt(1)->GetReferenceTypeInfo();
if (!rti.IsValid()) {
return false;
}
@@ -3112,23 +3126,14 @@ static bool TryReplaceStringBuilderAppend(CodeGenerator* codegen, HInvoke* invok
}
}
// Uses of the append return value should have been replaced with the first input.
- DCHECK(!as_invoke_virtual->HasUses());
- DCHECK(!as_invoke_virtual->HasEnvironmentUses());
+ DCHECK(!as_invoke->HasUses());
+ DCHECK(!as_invoke->HasEnvironmentUses());
if (num_args == StringBuilderAppend::kMaxArgs) {
return false;
}
format = (format << StringBuilderAppend::kBitsPerArg) | static_cast<uint32_t>(arg);
- args[num_args] = as_invoke_virtual->InputAt(1u);
+ args[num_args] = as_invoke->InputAt(1u);
++num_args;
- } else if (user->IsInvokeStaticOrDirect() &&
- user->AsInvokeStaticOrDirect()->GetResolvedMethod() != nullptr &&
- user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() &&
- user->AsInvokeStaticOrDirect()->GetNumberOfArguments() == 1u) {
- // After arguments, we should see the constructor.
- // We accept only the constructor with no extra arguments.
- DCHECK(!seen_constructor);
- DCHECK(!seen_constructor_fence);
- seen_constructor = true;
} else if (user->IsConstructorFence()) {
// The last use we see is the constructor fence.
DCHECK(seen_constructor);