[llvm] r240044 - [X86] Refactor stack adjustments into X86FrameLowering::BuildStackAdjustment
Reid Kleckner
reid at kleckner.net
Thu Jun 18 13:22:12 PDT 2015
Author: rnk
Date: Thu Jun 18 15:22:12 2015
New Revision: 240044
URL: http://llvm.org/viewvc/llvm-project?rev=240044&view=rev
Log:
[X86] Refactor stack adjustments into X86FrameLowering::BuildStackAdjustment
Deduplicates some code and lets us use LEA on atom when adjusting the
stack around callee-cleanup calls. This is the only intended
functionality change.
Modified:
llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp
llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
llvm/trunk/lib/Target/X86/X86FrameLowering.h
Modified: llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp?rev=240044&r1=240043&r2=240044&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ExpandPseudo.cpp Thu Jun 18 15:22:12 2015
@@ -84,14 +84,9 @@ bool X86ExpandPseudo::ExpandMI(MachineBa
int StackAdj = StackAdjust.getImm();
if (StackAdj) {
- // standard x86_64 and NaCl use 64-bit frame/stack pointers, x32 - 32-bit.
- // Check if we should use LEA for SP.
- const X86FrameLowering *TFI = STI->getFrameLowering();
- bool UseLEAForSP = STI->useLeaForSP() &&
- X86FL->canUseLEAForSPInEpilogue(*MBB.getParent());
// Check for possible merge with preceding ADD instruction.
- StackAdj += TFI->mergeSPUpdates(MBB, MBBI, true);
- TFI->emitSPUpdate(MBB, MBBI, StackAdj, UseLEAForSP);
+ StackAdj += X86FL->mergeSPUpdates(MBB, MBBI, true);
+ X86FL->emitSPUpdate(MBB, MBBI, StackAdj, /*InEpilogue=*/true);
}
// Jump to label or value in register.
Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.cpp?rev=240044&r1=240043&r2=240044&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.cpp Thu Jun 18 15:22:12 2015
@@ -214,20 +214,36 @@ static bool isEAXLiveIn(MachineFunction
return false;
}
+/// Check whether or not the terminators of \p MBB needs to read EFLAGS.
+static bool terminatorsNeedFlagsAsInput(const MachineBasicBlock &MBB) {
+ for (const MachineInstr &MI : MBB.terminators()) {
+ bool BreakNext = false;
+ for (const MachineOperand &MO : MI.operands()) {
+ if (!MO.isReg())
+ continue;
+ unsigned Reg = MO.getReg();
+ if (Reg != X86::EFLAGS)
+ continue;
+
+ // This terminator needs an eflag that is not defined
+ // by a previous terminator.
+ if (!MO.isDef())
+ return true;
+ BreakNext = true;
+ }
+ if (BreakNext)
+ break;
+ }
+ return false;
+}
+
/// emitSPUpdate - Emit a series of instructions to increment / decrement the
/// stack pointer by a constant value.
void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
- int64_t NumBytes, bool UseLEA) const {
+ int64_t NumBytes, bool InEpilogue) const {
bool isSub = NumBytes < 0;
uint64_t Offset = isSub ? -NumBytes : NumBytes;
- unsigned Opc;
- if (UseLEA)
- Opc = getLEArOpcode(Uses64BitFramePtr);
- else
- Opc = isSub
- ? getSUBriOpcode(Uses64BitFramePtr, Offset)
- : getADDriOpcode(Uses64BitFramePtr, Offset);
uint64_t Chunk = (1LL << 31) - 1;
DebugLoc DL = MBB.findDebugLoc(MBBI);
@@ -244,7 +260,7 @@ void X86FrameLowering::emitSPUpdate(Mach
Reg = findDeadCallerSavedReg(MBB, MBBI, RegInfo, Is64Bit);
if (Reg) {
- Opc = Is64Bit ? X86::MOV64ri : X86::MOV32ri;
+ unsigned Opc = Is64Bit ? X86::MOV64ri : X86::MOV32ri;
BuildMI(MBB, MBBI, DL, TII.get(Opc), Reg)
.addImm(Offset);
Opc = isSub
@@ -266,7 +282,7 @@ void X86FrameLowering::emitSPUpdate(Mach
? (unsigned)(Is64Bit ? X86::RAX : X86::EAX)
: findDeadCallerSavedReg(MBB, MBBI, RegInfo, Is64Bit);
if (Reg) {
- Opc = isSub
+ unsigned Opc = isSub
? (Is64Bit ? X86::PUSH64r : X86::PUSH32r)
: (Is64Bit ? X86::POP64r : X86::POP32r);
MachineInstr *MI = BuildMI(MBB, MBBI, DL, TII.get(Opc))
@@ -278,25 +294,59 @@ void X86FrameLowering::emitSPUpdate(Mach
}
}
- MachineInstr *MI = nullptr;
-
- if (UseLEA) {
- MI = addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr),
- StackPtr, false, isSub ? -ThisVal : ThisVal);
- } else {
- MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr)
- .addReg(StackPtr)
- .addImm(ThisVal);
- MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
- }
-
+ MachineInstrBuilder MI = BuildStackAdjustment(
+ MBB, MBBI, DL, isSub ? -ThisVal : ThisVal, InEpilogue);
if (isSub)
- MI->setFlag(MachineInstr::FrameSetup);
+ MI.setMIFlag(MachineInstr::FrameSetup);
Offset -= ThisVal;
}
}
+MachineInstrBuilder X86FrameLowering::BuildStackAdjustment(
+ MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL,
+ int64_t Offset, bool InEpilogue) const {
+ assert(Offset != 0 && "zero offset stack adjustment requested");
+
+ // On Atom, using LEA to adjust SP is preferred, but using it in the epilogue
+ // is tricky.
+ bool UseLEA;
+ if (!InEpilogue) {
+ UseLEA = STI.useLeaForSP();
+ } else {
+ // If we can use LEA for SP but we shouldn't, check that none
+ // of the terminators uses the eflags. Otherwise we will insert
+ // a ADD that will redefine the eflags and break the condition.
+ // Alternatively, we could move the ADD, but this may not be possible
+ // and is an optimization anyway.
+ UseLEA = canUseLEAForSPInEpilogue(*MBB.getParent());
+ if (UseLEA && !STI.useLeaForSP())
+ UseLEA = terminatorsNeedFlagsAsInput(MBB);
+ // If that assert breaks, that means we do not do the right thing
+ // in canUseAsEpilogue.
+ assert((UseLEA || !terminatorsNeedFlagsAsInput(MBB)) &&
+ "We shouldn't have allowed this insertion point");
+ }
+
+ MachineInstrBuilder MI;
+ if (UseLEA) {
+ MI = addRegOffset(BuildMI(MBB, MBBI, DL,
+ TII.get(getLEArOpcode(Uses64BitFramePtr)),
+ StackPtr),
+ StackPtr, false, Offset);
+ } else {
+ bool IsSub = Offset < 0;
+ uint64_t AbsOffset = IsSub ? -Offset : Offset;
+ unsigned Opc = IsSub ? getSUBriOpcode(Uses64BitFramePtr, AbsOffset)
+ : getADDriOpcode(Uses64BitFramePtr, AbsOffset);
+ MI = BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr)
+ .addReg(StackPtr)
+ .addImm(AbsOffset);
+ MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
+ }
+ return MI;
+}
+
/// mergeSPUpdatesUp - Merge two stack-manipulating instructions upper iterator.
static
void mergeSPUpdatesUp(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
@@ -602,7 +652,6 @@ void X86FrameLowering::emitPrologue(Mach
bool NeedsWinCFI = IsWin64Prologue && Fn->needsUnwindTableEntry();
bool NeedsDwarfCFI =
!IsWin64Prologue && (MMI.hasDebugInfo() || Fn->needsUnwindTableEntry());
- bool UseLEA = STI.useLeaForSP();
unsigned FramePtr = RegInfo->getFrameRegister(MF);
const unsigned MachineFramePtr =
STI.isTarget64BitILP32()
@@ -652,14 +701,9 @@ void X86FrameLowering::emitPrologue(Mach
// applies to tail call optimized functions where the callee argument stack
// size is bigger than the callers.
if (TailCallReturnAddrDelta < 0) {
- MachineInstr *MI =
- BuildMI(MBB, MBBI, DL,
- TII.get(getSUBriOpcode(Uses64BitFramePtr, -TailCallReturnAddrDelta)),
- StackPtr)
- .addReg(StackPtr)
- .addImm(-TailCallReturnAddrDelta)
+ BuildStackAdjustment(MBB, MBBI, DL, TailCallReturnAddrDelta,
+ /*InEpilogue=*/false)
.setMIFlag(MachineInstr::FrameSetup);
- MI->getOperand(3).setIsDead(); // The EFLAGS implicit def is dead.
}
// Mapping for machine moves:
@@ -856,7 +900,7 @@ void X86FrameLowering::emitPrologue(Mach
MBB.insert(MBBI, MI);
}
} else if (NumBytes) {
- emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, UseLEA);
+ emitSPUpdate(MBB, MBBI, -(int64_t)NumBytes, /*InEpilogue=*/false);
}
if (NeedsWinCFI && NumBytes)
@@ -958,29 +1002,6 @@ bool X86FrameLowering::canUseLEAForSPInE
return !MF.getTarget().getMCAsmInfo()->usesWindowsCFI() || hasFP(MF);
}
-/// Check whether or not the terminators of \p MBB needs to read EFLAGS.
-static bool terminatorsNeedFlagsAsInput(const MachineBasicBlock &MBB) {
- for (const MachineInstr &MI : MBB.terminators()) {
- bool BreakNext = false;
- for (const MachineOperand &MO : MI.operands()) {
- if (!MO.isReg())
- continue;
- unsigned Reg = MO.getReg();
- if (Reg != X86::EFLAGS)
- continue;
-
- // This terminator needs an eflag that is not defined
- // by a previous terminator.
- if (!MO.isDef())
- return true;
- BreakNext = true;
- }
- if (BreakNext)
- break;
- }
- return false;
-}
-
void X86FrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
@@ -999,18 +1020,6 @@ void X86FrameLowering::emitEpilogue(Mach
bool IsWin64Prologue = MF.getTarget().getMCAsmInfo()->usesWindowsCFI();
bool NeedsWinCFI =
IsWin64Prologue && MF.getFunction()->needsUnwindTableEntry();
- bool UseLEAForSP = canUseLEAForSPInEpilogue(MF);
- // If we can use LEA for SP but we shouldn't, check that none
- // of the terminators uses the eflags. Otherwise we will insert
- // a ADD that will redefine the eflags and break the condition.
- // Alternatively, we could move the ADD, but this may not be possible
- // and is an optimization anyway.
- if (UseLEAForSP && !STI.useLeaForSP())
- UseLEAForSP = terminatorsNeedFlagsAsInput(MBB);
- // If that assert breaks, that means we do not do the right thing
- // in canUseAsEpilogue.
- assert((UseLEAForSP || !terminatorsNeedFlagsAsInput(MBB)) &&
- "We shouldn't have allowed this insertion point");
// Get the number of bytes to allocate from the FrameInfo.
uint64_t StackSize = MFI->getStackSize();
@@ -1087,7 +1096,7 @@ void X86FrameLowering::emitEpilogue(Mach
}
} else if (NumBytes) {
// Adjust stack pointer back: ESP += numbytes.
- emitSPUpdate(MBB, MBBI, NumBytes, UseLEAForSP);
+ emitSPUpdate(MBB, MBBI, NumBytes, /*InEpilogue=*/true);
--MBBI;
}
@@ -1108,7 +1117,7 @@ void X86FrameLowering::emitEpilogue(Mach
// Check for possible merge with preceding ADD instruction.
Offset += mergeSPUpdates(MBB, MBBI, true);
- emitSPUpdate(MBB, MBBI, Offset, UseLEAForSP);
+ emitSPUpdate(MBB, MBBI, Offset, /*InEpilogue=*/true);
}
}
@@ -1880,54 +1889,29 @@ eliminateCallFramePseudoInstr(MachineFun
unsigned StackAlign = getStackAlignment();
Amount = RoundUpToAlignment(Amount, StackAlign);
- MachineInstr *New = nullptr;
-
// Factor out the amount that gets handled inside the sequence
// (Pushes of argument for frame setup, callee pops for frame destroy)
Amount -= InternalAmt;
if (Amount) {
- if (Opcode == TII.getCallFrameSetupOpcode()) {
- New = BuildMI(MF, DL, TII.get(getSUBriOpcode(IsLP64, Amount)), StackPtr)
- .addReg(StackPtr).addImm(Amount);
- } else {
- assert(Opcode == TII.getCallFrameDestroyOpcode());
-
- unsigned Opc = getADDriOpcode(IsLP64, Amount);
- New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
- .addReg(StackPtr).addImm(Amount);
- }
+ // Add Amount to SP to destroy a frame, and subtract to setup.
+ int Offset = isDestroy ? Amount : -Amount;
+ BuildStackAdjustment(MBB, I, DL, Offset, /*InEpilogue=*/false);
}
-
- if (New) {
- // The EFLAGS implicit def is dead.
- New->getOperand(3).setIsDead();
-
- // Replace the pseudo instruction with a new instruction.
- MBB.insert(I, New);
- }
-
return;
}
- if (Opcode == TII.getCallFrameDestroyOpcode() && InternalAmt) {
+ if (isDestroy && InternalAmt) {
// If we are performing frame pointer elimination and if the callee pops
// something off the stack pointer, add it back. We do this until we have
// more advanced stack pointer tracking ability.
- unsigned Opc = getSUBriOpcode(IsLP64, InternalAmt);
- MachineInstr *New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
- .addReg(StackPtr).addImm(InternalAmt);
-
- // The EFLAGS implicit def is dead.
- New->getOperand(3).setIsDead();
-
// We are not tracking the stack pointer adjustment by the callee, so make
// sure we restore the stack pointer immediately after the call, there may
// be spill code inserted between the CALL and ADJCALLSTACKUP instructions.
MachineBasicBlock::iterator B = MBB.begin();
while (I != B && !std::prev(I)->isCall())
--I;
- MBB.insert(I, New);
+ BuildStackAdjustment(MBB, I, DL, -InternalAmt, /*InEpilogue=*/false);
}
}
Modified: llvm/trunk/lib/Target/X86/X86FrameLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86FrameLowering.h?rev=240044&r1=240043&r2=240044&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86FrameLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86FrameLowering.h Thu Jun 18 15:22:12 2015
@@ -18,6 +18,7 @@
namespace llvm {
+class MachineInstrBuilder;
class MCCFIInstruction;
class X86Subtarget;
class X86RegisterInfo;
@@ -112,7 +113,7 @@ public:
/// Emit a series of instructions to increment / decrement the stack
/// pointer by a constant value.
void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
- int64_t NumBytes, bool UseLEA) const;
+ int64_t NumBytes, bool InEpilogue) const;
/// Check that LEA can be used on SP in an epilogue sequence for \p MF.
bool canUseLEAForSPInEpilogue(const MachineFunction &MF) const;
@@ -144,6 +145,12 @@ private:
void BuildStackAlignAND(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MBBI, DebugLoc DL,
uint64_t MaxAlign) const;
+
+ /// Adjusts the stack pointer using LEA, SUB, or ADD.
+ MachineInstrBuilder BuildStackAdjustment(MachineBasicBlock &MBB,
+ MachineBasicBlock::iterator MBBI,
+ DebugLoc DL, int64_t Offset,
+ bool InEpilogue) const;
};
} // End llvm namespace
More information about the llvm-commits
mailing list