diff options
author | 2021-11-01 09:02:09 +0000 | |
---|---|---|
committer | 2021-11-01 10:45:06 +0000 | |
commit | e43aa3f55fd01ce0887059b309a41b6441521e7c (patch) | |
tree | 7ba4ef9adfbb77e6baa1891c3fabd783fb03d580 /compiler/optimizing/instruction_simplifier.cc | |
parent | 808d8cc8114e0c5ee3116639fe9d31be5a70403a (diff) |
Revert^2 "Inline across dex files for bootclaspath's methods"
This reverts commit 8cb989f1019c4fa30845bf2deb5bc996ed4e8966, so we
are re-enabling commit d690f8ae8f8e2675bc52089a83ac18c749f8e6d2.
Reason for revert: Failing test was fixed here
https://android-review.googlesource.com/c/platform/art/+/1873567
Bug: 154012332
Test: ART tests
Change-Id: If159b29583e35abcfe753f30483f83990208b1b9
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 45 |
1 files changed, 38 insertions, 7 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc index 91b2e8bdc6..3f1f3b0f8d 100644 --- a/compiler/optimizing/instruction_simplifier.cc +++ b/compiler/optimizing/instruction_simplifier.cc @@ -2645,12 +2645,15 @@ static bool TryReplaceStringBuilderAppend(HInvoke* invoke) { // Collect args and check for unexpected uses. // We expect one call to a constructor with no arguments, one constructor fence (unless // eliminated), some number of append calls and one call to StringBuilder.toString(). + bool constructor_inlined = false; bool seen_constructor = false; bool seen_constructor_fence = false; bool seen_to_string = false; uint32_t format = 0u; uint32_t num_args = 0u; HInstruction* args[StringBuilderAppend::kMaxArgs]; // Added in reverse order. + // When inlining, `maybe_new_array` tracks an environment use that we want to allow. + HInstruction* maybe_new_array = nullptr; for (HBackwardInstructionIterator iter(block->GetInstructions()); !iter.Done(); iter.Advance()) { HInstruction* user = iter.Current(); // Instructions of interest apply to `sb`, skip those that do not involve `sb`. @@ -2731,13 +2734,25 @@ static bool TryReplaceStringBuilderAppend(HInvoke* invoke) { format = (format << StringBuilderAppend::kBitsPerArg) | static_cast<uint32_t>(arg); args[num_args] = as_invoke_virtual->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); + } else if (!seen_constructor) { + // At this point, we should see the constructor. However, we might have inlined it so we have + // to take care of both cases. We accept only the constructor with no extra arguments. This + // means that if we inline it, we have to check it is setting its field to a new array. + if (user->IsInvokeStaticOrDirect() && + user->AsInvokeStaticOrDirect()->GetResolvedMethod() != nullptr && + user->AsInvokeStaticOrDirect()->GetResolvedMethod()->IsConstructor() && + user->AsInvokeStaticOrDirect()->GetNumberOfArguments() == 1u) { + constructor_inlined = false; + } else if (user->IsInstanceFieldSet() && + user->AsInstanceFieldSet()->GetFieldType() == DataType::Type::kReference && + user->AsInstanceFieldSet()->InputAt(0) == sb && + user->AsInstanceFieldSet()->GetValue()->IsNewArray()) { + maybe_new_array = user->AsInstanceFieldSet()->GetValue(); + constructor_inlined = true; + } else { + // We were expecting a constructor but we haven't seen it. Abort optimization. + return false; + } DCHECK(!seen_constructor_fence); seen_constructor = true; } else if (user->IsConstructorFence()) { @@ -2763,6 +2778,10 @@ static bool TryReplaceStringBuilderAppend(HInvoke* invoke) { // Accept only calls on the StringBuilder (which shall all be removed). // TODO: Carve-out for const-string? Or rely on environment pruning (to be implemented)? if (holder->InputCount() == 0 || holder->InputAt(0) != sb) { + // When inlining the constructor, we have a NewArray as an environment use. + if (constructor_inlined && holder == maybe_new_array) { + continue; + } return false; } } @@ -2796,6 +2815,18 @@ static bool TryReplaceStringBuilderAppend(HInvoke* invoke) { while (sb->HasNonEnvironmentUses()) { block->RemoveInstruction(sb->GetUses().front().GetUser()); } + if (constructor_inlined) { + // We need to remove the inlined constructor instructions. That also removes all remaining + // environment uses. + DCHECK(sb->HasEnvironmentUses()); + DCHECK(maybe_new_array != nullptr); + DCHECK(maybe_new_array->IsNewArray()); + DCHECK(maybe_new_array->HasNonEnvironmentUses()); + HInstruction* fence = maybe_new_array->GetUses().front().GetUser(); + DCHECK(fence->IsConstructorFence()); + block->RemoveInstruction(fence); + block->RemoveInstruction(maybe_new_array); + } DCHECK(!sb->HasEnvironmentUses()); block->RemoveInstruction(sb); return true; |