| Index: src/IceTargetLoweringX86BaseImpl.h
|
| diff --git a/src/IceTargetLoweringX86BaseImpl.h b/src/IceTargetLoweringX86BaseImpl.h
|
| index 922efd6a8469d30d8f24ea9f6747653273ea0415..8f372196779cc6b3c068655afb1ccd4ff3948165 100644
|
| --- a/src/IceTargetLoweringX86BaseImpl.h
|
| +++ b/src/IceTargetLoweringX86BaseImpl.h
|
| @@ -82,7 +82,7 @@ public:
|
| PK_Icmp64,
|
| PK_Fcmp,
|
| PK_Trunc,
|
| - PK_Arith // A flag-setting arithmetic instruction.
|
| + PK_Arith // A flag-setting arithmetic instruction.
|
| };
|
|
|
| /// Currently the actual enum values are not used (other than CK_None), but we
|
| @@ -302,6 +302,11 @@ 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.
|
| + static constexpr bool SortAndCombineAllocas = true;
|
| + Func->processAllocas(SortAndCombineAllocas);
|
| + Func->dump("After Alloca processing");
|
| +
|
| if (!Ctx->getFlags().getPhiEdgeSplit()) {
|
| // Lower Phi instructions.
|
| Func->placePhiLoads();
|
| @@ -420,6 +425,11 @@ template <class Machine> void TargetX86Base<Machine>::translateO2() {
|
| template <class Machine> void TargetX86Base<Machine>::translateOm1() {
|
| TimerMarker T(TimerStack::TT_Om1, Func);
|
|
|
| + // Do not merge Alloca instructions, and lay out the stack.
|
| + static constexpr bool SortAndCombineAllocas = false;
|
| + Func->processAllocas(SortAndCombineAllocas);
|
| + Func->dump("After Alloca processing");
|
| +
|
| Func->placePhiLoads();
|
| if (Func->hasError())
|
| return;
|
| @@ -945,7 +955,7 @@ TargetX86Base<Machine>::getRegisterSet(RegSetMask Include,
|
| template <class Machine>
|
| void TargetX86Base<Machine>::lowerAlloca(const InstAlloca *Inst) {
|
| if (!Inst->getKnownFrameOffset())
|
| - IsEbpBasedFrame = true;
|
| + setHasFramePointer();
|
| // Conservatively require the stack to be aligned. Some stack adjustment
|
| // operations implemented below assume that the stack is aligned before the
|
| // alloca. All the alloca code ensures that the stack alignment is preserved
|
| @@ -969,6 +979,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 =
|
| @@ -5500,10 +5511,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 = legalizeToReg(Index);
|
| + RegIndex = llvm::cast<Variable>(
|
| + legalize(Index, Legal_Reg | Legal_Rematerializable));
|
| }
|
| if (Base != RegBase || Index != RegIndex) {
|
| Mem = Traits::X86OperandMem::create(Func, Ty, RegBase, Mem->getOffset(),
|
| @@ -5575,12 +5588,25 @@ 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
|
| - // register, or
|
| - // RegNum is required and Var->getRegNum() doesn't match.
|
| - if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
|
| - (RegNum != Variable::NoRegister && RegNum != Var->getRegNum())) {
|
| + // - Mem is not allowed and Var isn't guaranteed a physical register, or
|
| + // - RegNum is required and Var->getRegNum() doesn't match, or
|
| + // - Var is a rematerializable variable and rematerializable pass-through 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 lea is
|
| + // emitted.
|
| + constexpr Constant *NoOffset = nullptr;
|
| + auto *Mem = Traits::X86OperandMem::create(Func, Ty, Var, NoOffset);
|
| + _lea(NewVar, Mem);
|
| + From = NewVar;
|
| + } else if ((!(Allowed & Legal_Mem) && !MustHaveRegister) ||
|
| + (RegNum != Variable::NoRegister && RegNum != Var->getRegNum()) ||
|
| + MustRematerialize) {
|
| From = copyToReg(From, RegNum);
|
| }
|
| return From;
|
|
|