summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
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);