diff options
author | 2016-11-16 10:17:46 -0800 | |
---|---|---|
committer | 2016-11-30 13:21:21 -0800 | |
commit | 71bf7b43380eb445973f32a7f789d9670f8cc97d (patch) | |
tree | 76425f8578b247a845fe61724d71efc63059760f /compiler/optimizing/nodes.h | |
parent | 52f52361c2ea37941fbda71e3c653bb8096bf516 (diff) |
Optimizations around escape analysis. With tests.
Details:
(1) added new intrinsics
(2) implemented optimizations
more !can be null information
more null check removals
replace return-this uses with incoming parameter
remove dead StringBuffer/Builder calls (with escape analysis)
(3) Fixed exposed bug in CanBeMoved()
Performance gain:
This improves CafeineString by about 360%
(removes null check from first loop, eliminates second loop completely)
Test: test-art-host
Change-Id: Iaf16a1b9cab6a7386f43d71c6b51dd59600e81c1
Diffstat (limited to 'compiler/optimizing/nodes.h')
-rw-r--r-- | compiler/optimizing/nodes.h | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index eebc49c991..0734fd18f0 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -2072,6 +2072,8 @@ class HInstruction : public ArenaObject<kArenaAllocInstruction> { #undef INSTRUCTION_TYPE_CHECK // Returns whether the instruction can be moved within the graph. + // TODO: this method is used by LICM and GVN with possibly different + // meanings? split and rename? virtual bool CanBeMoved() const { return false; } // Returns whether the two instructions are of the same kind. @@ -3789,7 +3791,7 @@ class HInvoke : public HInstruction { bool CanThrow() const OVERRIDE { return GetPackedFlag<kFlagCanThrow>(); } - bool CanBeMoved() const OVERRIDE { return IsIntrinsic(); } + bool CanBeMoved() const OVERRIDE { return IsIntrinsic() && !DoesAnyWrite(); } bool InstructionDataEquals(const HInstruction* other) const OVERRIDE { return intrinsic_ != Intrinsics::kNone && intrinsic_ == other->AsInvoke()->intrinsic_; @@ -4181,6 +4183,19 @@ class HInvokeVirtual FINAL : public HInvoke { kVirtual), vtable_index_(vtable_index) {} + bool CanBeNull() const OVERRIDE { + switch (GetIntrinsic()) { + case Intrinsics::kThreadCurrentThread: + case Intrinsics::kStringBufferAppend: + case Intrinsics::kStringBufferToString: + case Intrinsics::kStringBuilderAppend: + case Intrinsics::kStringBuilderToString: + return false; + default: + return HInvoke::CanBeNull(); + } + } + bool CanDoImplicitNullCheckOn(HInstruction* obj) const OVERRIDE { // TODO: Add implicit null checks in intrinsics. return (obj == InputAt(0)) && !GetLocations()->Intrinsified(); |