Index: src/IceTargetLoweringX86BaseImpl.h |
diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h |
index 56ee04d32e6510add168fd47871608b65c2cc9e2..0a6df2b12a3484defe01109b8b2b4317d730d39e 100644 |
--- a/src/IceTargetLoweringX86BaseImpl.h |
+++ b/src/IceTargetLoweringX86BaseImpl.h |
@@ -290,6 +290,10 @@ template <class Machine> void TargetX86Base<Machine>::staticInit() { |
template <class Machine> void TargetX86Base<Machine>::translateO2() { |
TimerMarker T(TimerStack::TT_O2, Func); |
+ // Merge Alloca instructions, and lay out the stack. |
+ Func->processAllocas(); |
+ Func->dump("After Alloca combining"); |
+ |
if (!Ctx->getFlags().getPhiEdgeSplit()) { |
// Lower Phi instructions. |
Func->placePhiLoads(); |
@@ -957,6 +961,7 @@ void TargetX86Base<Machine>::lowerAlloca(const InstAlloca *Inst) { |
uint32_t Alignment = |
std::max(AlignmentParam, Traits::X86_STACK_ALIGNMENT_BYTES); |
if (Alignment > Traits::X86_STACK_ALIGNMENT_BYTES) { |
+ setHasFramePointer(); |
_and(esp, Ctx->getConstantInt32(-Alignment)); |
} |
if (const auto *ConstantTotalSize = |
@@ -5429,9 +5434,12 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed, |
Variable *RegBase = nullptr; |
Variable *RegIndex = nullptr; |
if (Base) { |
- RegBase = legalizeToReg(Base); |
+ RegBase = llvm::cast<Variable>( |
+ legalize(Base, Legal_Reg | Legal_Rematerializable)); |
} |
if (Index) { |
+ RegIndex = llvm::cast<Variable>( |
+ legalize(Index, Legal_Reg | Legal_Rematerializable)); |
RegIndex = legalizeToReg(Index); |
Jim Stichnoth
2015/11/11 17:39:45
This statement eliminates the effect of the previo
sehr
2015/11/11 22:14:11
Cursed cut/paste. I wanted the rematerializable v
|
} |
if (Base != RegBase || Index != RegIndex) { |
@@ -5504,12 +5512,26 @@ Operand *TargetX86Base<Machine>::legalize(Operand *From, LegalMask Allowed, |
// either when the variable is pre-colored or when it is assigned infinite |
// weight. |
bool MustHaveRegister = (Var->hasReg() || Var->mustHaveReg()); |
+ bool MustRematerialize = |
+ (Var->isRematerializable() && !(Allowed & Legal_Rematerializable)); |
// We need a new physical register for the operand if: |
- // Mem is not allowed and Var isn't guaranteed a physical |
+ // - Mem is not allowed and Var isn't guaranteed a physical |
Jim Stichnoth
2015/11/11 17:39:45
reflow to 80-col
sehr
2015/11/11 22:14:11
Done.
|
// register, or |
- // RegNum is required and Var->getRegNum() doesn't match. |
- if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
- (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) { |
+ // - RegNum is required and Var->getRegNum() doesn't match, or |
+ // - Var is a rematerializable variable and rematerializable pass-through |
Jim Stichnoth
2015/11/11 17:39:45
reflow
sehr
2015/11/11 22:14:11
Done.
|
+ // is not allowed (in which case we need an lea instruction). |
+ if (MustRematerialize) { |
+ assert(Ty == IceType_i32); |
+ Variable *NewVar = makeReg(Ty, RegNum); |
+ // Since Var is rematerializable, the offset will be added when the |
Jim Stichnoth
2015/11/11 17:39:45
reflow
sehr
2015/11/11 22:14:11
Done.
|
+ // lea is emitted. |
+ Constant *Offset = Ctx->getConstantInt(Ty, 0); |
Jim Stichnoth
2015/11/11 17:39:45
John's cool new style:
Constant *_0 = Ctx->getC
sehr
2015/11/11 22:14:11
Chose the latter. Fewer constant lookups is goo.
|
+ auto *Mem = Traits::X86OperandMem::create(Func, Ty, Var, Offset); |
+ _lea(NewVar, Mem); |
+ From = NewVar; |
+ } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) || |
+ (RegNum != Variable::NoRegister && RegNum != Var->getRegNum()) || |
+ MustRematerialize) { |
From = copyToReg(From, RegNum); |
} |
return From; |