Subzero. ARM32. Removes memory legalization warts.
This CL removes two warts from the ARM32 backend:
1) during argument lowering, if a stack parameter is assigned a
register, the backend creates a new Variable that references the stack
location with the incoming argument, and _mov() it to the parameter.
2) During stack slot legalization, all _mov(Mem(), Reg) are converted to
stores; and all _mov(Reg, Mem()) are converted to loads.
BUG= https://code.google.com/p/nativeclient/issues/detail?id=4076
R=kschimpf@google.com
Review URL: https://codereview.chromium.org/1457683004 .
diff --git a/src/IceTargetLoweringARM32.h b/src/IceTargetLoweringARM32.h
index 8970838..318bce5 100644
--- a/src/IceTargetLoweringARM32.h
+++ b/src/IceTargetLoweringARM32.h
@@ -135,7 +135,7 @@
Operand *loOperand(Operand *Operand);
Operand *hiOperand(Operand *Operand);
void finishArgumentLowering(Variable *Arg, Variable *FramePtr,
- size_t BasicFrameOffset, size_t &InArgsSizeBytes);
+ size_t BasicFrameOffset, size_t *InArgsSizeBytes);
bool hasCPUFeature(TargetARM32Features::ARM32InstructionSet I) const {
return CPUFeatures.hasFeature(I);
@@ -384,6 +384,7 @@
// an assert around just in case there is some untested code path where Dest
// is nullptr.
assert(Dest != nullptr);
+ assert(!llvm::isa<OperandARM32Mem>(Src0));
auto *Instr = InstARM32Mov::create(Func, Dest, Src0, Pred);
Context.insert(Instr);
@@ -794,15 +795,15 @@
CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vcmp::create(Func, Src0, FpZero, Pred));
}
+ void _veor(Variable *Dest, Variable *Src0, Variable *Src1) {
+ Context.insert(InstARM32Veor::create(Func, Dest, Src0, Src1));
+ }
void _vmrs(CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vmrs::create(Func, Pred));
}
void _vmul(Variable *Dest, Variable *Src0, Variable *Src1) {
Context.insert(InstARM32Vmul::create(Func, Dest, Src0, Src1));
}
- void _veor(Variable *Dest, Variable *Src0, Variable *Src1) {
- Context.insert(InstARM32Veor::create(Func, Dest, Src0, Src1));
- }
void _vsqrt(Variable *Dest, Variable *Src,
CondARM32::Cond Pred = CondARM32::AL) {
Context.insert(InstARM32Vsqrt::create(Func, Dest, Src, Pred));
@@ -821,17 +822,27 @@
// [OrigBaseReg, +/- Offset+StackAdjust].
Variable *newBaseRegister(int32_t Offset, int32_t StackAdjust,
Variable *OrigBaseReg);
- /// Creates a new, legal StackVariable w.r.t. ARM's Immediate requirements.
- /// This method is not very smart: it will always create and return a new
- /// StackVariable, even if Offset + StackAdjust is encodable.
- StackVariable *legalizeStackSlot(Type Ty, int32_t Offset, int32_t StackAdjust,
- Variable *OrigBaseReg, Variable **NewBaseReg,
- int32_t *NewBaseOffset);
- /// Legalizes Mov if its Source (or Destination) contains an invalid
- /// immediate.
- void legalizeMovStackAddrImm(InstARM32Mov *Mov, int32_t StackAdjust,
- Variable *OrigBaseReg, Variable **NewBaseReg,
- int32_t *NewBaseOffset);
+ /// Creates a new, legal OperandARM32Mem for accessing OrigBase + Offset +
+ /// StackAdjust. The returned mem operand is a legal operand for accessing
+ /// memory that is of type Ty.
+ ///
+ /// If [OrigBaseReg, #Offset+StackAdjust] is encodable, then the method
+ /// returns a Mem operand expressing it. Otherwise,
+ ///
+ /// if [*NewBaseReg, #Offset+StackAdjust-*NewBaseOffset] is encodable, the
+ /// method will return that. Otherwise,
+ ///
+ /// a new base register ip=OrigBaseReg+Offset+StackAdjust is created, and the
+ /// method returns [ip, #0].
+ OperandARM32Mem *createMemOperand(Type Ty, int32_t Offset,
+ int32_t StackAdjust, Variable *OrigBaseReg,
+ Variable **NewBaseReg,
+ int32_t *NewBaseOffset);
+ /// Legalizes Mov if its Source (or Destination) is a spilled Variable. Moves
+ /// to memory become store instructions, and moves from memory, loads.
+ void legalizeMov(InstARM32Mov *Mov, int32_t StackAdjust,
+ Variable *OrigBaseReg, Variable **NewBaseReg,
+ int32_t *NewBaseOffset);
TargetARM32Features CPUFeatures;
bool UsesFramePointer = false;