summaryrefslogtreecommitdiff
path: root/compiler/optimizing/instruction_simplifier.cc
diff options
context:
space:
mode:
author Aart Bik <ajcbik@google.com> 2016-11-07 08:49:28 -0800
committer Aart Bik <ajcbik@google.com> 2016-11-09 09:32:36 -0800
commitff7d89c0364f6ebd0f0798eb18ef8bd62917de6a (patch)
tree9a8401416b499f815731fd38dec219a1e49b623d /compiler/optimizing/instruction_simplifier.cc
parent8acdebc1a1b5821d3bb8e9461f7877fc234a37ff (diff)
Allow read side effects for removing dead instructions.
Rationale: Instructions that only have the harmless read side effect may be removed when dead as well, we were too strict previously. As proof of concept, this cl also provides more accurate information on a few string related intrinsics. This removes the dead indexOf from CaffeineString (17% performance improvement, big bottleneck of the StringBuffer's toString() still remains in loop). Test: test-art-host Change-Id: Id835a8e287e13e1f09be6b46278a039b8865802e
Diffstat (limited to 'compiler/optimizing/instruction_simplifier.cc')
-rw-r--r--compiler/optimizing/instruction_simplifier.cc15
1 files changed, 15 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_simplifier.cc b/compiler/optimizing/instruction_simplifier.cc
index e06fdee370..85b461dcf6 100644
--- a/compiler/optimizing/instruction_simplifier.cc
+++ b/compiler/optimizing/instruction_simplifier.cc
@@ -106,6 +106,7 @@ class InstructionSimplifierVisitor : public HGraphDelegateVisitor {
void SimplifyFP2Int(HInvoke* invoke);
void SimplifyStringCharAt(HInvoke* invoke);
void SimplifyStringIsEmptyOrLength(HInvoke* invoke);
+ void SimplifyNPEOnArgN(HInvoke* invoke, size_t);
void SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind);
OptimizingCompilerStats* stats_;
@@ -1858,6 +1859,16 @@ void InstructionSimplifierVisitor::SimplifyStringIsEmptyOrLength(HInvoke* invoke
invoke->GetBlock()->ReplaceAndRemoveInstructionWith(invoke, replacement);
}
+// This method should only be used on intrinsics whose sole way of throwing an
+// exception is raising a NPE when the nth argument is null. If that argument
+// is provably non-null, we can clear the flag.
+void InstructionSimplifierVisitor::SimplifyNPEOnArgN(HInvoke* invoke, size_t n) {
+ HInstruction* arg = invoke->InputAt(n);
+ if (!arg->CanBeNull()) {
+ invoke->SetCanThrow(false);
+ }
+}
+
void InstructionSimplifierVisitor::SimplifyMemBarrier(HInvoke* invoke, MemBarrierKind barrier_kind) {
uint32_t dex_pc = invoke->GetDexPc();
HMemoryBarrier* mem_barrier = new (GetGraph()->GetArena()) HMemoryBarrier(barrier_kind, dex_pc);
@@ -1911,6 +1922,10 @@ void InstructionSimplifierVisitor::VisitInvoke(HInvoke* instruction) {
case Intrinsics::kStringLength:
SimplifyStringIsEmptyOrLength(instruction);
break;
+ case Intrinsics::kStringStringIndexOf:
+ case Intrinsics::kStringStringIndexOfAfter:
+ SimplifyNPEOnArgN(instruction, 1); // 0th has own NullCheck
+ break;
case Intrinsics::kUnsafeLoadFence:
SimplifyMemBarrier(instruction, MemBarrierKind::kLoadAny);
break;