diff options
author | 2020-06-17 15:37:02 +0100 | |
---|---|---|
committer | 2020-06-19 11:32:38 +0000 | |
commit | 3d190c0f01071c5c402a96ac77ef07d20291405a (patch) | |
tree | c99b356725b7474448ae2c14d7bbe0e491c0cd15 /compiler/optimizing/instruction_simplifier_shared.cc | |
parent | 86c8752f64629325026945cd4eabd1dcea224acb (diff) |
ART: Transform Sub+Sub into Sub+Add to merge Shl
In the instruction sequence like the following:
t1 = Shl(a, n)
t2 = Sub(t1, *)
r = Sub(*, t2)
Shl cannot be merged with Sub. However it can be done when the first Sub
operands are reordered and the second Sub is replaced with Add:
t1 = Shl(a, n)
t2 = Sub(*, t1)
r = Add(*, t2)
This CL implements this transformation in the ARM/ARM64 instruction simplifiers.
Test: 411-checker-instruct-simplifier-hrem
Test: test.py --host --optimizing --jit --gtest --interpreter
Test: test.py --target --optimizing --jit --interpreter
Test: run-gtests.sh
Change-Id: I24fde29d307f3ad53a8df8bbafe945b4f733ce6c
Diffstat (limited to 'compiler/optimizing/instruction_simplifier_shared.cc')
-rw-r--r-- | compiler/optimizing/instruction_simplifier_shared.cc | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/compiler/optimizing/instruction_simplifier_shared.cc b/compiler/optimizing/instruction_simplifier_shared.cc index 0f30f662cd..dc60ba62bb 100644 --- a/compiler/optimizing/instruction_simplifier_shared.cc +++ b/compiler/optimizing/instruction_simplifier_shared.cc @@ -336,4 +336,26 @@ bool TryExtractVecArrayAccessAddress(HVecMemoryOperation* access, HInstruction* return true; } +bool TryReplaceSubSubWithSubAdd(HSub* last_sub) { + DCHECK(last_sub->GetRight()->IsSub()); + HBasicBlock* basic_block = last_sub->GetBlock(); + ArenaAllocator* allocator = basic_block->GetGraph()->GetAllocator(); + HInstruction* last_sub_right = last_sub->GetRight(); + HInstruction* last_sub_left = last_sub->GetLeft(); + if (last_sub_right->GetUses().HasExactlyOneElement()) { + // Reorder operands of last_sub_right: Sub(a, b) -> Sub(b, a). + HInstruction* a = last_sub_right->InputAt(0); + HInstruction* b = last_sub_right->InputAt(1); + last_sub_right->ReplaceInput(b, 0); + last_sub_right->ReplaceInput(a, 1); + + // Replace Sub(c, Sub(a, b)) with Add(c, Sub(b, a). + HAdd* add = new (allocator) HAdd(last_sub->GetType(), last_sub_left, last_sub_right); + basic_block->ReplaceAndRemoveInstructionWith(last_sub, add); + return true; + } else { + return false; + } +} + } // namespace art |