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
diff --git a/compiler/optimizing/common_arm64.h b/compiler/optimizing/common_arm64.h
index 4abe5e9..e1a8c9c 100644
--- a/compiler/optimizing/common_arm64.h
+++ b/compiler/optimizing/common_arm64.h
@@ -203,19 +203,23 @@
int64_t value = CodeGenerator::GetInt64ValueOf(constant);
- if (instr->IsAdd() || instr->IsSub() || instr->IsCondition() ||
- instr->IsCompare() || instr->IsBoundsCheck()) {
+ if (instr->IsAnd() || instr->IsOr() || instr->IsXor()) {
+ // Uses logical operations.
+ return vixl::Assembler::IsImmLogical(value, vixl::kXRegSize);
+ } 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);
- } else if (instr->IsAnd() || instr->IsOr() || instr->IsXor()) {
- // Uses logical operations.
- return vixl::Assembler::IsImmLogical(value, vixl::kXRegSize);
- } else {
- DCHECK(instr->IsNeg());
- // Uses mov -immediate.
- return vixl::Assembler::IsImmMovn(value, vixl::kXRegSize);
}
}