summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
author Vladimir Marko <vmarko@google.com> 2016-04-28 15:52:11 +0100
committer Vladimir Marko <vmarko@google.com> 2016-06-21 15:17:38 +0100
commit87f3fcbd0db352157fc59148e94647ef21b73bce (patch)
tree5bdeabb246f5de86704333b3fcbccc6e9146d246 /compiler/optimizing/instruction_simplifier.cc
parentb94b5706f0b8e2e1c7e1db22274f9f4bae0c4b5a (diff)
Replace String.charAt() with HIR.
Replace String.charAt() with HArrayLength, HBoundsCheck and HArrayGet. This allows GVN on the HArrayLength and BCE on the HBoundsCheck as well as using the infrastructure for HArrayGet, i.e. better handling of constant indexes than the old intrinsic and using the HArm64IntermediateAddress. Bug: 28330359 Change-Id: I32bf1da7eeafe82537a60416abf6ac412baa80dc
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc27
1 files changed, 25 insertions, 2 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index eb1d1560db..62d637081d 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -101,6 +101,7 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
void SimplifyCompare(HInvoke* invoke, bool is_signum, Primitive::Type type);
void SimplifyIsNaN(HInvoke* invoke);
void SimplifyFP2Int(HInvoke* invoke);
+ void SimplifyStringCharAt(HInvoke* invoke);
void SimplifyStringIsEmptyOrLength(HInvoke* invoke);
void SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind);
@@ -1685,13 +1686,32 @@ void InstructionSimplifierVisitor::SimplifyFP2Int(HInvoke* invoke) {
invoke->ReplaceWithExceptInReplacementAtIndex(select, 0); // false at index 0
}
+void InstructionSimplifierVisitor::SimplifyStringCharAt(HInvoke* invoke) {
+ HInstruction* str = invoke->InputAt(0);
+ HInstruction* index = invoke->InputAt(1);
+ uint32_t dex_pc = invoke->GetDexPc();
+ ArenaAllocator* arena = GetGraph()->GetArena();
+ // We treat String as an array to allow DCE and BCE to seamlessly work on strings,
+ // so create the HArrayLength, HBoundsCheck and HArrayGet.
+ HArrayLength* length = new (arena) HArrayLength(str, dex_pc, /* is_string_length */ true);
+ invoke->GetBlock()->InsertInstructionBefore(length, invoke);
+ HBoundsCheck* bounds_check =
+ new (arena) HBoundsCheck(index, length, dex_pc, invoke->GetDexMethodIndex());
+ invoke->GetBlock()->InsertInstructionBefore(bounds_check, invoke);
+ HArrayGet* array_get =
+ new (arena) HArrayGet(str, index, Primitive::kPrimChar, dex_pc, /* is_string_char_at */ true);
+ invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, array_get);
+ bounds_check->CopyEnvironmentFrom(invoke->GetEnvironment());
+ GetGraph()->SetHasBoundsChecks(true);
+}
+
void InstructionSimplifierVisitor::SimplifyStringIsEmptyOrLength(HInvoke* invoke) {
HInstruction* str = invoke->InputAt(0);
uint32_t dex_pc = invoke->GetDexPc();
// We treat String as an array to allow DCE and BCE to seamlessly work on strings,
// so create the HArrayLength.
- HArrayLength* length = new (GetGraph()->GetArena()) HArrayLength(str, dex_pc);
- length->MarkAsStringLength();
+ HArrayLength* length =
+ new (GetGraph()->GetArena()) HArrayLength(str, dex_pc, /* is_string_length */ true);
HInstruction* replacement;
if (invoke->GetIntrinsic() == Intrinsics::kStringIsEmpty) {
// For String.isEmpty(), create the `HEqual` representing the `length == 0`.
@@ -1752,6 +1772,9 @@ void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
case Intrinsics::kDoubleDoubleToLongBits:
SimplifyFP2Int(instruction);
break;
+ case Intrinsics::kStringCharAt:
+ SimplifyStringCharAt(instruction);
+ break;
case Intrinsics::kStringIsEmpty:
case Intrinsics::kStringLength:
SimplifyStringIsEmptyOrLength(instruction);