diff options
author | 2016-06-21 16:18:10 +0000 | |
---|---|---|
committer | 2016-06-21 16:18:10 +0000 | |
commit | 4692c35c151951aa1fa901ca24bfa302a9beeacf (patch) | |
tree | 8d28d7714dd7fa0ae1ff44888ae61f3c8786bfeb /compiler/optimizing/instruction_simplifier.cc | |
parent | f6d4f6e0e61977777b7a9ca18b75bcd26e98e9f9 (diff) | |
parent | 87f3fcbd0db352157fc59148e94647ef21b73bce (diff) |
Merge "Replace String.charAt() with HIR."
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r-- | compiler/optimizing/instruction_simplifier.cc | 27 |
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); |