diff options
author | 2015-10-19 10:10:41 +0100 | |
---|---|---|
committer | 2015-10-19 10:10:41 +0100 | |
commit | e6dbf48d7a549e58a3d798bbbdc391e4d091b432 (patch) | |
tree | e9edbb884c0143a38e0b32350119999bc11b4dee /compiler/optimizing/common_arm64.h | |
parent | 45513eb694fe55cf02ca6e8f0884621a6c3f6268 (diff) |
ARM64: Instruction simplification for array accesses.
HArrayGet and HArraySet with variable indexes generate two
instructions on arm64, like
add temp, obj, #data_offset
ldr out, [temp, index LSL #shift_amount]
When we have multiple accesses to the same array, the initial `add`
instruction is redundant.
This patch introduces the first instruction simplification in the
arm64-specific instruction simplification pass. It splits HArrayGet
and HArraySet using the new arm64-specific IR HIntermediateAddress.
After that we run GVN again to squash the multiple occurrences of
HIntermediateAddress.
Change-Id: I2e3d12fbb07fed07b2cb2f3f47f99f5a032f8312
Diffstat (limited to 'compiler/optimizing/common_arm64.h')
-rw-r--r-- | compiler/optimizing/common_arm64.h | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h index 4abe5e953c..e1a8c9cc0f 100644 --- a/compiler/optimizing/common_arm64.h +++ b/compiler/optimizing/common_arm64.h @@ -203,19 +203,23 @@ static bool CanEncodeConstantAsImmediate(HConstant* constant, HInstruction* inst int64_t value = CodeGenerator::GetInt64ValueOf(constant); - if (instr->IsAdd() || instr->IsSub() || instr->IsCondition() || - instr->IsCompare() || instr->IsBoundsCheck()) { - // Uses aliases of ADD/SUB instructions. - // If `value` does not fit but `-value` does, VIXL will automatically use - // the 'opposite' instruction. - return vixl::Assembler::IsImmAddSub(value) || vixl::Assembler::IsImmAddSub(-value); - } else if (instr->IsAnd() || instr->IsOr() || instr->IsXor()) { + if (instr->IsAnd() || instr->IsOr() || instr->IsXor()) { // Uses logical operations. return vixl::Assembler::IsImmLogical(value, vixl::kXRegSize); - } else { - DCHECK(instr->IsNeg()); + } else if (instr->IsNeg()) { // Uses mov -immediate. return vixl::Assembler::IsImmMovn(value, vixl::kXRegSize); + } else { + DCHECK(instr->IsAdd() || + instr->IsArm64IntermediateAddress() || + instr->IsBoundsCheck() || + instr->IsCompare() || + instr->IsCondition() || + instr->IsSub()); + // Uses aliases of ADD/SUB instructions. + // If `value` does not fit but `-value` does, VIXL will automatically use + // the 'opposite' instruction. + return vixl::Assembler::IsImmAddSub(value) || vixl::Assembler::IsImmAddSub(-value); } } |