Fix code generation of materialized conditions.
Move the logic for knowing if a condition needs to be materialized
in an optimization pass (so that the information does not change
as a side effect of another optimization).
Also clean-up arm and x86_64 codegen:
- arm: ldr and str are for power-users when a constant is
in play. We should use LoadFromOffset and StoreToOffset.
- x86_64: fix misuses of movq instead of movl.
Change-Id: I01a03b91803624be2281a344a13ad5efbf4f3ef3
diff --git a/compiler/optimizing/code_generator_arm.cc b/compiler/optimizing/code_generator_arm.cc
index d555a0d..1297381 100644
--- a/compiler/optimizing/code_generator_arm.cc
+++ b/compiler/optimizing/code_generator_arm.cc
@@ -67,7 +67,7 @@
virtual void EmitNativeCode(CodeGenerator* codegen) OVERRIDE {
__ Bind(GetEntryLabel());
int32_t offset = QUICK_ENTRYPOINT_OFFSET(kArmWordSize, pThrowNullPointer).Int32Value();
- __ ldr(LR, Address(TR, offset));
+ __ LoadFromOffset(kLoadWord, LR, TR, offset);
__ blx(LR);
codegen->RecordPcInfo(instruction_, instruction_->GetDexPc());
}
@@ -100,7 +100,7 @@
__ Bind(GetEntryLabel());
codegen->SaveLiveRegisters(instruction_->GetLocations());
int32_t offset = QUICK_ENTRYPOINT_OFFSET(kArmWordSize, pTestSuspend).Int32Value();
- __ ldr(LR, Address(TR, offset));
+ __ LoadFromOffset(kLoadWord, LR, TR, offset);
__ blx(LR);
codegen->RecordPcInfo(instruction_, instruction_->GetDexPc());
codegen->RestoreLiveRegisters(instruction_->GetLocations());
@@ -143,7 +143,7 @@
arm_codegen->Move32(Location::RegisterLocation(calling_convention.GetRegisterAt(0)), index_location_);
arm_codegen->Move32(Location::RegisterLocation(calling_convention.GetRegisterAt(1)), length_location_);
int32_t offset = QUICK_ENTRYPOINT_OFFSET(kArmWordSize, pThrowArrayBounds).Int32Value();
- __ ldr(LR, Address(TR, offset));
+ __ LoadFromOffset(kLoadWord, LR, TR, offset);
__ blx(LR);
codegen->RecordPcInfo(instruction_, instruction_->GetDexPc());
}
@@ -196,11 +196,11 @@
}
void CodeGeneratorARM::SaveCoreRegister(Location stack_location, uint32_t reg_id) {
- __ str(static_cast<Register>(reg_id), Address(SP, stack_location.GetStackIndex()));
+ __ StoreToOffset(kStoreWord, static_cast<Register>(reg_id), SP, stack_location.GetStackIndex());
}
void CodeGeneratorARM::RestoreCoreRegister(Location stack_location, uint32_t reg_id) {
- __ ldr(static_cast<Register>(reg_id), Address(SP, stack_location.GetStackIndex()));
+ __ LoadFromOffset(kLoadWord, static_cast<Register>(reg_id), SP, stack_location.GetStackIndex());
}
CodeGeneratorARM::CodeGeneratorARM(HGraph* graph)
@@ -339,7 +339,7 @@
__ b(slow_path->GetEntryLabel(), CC);
} else {
__ AddConstant(IP, SP, -static_cast<int32_t>(GetStackOverflowReservedBytes(kArm)));
- __ ldr(IP, Address(IP, 0));
+ __ LoadFromOffset(kLoadWord, IP, IP, 0);
RecordPcInfo(nullptr, 0);
}
}
@@ -349,7 +349,7 @@
// The return PC has already been pushed on the stack.
__ AddConstant(SP, -(GetFrameSize() - kNumberOfPushedRegistersAtEntry * kArmWordSize));
- __ str(R0, Address(SP, 0));
+ __ StoreToOffset(kStoreWord, R0, SP, 0);
}
void CodeGeneratorARM::GenerateFrameExit() {
@@ -434,7 +434,7 @@
} else if (source.IsFpuRegister()) {
__ vmovrs(destination.As<Register>(), FromDToLowS(source.As<DRegister>()));
} else {
- __ ldr(destination.As<Register>(), Address(SP, source.GetStackIndex()));
+ __ LoadFromOffset(kLoadWord, destination.As<Register>(), SP, source.GetStackIndex());
}
} else if (destination.IsFpuRegister()) {
if (source.IsRegister()) {
@@ -447,13 +447,13 @@
} else {
DCHECK(destination.IsStackSlot());
if (source.IsRegister()) {
- __ str(source.As<Register>(), Address(SP, destination.GetStackIndex()));
+ __ StoreToOffset(kStoreWord, source.As<Register>(), SP, destination.GetStackIndex());
} else if (source.IsFpuRegister()) {
__ vstrs(FromDToLowS(source.As<DRegister>()), Address(SP, destination.GetStackIndex()));
} else {
DCHECK(source.IsStackSlot());
- __ ldr(IP, Address(SP, source.GetStackIndex()));
- __ str(IP, Address(SP, destination.GetStackIndex()));
+ __ LoadFromOffset(kLoadWord, IP, SP, source.GetStackIndex());
+ __ StoreToOffset(kStoreWord, IP, SP, destination.GetStackIndex());
}
}
}
@@ -473,14 +473,14 @@
InvokeDexCallingConvention calling_convention;
__ Mov(destination.AsRegisterPairLow<Register>(),
calling_convention.GetRegisterAt(argument_index));
- __ ldr(destination.AsRegisterPairHigh<Register>(),
- Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1) + GetFrameSize()));
+ __ LoadFromOffset(kLoadWord, destination.AsRegisterPairHigh<Register>(),
+ SP, calling_convention.GetStackOffsetOf(argument_index + 1) + GetFrameSize());
} else {
DCHECK(source.IsDoubleStackSlot());
if (destination.AsRegisterPairLow<Register>() == R1) {
DCHECK_EQ(destination.AsRegisterPairHigh<Register>(), R2);
- __ ldr(R1, Address(SP, source.GetStackIndex()));
- __ ldr(R2, Address(SP, source.GetHighStackIndex(kArmWordSize)));
+ __ LoadFromOffset(kLoadWord, R1, SP, source.GetStackIndex());
+ __ LoadFromOffset(kLoadWord, R2, SP, source.GetHighStackIndex(kArmWordSize));
} else {
__ LoadFromOffset(kLoadWordPair, destination.AsRegisterPairLow<Register>(),
SP, source.GetStackIndex());
@@ -496,24 +496,25 @@
InvokeDexCallingConvention calling_convention;
uint32_t argument_index = destination.GetQuickParameterIndex();
if (source.IsRegisterPair()) {
- __ Mov(calling_convention.GetRegisterAt(argument_index), source.AsRegisterPairLow<Register>());
- __ str(source.AsRegisterPairHigh<Register>(),
- Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1)));
+ __ Mov(calling_convention.GetRegisterAt(argument_index),
+ source.AsRegisterPairLow<Register>());
+ __ StoreToOffset(kStoreWord, source.AsRegisterPairHigh<Register>(),
+ SP, calling_convention.GetStackOffsetOf(argument_index + 1));
} else if (source.IsFpuRegister()) {
LOG(FATAL) << "Unimplemented";
} else {
DCHECK(source.IsDoubleStackSlot());
- __ ldr(calling_convention.GetRegisterAt(argument_index), Address(SP, source.GetStackIndex()));
- __ ldr(R0, Address(SP, source.GetHighStackIndex(kArmWordSize)));
- __ str(R0, Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1)));
+ __ LoadFromOffset(kLoadWord, calling_convention.GetRegisterAt(argument_index), SP, source.GetStackIndex());
+ __ LoadFromOffset(kLoadWord, R0, SP, source.GetHighStackIndex(kArmWordSize));
+ __ StoreToOffset(kStoreWord, R0, SP, calling_convention.GetStackOffsetOf(argument_index + 1));
}
} else {
DCHECK(destination.IsDoubleStackSlot());
if (source.IsRegisterPair()) {
if (source.AsRegisterPairLow<Register>() == R1) {
DCHECK_EQ(source.AsRegisterPairHigh<Register>(), R2);
- __ str(R1, Address(SP, destination.GetStackIndex()));
- __ str(R2, Address(SP, destination.GetHighStackIndex(kArmWordSize)));
+ __ StoreToOffset(kStoreWord, R1, SP, destination.GetStackIndex());
+ __ StoreToOffset(kStoreWord, R2, SP, destination.GetHighStackIndex(kArmWordSize));
} else {
__ StoreToOffset(kStoreWordPair, source.AsRegisterPairLow<Register>(),
SP, destination.GetStackIndex());
@@ -521,19 +522,19 @@
} else if (source.IsQuickParameter()) {
InvokeDexCallingConvention calling_convention;
uint32_t argument_index = source.GetQuickParameterIndex();
- __ str(calling_convention.GetRegisterAt(argument_index),
- Address(SP, destination.GetStackIndex()));
- __ ldr(R0,
- Address(SP, calling_convention.GetStackOffsetOf(argument_index + 1) + GetFrameSize()));
- __ str(R0, Address(SP, destination.GetHighStackIndex(kArmWordSize)));
+ __ StoreToOffset(kStoreWord, calling_convention.GetRegisterAt(argument_index),
+ SP, destination.GetStackIndex());
+ __ LoadFromOffset(kLoadWord, R0,
+ SP, calling_convention.GetStackOffsetOf(argument_index + 1) + GetFrameSize());
+ __ StoreToOffset(kStoreWord, R0, SP, destination.GetHighStackIndex(kArmWordSize));
} else if (source.IsFpuRegister()) {
__ vstrd(source.As<DRegister>(), Address(SP, destination.GetStackIndex()));
} else {
DCHECK(source.IsDoubleStackSlot());
- __ ldr(IP, Address(SP, source.GetStackIndex()));
- __ str(IP, Address(SP, destination.GetStackIndex()));
- __ ldr(IP, Address(SP, source.GetHighStackIndex(kArmWordSize)));
- __ str(IP, Address(SP, destination.GetHighStackIndex(kArmWordSize)));
+ __ LoadFromOffset(kLoadWord, IP, SP, source.GetStackIndex());
+ __ StoreToOffset(kStoreWord, IP, SP, destination.GetStackIndex());
+ __ LoadFromOffset(kLoadWord, IP, SP, source.GetHighStackIndex(kArmWordSize));
+ __ StoreToOffset(kStoreWord, IP, SP, destination.GetHighStackIndex(kArmWordSize));
}
}
}
@@ -551,7 +552,7 @@
} else {
DCHECK(location.IsStackSlot());
__ LoadImmediate(IP, value);
- __ str(IP, Address(SP, location.GetStackIndex()));
+ __ StoreToOffset(kStoreWord, IP, SP, location.GetStackIndex());
}
} else if (instruction->AsLongConstant() != nullptr) {
int64_t value = instruction->AsLongConstant()->GetValue();
@@ -561,9 +562,9 @@
} else {
DCHECK(location.IsDoubleStackSlot());
__ LoadImmediate(IP, Low32Bits(value));
- __ str(IP, Address(SP, location.GetStackIndex()));
+ __ StoreToOffset(kStoreWord, IP, SP, location.GetStackIndex());
__ LoadImmediate(IP, High32Bits(value));
- __ str(IP, Address(SP, location.GetHighStackIndex(kArmWordSize)));
+ __ StoreToOffset(kStoreWord, IP, SP, location.GetHighStackIndex(kArmWordSize));
}
} else if (instruction->AsLoadLocal() != nullptr) {
uint32_t stack_slot = GetStackSlot(instruction->AsLoadLocal()->GetLocal());
@@ -902,7 +903,7 @@
}
void InstructionCodeGeneratorARM::LoadCurrentMethod(Register reg) {
- __ ldr(reg, Address(SP, kCurrentMethodStackOffset));
+ __ LoadFromOffset(kLoadWord, reg, SP, kCurrentMethodStackOffset);
}
void InstructionCodeGeneratorARM::VisitInvokeStatic(HInvokeStatic* invoke) {
@@ -921,12 +922,12 @@
// temp = method;
LoadCurrentMethod(temp);
// temp = temp->dex_cache_resolved_methods_;
- __ ldr(temp, Address(temp, mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value()));
+ __ LoadFromOffset(kLoadWord, temp, temp, mirror::ArtMethod::DexCacheResolvedMethodsOffset().Int32Value());
// temp = temp[index_in_cache]
- __ ldr(temp, Address(temp, index_in_cache));
+ __ LoadFromOffset(kLoadWord, temp, temp, index_in_cache);
// LR = temp[offset_of_quick_compiled_code]
- __ ldr(LR, Address(temp,
- mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset().Int32Value()));
+ __ LoadFromOffset(kLoadWord, LR, temp,
+ mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset().Int32Value());
// LR()
__ blx(LR);
@@ -980,16 +981,16 @@
uint32_t class_offset = mirror::Object::ClassOffset().Int32Value();
// temp = object->GetClass();
if (receiver.IsStackSlot()) {
- __ ldr(temp, Address(SP, receiver.GetStackIndex()));
- __ ldr(temp, Address(temp, class_offset));
+ __ LoadFromOffset(kLoadWord, temp, SP, receiver.GetStackIndex());
+ __ LoadFromOffset(kLoadWord, temp, temp, class_offset);
} else {
- __ ldr(temp, Address(receiver.As<Register>(), class_offset));
+ __ LoadFromOffset(kLoadWord, temp, receiver.As<Register>(), class_offset);
}
// temp = temp->GetMethodAt(method_offset);
uint32_t entry_point = mirror::ArtMethod::EntryPointFromQuickCompiledCodeOffset().Int32Value();
- __ ldr(temp, Address(temp, method_offset));
+ __ LoadFromOffset(kLoadWord, temp, temp, method_offset);
// LR = temp->GetEntryPoint();
- __ ldr(LR, Address(temp, entry_point));
+ __ LoadFromOffset(kLoadWord, LR, temp, entry_point);
// LR();
__ blx(LR);
DCHECK(!codegen_->IsLeafMethod());
@@ -1139,7 +1140,7 @@
__ LoadImmediate(calling_convention.GetRegisterAt(0), instruction->GetTypeIndex());
int32_t offset = QUICK_ENTRYPOINT_OFFSET(kArmWordSize, pAllocObjectWithAccessCheck).Int32Value();
- __ ldr(LR, Address(TR, offset));
+ __ LoadFromOffset(kLoadWord, LR, TR, offset);
__ blx(LR);
codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
@@ -1552,7 +1553,7 @@
case Primitive::kPrimNot: {
int32_t offset = QUICK_ENTRYPOINT_OFFSET(kArmWordSize, pAputObject).Int32Value();
- __ ldr(LR, Address(TR, offset));
+ __ LoadFromOffset(kLoadWord, LR, TR, offset);
__ blx(LR);
codegen_->RecordPcInfo(instruction, instruction->GetDexPc());
DCHECK(!codegen_->IsLeafMethod());
@@ -1713,7 +1714,7 @@
} else {
DCHECK(destination.IsStackSlot());
__ LoadImmediate(IP, value);
- __ str(IP, Address(SP, destination.GetStackIndex()));
+ __ StoreToOffset(kStoreWord, IP, SP, destination.GetStackIndex());
}
}
}