#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/Support/Compiler.h"
using namespace llvm;
X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm,
// Stack Frame Processing methods
//===----------------------------------------------------------------------===//
+static unsigned calculateMaxStackAlignment(const MachineFrameInfo *FFI) {
+ unsigned MaxAlign = 0;
+ for (int i = FFI->getObjectIndexBegin(),
+ e = FFI->getObjectIndexEnd(); i != e; ++i) {
+ if (FFI->isDeadObjectIndex(i))
+ continue;
+ unsigned Align = FFI->getObjectAlignment(i);
+ MaxAlign = std::max(MaxAlign, Align);
+ }
+
+ return MaxAlign;
+}
+
// hasFP - Return true if the specified function should have a dedicated frame
// pointer register. This is true if the function has variable sized allocas or
// if frame pointer elimination is disabled.
bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const {
MachineFrameInfo *MFI = MF.getFrameInfo();;
- return (MFI->getMaxAlignment() > StackAlign);
+ // FIXME: Currently we don't support stack realignment for functions with
+ // variable-sized allocas
+ return (RealignStack &&
+ (MFI->getMaxAlignment() > StackAlign &&
+ !MFI->hasVarSizedObjects()));
}
bool X86RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
return !MF.getFrameInfo()->hasVarSizedObjects();
}
+int
+X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
+ int Offset = MF.getFrameInfo()->getObjectOffset(FI) + SlotSize;
+ uint64_t StackSize = MF.getFrameInfo()->getStackSize();
+
+ if (needsStackRealignment(MF)) {
+ if (FI < 0)
+ // Skip the saved EBP
+ Offset += SlotSize;
+ else {
+ unsigned MaxAlign = MF.getFrameInfo()->getMaxAlignment();
+ uint64_t FrameSize =
+ (StackSize - SlotSize + MaxAlign - 1)/MaxAlign*MaxAlign;
+
+ return Offset + FrameSize - SlotSize;
+ }
+
+ // FIXME: Support tail calls
+ } else {
+ if (!hasFP(MF))
+ return Offset + StackSize;
+
+ // Skip the saved EBP
+ Offset += SlotSize;
+
+ // Skip the RETADDR move area
+ X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
+ int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
+ if (TailCallReturnAddrDelta < 0) Offset -= TailCallReturnAddrDelta;
+ }
+
+ return Offset;
+}
+
void X86RegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
}
int FrameIndex = MI.getOperand(i).getIndex();
+
+ unsigned BasePtr;
+ if (needsStackRealignment(MF))
+ BasePtr = (FrameIndex < 0 ? FramePtr : StackPtr);
+ else
+ BasePtr = (hasFP(MF) ? FramePtr : StackPtr);
+
// This must be part of a four operand memory reference. Replace the
// FrameIndex with base register with EBP. Add an offset to the offset.
- MI.getOperand(i).ChangeToRegister(hasFP(MF) ? FramePtr : StackPtr, false);
+ MI.getOperand(i).ChangeToRegister(BasePtr, false);
// Now add the frame object offset to the offset from EBP.
- int64_t Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
- MI.getOperand(i+3).getImm()+SlotSize;
-
- if (!hasFP(MF))
- Offset += MF.getFrameInfo()->getStackSize();
- else {
- Offset += SlotSize; // Skip the saved EBP
- // Skip the RETADDR move area
- X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
- int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
- if (TailCallReturnAddrDelta < 0) Offset -= TailCallReturnAddrDelta;
- }
+ int64_t Offset = getFrameIndexOffset(MF, FrameIndex) +
+ MI.getOperand(i+3).getImm();
MI.getOperand(i+3).ChangeToImmediate(Offset);
}
+void
+X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
+ RegScavenger *RS) const {
+ MachineFrameInfo *FFI = MF.getFrameInfo();
+
+ // Calculate and set max stack object alignment early, so we can decide
+ // whether we will need stack realignment (and thus FP).
+ unsigned MaxAlign = std::max(FFI->getMaxAlignment(),
+ calculateMaxStackAlignment(FFI));
+
+ FFI->setMaxAlignment(MaxAlign);
+}
+
void
X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
// Get the number of bytes to allocate from the FrameInfo.
uint64_t StackSize = MFI->getStackSize();
+ // Get desired stack alignment
+ uint64_t MaxAlign = MFI->getMaxAlignment();
+
// Add RETADDR move area to callee saved frame size.
int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
if (TailCallReturnAddrDelta < 0)
X86FI->setCalleeSavedFrameSize(
X86FI->getCalleeSavedFrameSize() +(-TailCallReturnAddrDelta));
- uint64_t NumBytes = StackSize - X86FI->getCalleeSavedFrameSize();
// Insert stack pointer adjustment for later moving of return addr. Only
// applies to tail call optimized functions where the callee argument stack
StackPtr).addReg(StackPtr).addImm(-TailCallReturnAddrDelta);
}
+ uint64_t NumBytes = 0;
if (hasFP(MF)) {
+ // Calculate required stack adjustment
+ uint64_t FrameSize = StackSize - SlotSize;
+ if (needsStackRealignment(MF))
+ FrameSize = (FrameSize + MaxAlign - 1)/MaxAlign*MaxAlign;
+
+ NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize();
+
// Get the offset of the stack slot for the EBP register... which is
// guaranteed to be the last slot by processFunctionBeforeFrameFinalized.
// Update the frame offset adjustment.
- MFI->setOffsetAdjustment(SlotSize-NumBytes);
+ MFI->setOffsetAdjustment(-NumBytes);
// Save EBP into the appropriate stack slot...
BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r))
.addReg(FramePtr);
- NumBytes -= SlotSize;
if (needsFrameMoves) {
// Mark effective beginning of when frame pointer becomes valid.
// Update EBP with the new base value...
BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr)
.addReg(StackPtr);
- }
+
+ // Realign stack
+ if (needsStackRealignment(MF))
+ BuildMI(MBB, MBBI,
+ TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri),
+ StackPtr).addReg(StackPtr).addImm(-MaxAlign);
+ } else
+ NumBytes = StackSize - X86FI->getCalleeSavedFrameSize();
unsigned ReadyLabelId = 0;
if (needsFrameMoves) {
if (needsFrameMoves)
emitFrameMoves(MF, FrameLabelId, ReadyLabelId);
-
- // If it's main() on Cygwin\Mingw32 we should align stack as well
- if (Fn->hasExternalLinkage() && Fn->getName() == "main" &&
- Subtarget->isTargetCygMing()) {
- BuildMI(MBB, MBBI, TII.get(X86::AND32ri), X86::ESP)
- .addReg(X86::ESP).addImm(-StackAlign);
-
- // Probe the stack
- BuildMI(MBB, MBBI, TII.get(X86::MOV32ri), X86::EAX).addImm(StackAlign);
- BuildMI(MBB, MBBI, TII.get(X86::CALLpcrel32)).addExternalSymbol("_alloca");
- }
}
void X86RegisterInfo::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();
- const Function* Fn = MF.getFunction();
X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
- const X86Subtarget* Subtarget = &MF.getTarget().getSubtarget<X86Subtarget>();
MachineBasicBlock::iterator MBBI = prior(MBB.end());
unsigned RetOpcode = MBBI->getOpcode();
// Get the number of bytes to allocate from the FrameInfo
uint64_t StackSize = MFI->getStackSize();
+ uint64_t MaxAlign = MFI->getMaxAlignment();
unsigned CSSize = X86FI->getCalleeSavedFrameSize();
- uint64_t NumBytes = StackSize - CSSize;
+ uint64_t NumBytes = 0;
if (hasFP(MF)) {
+ // Calculate required stack adjustment
+ uint64_t FrameSize = StackSize - SlotSize;
+ if (needsStackRealignment(MF))
+ FrameSize = (FrameSize + MaxAlign - 1)/MaxAlign*MaxAlign;
+
+ NumBytes = FrameSize - CSSize;
+
// pop EBP.
BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr);
- NumBytes -= SlotSize;
- }
+ } else
+ NumBytes = StackSize - CSSize;
// Skip the callee-saved pop instructions.
+ MachineBasicBlock::iterator LastCSPop = MBBI;
while (MBBI != MBB.begin()) {
MachineBasicBlock::iterator PI = prior(MBBI);
unsigned Opc = PI->getOpcode();
mergeSPUpdatesUp(MBB, MBBI, StackPtr, &NumBytes);
// If dynamic alloca is used, then reset esp to point to the last callee-saved
- // slot before popping them off! Also, if it's main() on Cygwin/Mingw32 we
- // aligned stack in the prologue, - revert stack changes back. Note: we're
- // assuming, that frame pointer was forced for main()
- if (MFI->hasVarSizedObjects() ||
- (Fn->hasExternalLinkage() && Fn->getName() == "main" &&
- Subtarget->isTargetCygMing())) {
- unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r;
+ // slot before popping them off! Same applies for the case, when stack was
+ // realigned
+ if (needsStackRealignment(MF)) {
+ // We cannot use LEA here, because stack pointer was realigned. We need to
+ // deallocate local frame back
if (CSSize) {
+ emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
+ MBBI = prior(LastCSPop);
+ }
+
+ BuildMI(MBB, MBBI,
+ TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),
+ StackPtr).addReg(FramePtr);
+ } else if (MFI->hasVarSizedObjects()) {
+ if (CSSize) {
+ unsigned Opc = Is64Bit ? X86::LEA64r : X86::LEA32r;
MachineInstr *MI = addRegOffset(BuildMI(TII.get(Opc), StackPtr),
FramePtr, -CSSize);
MBB.insert(MBBI, MI);
BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),StackPtr).
addReg(FramePtr);
- NumBytes = 0;
+ } else {
+ // adjust stack pointer back: ESP += numbytes
+ if (NumBytes)
+ emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
}
- // adjust stack pointer back: ESP += numbytes
- if (NumBytes)
- emitSPUpdate(MBB, MBBI, StackPtr, NumBytes, Is64Bit, TII);
-
// We're returning from function via eh_return.
if (RetOpcode == X86::EH_RETURN) {
MBBI = prior(MBB.end());
return hasFP(MF) ? FramePtr : StackPtr;
}
-int
-X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const {
- int Offset = MF.getFrameInfo()->getObjectOffset(FI) + SlotSize;
- if (!hasFP(MF))
- return Offset + MF.getFrameInfo()->getStackSize();
-
- Offset += SlotSize; // Skip the saved EBP
- // Skip the RETADDR move area
- X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
- int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta();
- if (TailCallReturnAddrDelta < 0) Offset -= TailCallReturnAddrDelta;
- return Offset;
-}
-
void X86RegisterInfo::getInitialFrameState(std::vector<MachineMove> &Moves)
const {
// Calculate amount of bytes used for return address storing
}
namespace llvm {
-unsigned getX86SubSuperRegister(unsigned Reg, MVT::ValueType VT, bool High) {
- switch (VT) {
+unsigned getX86SubSuperRegister(unsigned Reg, MVT VT, bool High) {
+ switch (VT.getSimpleVT()) {
default: return Reg;
case MVT::i8:
if (High) {
}
#include "X86GenRegisterInfo.inc"
+
+namespace {
+ struct VISIBILITY_HIDDEN MSAC : public MachineFunctionPass {
+ static char ID;
+ MSAC() : MachineFunctionPass((intptr_t)&ID) {}
+
+ virtual bool runOnMachineFunction(MachineFunction &MF) {
+ MachineFrameInfo *FFI = MF.getFrameInfo();
+ MachineRegisterInfo &RI = MF.getRegInfo();
+
+ // Calculate max stack alignment of all already allocated stack objects.
+ unsigned MaxAlign = calculateMaxStackAlignment(FFI);
+
+ // Be over-conservative: scan over all vreg defs and find, whether vector
+ // registers are used. If yes - there is probability, that vector register
+ // will be spilled and thus stack needs to be aligned properly.
+ for (unsigned RegNum = TargetRegisterInfo::FirstVirtualRegister;
+ RegNum < RI.getLastVirtReg(); ++RegNum)
+ MaxAlign = std::max(MaxAlign, RI.getRegClass(RegNum)->getAlignment());
+
+ FFI->setMaxAlignment(MaxAlign);
+
+ return false;
+ }
+
+ virtual const char *getPassName() const {
+ return "X86 Maximal Stack Alignment Calculator";
+ }
+ };
+
+ char MSAC::ID = 0;
+}
+
+FunctionPass*
+llvm::createX86MaxStackAlignmentCalculatorPass() { return new MSAC(); }