X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTarget%2FX86%2FX86RegisterInfo.cpp;h=6bb05c5ebe2851f4ebe8e9bb921f976fe7be21ff;hp=b48cee3ac338df6616839d0c5b69bcb1e5d2f9eb;hb=c25e7581b9b8088910da31702d4ca21c4734c6d7;hpb=b5dae003252d8e650a32bfdf33cba5aed8e41e40 diff --git a/lib/Target/X86/X86RegisterInfo.cpp b/lib/Target/X86/X86RegisterInfo.cpp index b48cee3ac33..6bb05c5ebe2 100644 --- a/lib/Target/X86/X86RegisterInfo.cpp +++ b/lib/Target/X86/X86RegisterInfo.cpp @@ -25,6 +25,7 @@ #include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineFunction.h" +#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineLocation.h" #include "llvm/CodeGen/MachineModuleInfo.h" @@ -37,11 +38,17 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" using namespace llvm; X86RegisterInfo::X86RegisterInfo(X86TargetMachine &tm, const TargetInstrInfo &tii) - : X86GenRegisterInfo(X86::ADJCALLSTACKDOWN, X86::ADJCALLSTACKUP), + : X86GenRegisterInfo(tm.getSubtarget().is64Bit() ? + X86::ADJCALLSTACKDOWN64 : + X86::ADJCALLSTACKDOWN32, + tm.getSubtarget().is64Bit() ? + X86::ADJCALLSTACKUP64 : + X86::ADJCALLSTACKUP32), TM(tm), TII(tii) { // Cache some information. const X86Subtarget *Subtarget = &TM.getSubtarget(); @@ -140,11 +147,19 @@ unsigned X86RegisterInfo::getX86RegNum(unsigned RegNo) { default: assert(isVirtualRegister(RegNo) && "Unknown physical register!"); - assert(0 && "Register allocator hasn't allocated reg correctly yet!"); + LLVM_UNREACHABLE("Register allocator hasn't allocated reg correctly yet!"); return 0; } } +const TargetRegisterClass *X86RegisterInfo::getPointerRegClass() const { + const X86Subtarget *Subtarget = &TM.getSubtarget(); + if (Subtarget->is64Bit()) + return &X86::GR64RegClass; + else + return &X86::GR32RegClass; +} + const TargetRegisterClass * X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { if (RC == &X86::CCRRegClass) { @@ -158,6 +173,14 @@ X86RegisterInfo::getCrossCopyRegClass(const TargetRegisterClass *RC) const { const unsigned * X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { + bool callsEHReturn = false; + + if (MF) { + const MachineFrameInfo *MFI = MF->getFrameInfo(); + const MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); + callsEHReturn = (MMI ? MMI->callsEHReturn() : false); + } + static const unsigned CalleeSavedRegs32Bit[] = { X86::ESI, X86::EDI, X86::EBX, X86::EBP, 0 }; @@ -170,29 +193,39 @@ X86RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { X86::RBX, X86::R12, X86::R13, X86::R14, X86::R15, X86::RBP, 0 }; + static const unsigned CalleeSavedRegs64EHRet[] = { + X86::RAX, X86::RDX, X86::RBX, X86::R12, + X86::R13, X86::R14, X86::R15, X86::RBP, 0 + }; + static const unsigned CalleeSavedRegsWin64[] = { - X86::RBX, X86::RBP, X86::RDI, X86::RSI, - X86::R12, X86::R13, X86::R14, X86::R15, 0 + X86::RBX, X86::RBP, X86::RDI, X86::RSI, + X86::R12, X86::R13, X86::R14, X86::R15, + X86::XMM6, X86::XMM7, X86::XMM8, X86::XMM9, + X86::XMM10, X86::XMM11, X86::XMM12, X86::XMM13, + X86::XMM14, X86::XMM15, 0 }; if (Is64Bit) { if (IsWin64) return CalleeSavedRegsWin64; else - return CalleeSavedRegs64Bit; + return (callsEHReturn ? CalleeSavedRegs64EHRet : CalleeSavedRegs64Bit); } else { - if (MF) { - MachineFrameInfo *MFI = MF->getFrameInfo(); - MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); - if (MMI && MMI->callsEHReturn()) - return CalleeSavedRegs32EHRet; - } - return CalleeSavedRegs32Bit; + return (callsEHReturn ? CalleeSavedRegs32EHRet : CalleeSavedRegs32Bit); } } const TargetRegisterClass* const* X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { + bool callsEHReturn = false; + + if (MF) { + const MachineFrameInfo *MFI = MF->getFrameInfo(); + const MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); + callsEHReturn = (MMI ? MMI->callsEHReturn() : false); + } + static const TargetRegisterClass * const CalleeSavedRegClasses32Bit[] = { &X86::GR32RegClass, &X86::GR32RegClass, &X86::GR32RegClass, &X86::GR32RegClass, 0 @@ -207,42 +240,62 @@ X86RegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const { &X86::GR64RegClass, &X86::GR64RegClass, &X86::GR64RegClass, &X86::GR64RegClass, 0 }; - static const TargetRegisterClass * const CalleeSavedRegClassesWin64[] = { + static const TargetRegisterClass * const CalleeSavedRegClasses64EHRet[] = { &X86::GR64RegClass, &X86::GR64RegClass, &X86::GR64RegClass, &X86::GR64RegClass, &X86::GR64RegClass, &X86::GR64RegClass, &X86::GR64RegClass, &X86::GR64RegClass, 0 }; + static const TargetRegisterClass * const CalleeSavedRegClassesWin64[] = { + &X86::GR64RegClass, &X86::GR64RegClass, + &X86::GR64RegClass, &X86::GR64RegClass, + &X86::GR64RegClass, &X86::GR64RegClass, + &X86::GR64RegClass, &X86::GR64RegClass, + &X86::VR128RegClass, &X86::VR128RegClass, + &X86::VR128RegClass, &X86::VR128RegClass, + &X86::VR128RegClass, &X86::VR128RegClass, + &X86::VR128RegClass, &X86::VR128RegClass, + &X86::VR128RegClass, &X86::VR128RegClass, 0 + }; if (Is64Bit) { if (IsWin64) return CalleeSavedRegClassesWin64; else - return CalleeSavedRegClasses64Bit; + return (callsEHReturn ? + CalleeSavedRegClasses64EHRet : CalleeSavedRegClasses64Bit); } else { - if (MF) { - MachineFrameInfo *MFI = MF->getFrameInfo(); - MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); - if (MMI && MMI->callsEHReturn()) - return CalleeSavedRegClasses32EHRet; - } - return CalleeSavedRegClasses32Bit; + return (callsEHReturn ? + CalleeSavedRegClasses32EHRet : CalleeSavedRegClasses32Bit); } - } BitVector X86RegisterInfo::getReservedRegs(const MachineFunction &MF) const { BitVector Reserved(getNumRegs()); + // Set the stack-pointer register and its aliases as reserved. Reserved.set(X86::RSP); Reserved.set(X86::ESP); Reserved.set(X86::SP); Reserved.set(X86::SPL); + // Set the frame-pointer register and its aliases as reserved if needed. if (hasFP(MF)) { Reserved.set(X86::RBP); Reserved.set(X86::EBP); Reserved.set(X86::BP); Reserved.set(X86::BPL); } + // Mark the x87 stack registers as reserved, since they don't + // behave normally with respect to liveness. We don't fully + // model the effects of x87 stack pushes and pops after + // stackification. + Reserved.set(X86::ST0); + Reserved.set(X86::ST1); + Reserved.set(X86::ST2); + Reserved.set(X86::ST3); + Reserved.set(X86::ST4); + Reserved.set(X86::ST5); + Reserved.set(X86::ST6); + Reserved.set(X86::ST7); return Reserved; } @@ -268,18 +321,19 @@ static unsigned calculateMaxStackAlignment(const MachineFrameInfo *FFI) { // if frame pointer elimination is disabled. // bool X86RegisterInfo::hasFP(const MachineFunction &MF) const { - MachineFrameInfo *MFI = MF.getFrameInfo(); - MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); + const MachineFrameInfo *MFI = MF.getFrameInfo(); + const MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); return (NoFramePointerElim || needsStackRealignment(MF) || MFI->hasVarSizedObjects() || + MFI->isFrameAddressTaken() || MF.getInfo()->getForceFramePointer() || (MMI && MMI->callsUnwindInit())); } bool X86RegisterInfo::needsStackRealignment(const MachineFunction &MF) const { - MachineFrameInfo *MFI = MF.getFrameInfo();; + const MachineFrameInfo *MFI = MF.getFrameInfo(); // FIXME: Currently we don't support stack realignment for functions with // variable-sized allocas @@ -292,6 +346,16 @@ bool X86RegisterInfo::hasReservedCallFrame(MachineFunction &MF) const { return !MF.getFrameInfo()->hasVarSizedObjects(); } +bool X86RegisterInfo::hasReservedSpillSlot(MachineFunction &MF, unsigned Reg, + int &FrameIdx) const { + if (Reg == FramePtr && hasFP(MF)) { + FrameIdx = MF.getFrameInfo()->getObjectIndexBegin(); + return true; + } + return false; +} + + int X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const { int Offset = MF.getFrameInfo()->getObjectOffset(FI) + SlotSize; @@ -304,6 +368,7 @@ X86RegisterInfo::getFrameIndexOffset(MachineFunction &MF, int FI) const { else { unsigned Align = MF.getFrameInfo()->getObjectAlignment(FI); assert( (-(Offset + StackSize)) % Align == 0); + Align = 0; return Offset + StackSize; } @@ -341,11 +406,12 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, Amount = (Amount+StackAlign-1)/StackAlign*StackAlign; MachineInstr *New = 0; - if (Old->getOpcode() == X86::ADJCALLSTACKDOWN) { - New=BuildMI(TII.get(Is64Bit ? X86::SUB64ri32 : X86::SUB32ri), StackPtr) - .addReg(StackPtr).addImm(Amount); + if (Old->getOpcode() == getCallFrameSetupOpcode()) { + New = BuildMI(MF, Old->getDebugLoc(), + TII.get(Is64Bit ? X86::SUB64ri32 : X86::SUB32ri), + StackPtr).addReg(StackPtr).addImm(Amount); } else { - assert(Old->getOpcode() == X86::ADJCALLSTACKUP); + assert(Old->getOpcode() == getCallFrameDestroyOpcode()); // factor out the amount the callee already popped. uint64_t CalleeAmt = Old->getOperand(1).getImm(); Amount -= CalleeAmt; @@ -353,14 +419,20 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, unsigned Opc = (Amount < 128) ? (Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) : (Is64Bit ? X86::ADD64ri32 : X86::ADD32ri); - New = BuildMI(TII.get(Opc), StackPtr).addReg(StackPtr).addImm(Amount); + New = BuildMI(MF, Old->getDebugLoc(), TII.get(Opc), StackPtr) + .addReg(StackPtr).addImm(Amount); } } - // Replace the pseudo instruction with a new instruction... - if (New) MBB.insert(I, New); + if (New) { + // The EFLAGS implicit def is dead. + New->getOperand(3).setIsDead(); + + // Replace the pseudo instruction with a new instruction... + MBB.insert(I, New); + } } - } else if (I->getOpcode() == X86::ADJCALLSTACKUP) { + } else if (I->getOpcode() == getCallFrameDestroyOpcode()) { // 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. @@ -368,8 +440,13 @@ eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB, unsigned Opc = (CalleeAmt < 128) ? (Is64Bit ? X86::SUB64ri8 : X86::SUB32ri8) : (Is64Bit ? X86::SUB64ri32 : X86::SUB32ri); + MachineInstr *Old = I; MachineInstr *New = - BuildMI(TII.get(Opc), StackPtr).addReg(StackPtr).addImm(CalleeAmt); + BuildMI(MF, Old->getDebugLoc(), TII.get(Opc), + StackPtr).addReg(StackPtr).addImm(CalleeAmt); + // The EFLAGS implicit def is dead. + New->getOperand(3).setIsDead(); + MBB.insert(I, New); } } @@ -384,7 +461,7 @@ void X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, unsigned i = 0; MachineInstr &MI = *II; MachineFunction &MF = *MI.getParent()->getParent(); - while (!MI.getOperand(i).isFrameIndex()) { + while (!MI.getOperand(i).isFI()) { ++i; assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); } @@ -402,10 +479,18 @@ void X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.getOperand(i).ChangeToRegister(BasePtr, false); // Now add the frame object offset to the offset from EBP. - int64_t Offset = getFrameIndexOffset(MF, FrameIndex) + - MI.getOperand(i+3).getImm(); - - MI.getOperand(i+3).ChangeToImmediate(Offset); + if (MI.getOperand(i+3).isImm()) { + // Offset is a 32-bit integer. + int Offset = getFrameIndexOffset(MF, FrameIndex) + + (int)(MI.getOperand(i+3).getImm()); + + MI.getOperand(i+3).ChangeToImmediate(Offset); + } else { + // Offset is symbolic. This is extremely rare. + uint64_t Offset = getFrameIndexOffset(MF, FrameIndex) + + (uint64_t)MI.getOperand(i+3).getOffset(); + MI.getOperand(i+3).setOffset(Offset); + } } void @@ -419,10 +504,7 @@ X86RegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF, calculateMaxStackAlignment(FFI)); FFI->setMaxAlignment(MaxAlign); -} -void -X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{ X86MachineFunctionInfo *X86FI = MF.getInfo(); int32_t TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); if (TailCallReturnAddrDelta < 0) { @@ -448,6 +530,7 @@ X86RegisterInfo::processFunctionBeforeFrameFinalized(MachineFunction &MF) const{ TailCallReturnAddrDelta); assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() && "Slot for EBP register must be last in order to be found!"); + FrameIdx = 0; } } @@ -467,10 +550,16 @@ void emitSPUpdate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, (Is64Bit ? X86::ADD64ri8 : X86::ADD32ri8) : (Is64Bit ? X86::ADD64ri32 : X86::ADD32ri)); uint64_t Chunk = (1LL << 31) - 1; + DebugLoc DL = (MBBI != MBB.end() ? MBBI->getDebugLoc() : + DebugLoc::getUnknownLoc()); while (Offset) { uint64_t ThisVal = (Offset > Chunk) ? Chunk : Offset; - BuildMI(MBB, MBBI, TII.get(Opc), StackPtr).addReg(StackPtr).addImm(ThisVal); + MachineInstr *MI = + BuildMI(MBB, MBBI, DL, TII.get(Opc), StackPtr) + .addReg(StackPtr).addImm(ThisVal); + // The EFLAGS implicit def is dead. + MI->getOperand(3).setIsDead(); Offset -= ThisVal; } } @@ -563,17 +652,20 @@ static int mergeSPUpdates(MachineBasicBlock &MBB, return Offset; } -void X86RegisterInfo::emitFrameMoves(MachineFunction &MF, - unsigned FrameLabelId, - unsigned ReadyLabelId) const { +void X86RegisterInfo::emitCalleeSavedFrameMoves(MachineFunction &MF, + unsigned LabelId, + unsigned FramePtr) const { MachineFrameInfo *MFI = MF.getFrameInfo(); MachineModuleInfo *MMI = MFI->getMachineModuleInfo(); - if (!MMI) - return; + if (!MMI) return; + + // Add callee saved registers to move list. + const std::vector &CSI = MFI->getCalleeSavedInfo(); + if (CSI.empty()) return; - uint64_t StackSize = MFI->getStackSize(); std::vector &Moves = MMI->getFrameMoves(); const TargetData *TD = MF.getTarget().getTargetData(); + bool HasFP = hasFP(MF); // Calculate amount of bytes used for return address storing int stackGrowth = @@ -581,62 +673,53 @@ void X86RegisterInfo::emitFrameMoves(MachineFunction &MF, TargetFrameInfo::StackGrowsUp ? TD->getPointerSize() : -TD->getPointerSize()); - if (StackSize) { - // Show update of SP. - if (hasFP(MF)) { - // Adjust SP - MachineLocation SPDst(MachineLocation::VirtualFP); - MachineLocation SPSrc(MachineLocation::VirtualFP, 2*stackGrowth); - Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); - } else { - MachineLocation SPDst(MachineLocation::VirtualFP); - MachineLocation SPSrc(MachineLocation::VirtualFP, - -StackSize+stackGrowth); - Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); - } - } else { - //FIXME: Verify & implement for FP - MachineLocation SPDst(StackPtr); - MachineLocation SPSrc(StackPtr, stackGrowth); - Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); - } - - // Add callee saved registers to move list. - const std::vector &CSI = MFI->getCalleeSavedInfo(); - // FIXME: This is dirty hack. The code itself is pretty mess right now. // It should be rewritten from scratch and generalized sometimes. // Determine maximum offset (minumum due to stack growth) int64_t MaxOffset = 0; - for (unsigned I = 0, E = CSI.size(); I!=E; ++I) + for (std::vector::const_iterator + I = CSI.begin(), E = CSI.end(); I != E; ++I) MaxOffset = std::min(MaxOffset, - MFI->getObjectOffset(CSI[I].getFrameIdx())); - - // Calculate offsets - int64_t saveAreaOffset = (hasFP(MF) ? 3 : 2)*stackGrowth; - for (unsigned I = 0, E = CSI.size(); I!=E; ++I) { - int64_t Offset = MFI->getObjectOffset(CSI[I].getFrameIdx()); - unsigned Reg = CSI[I].getReg(); - Offset = (MaxOffset-Offset+saveAreaOffset); + MFI->getObjectOffset(I->getFrameIdx())); + + // Calculate offsets. + int64_t saveAreaOffset = (HasFP ? 3 : 2) * stackGrowth; + for (std::vector::const_iterator + I = CSI.begin(), E = CSI.end(); I != E; ++I) { + int64_t Offset = MFI->getObjectOffset(I->getFrameIdx()); + unsigned Reg = I->getReg(); + Offset = MaxOffset - Offset + saveAreaOffset; + + // Don't output a new machine move if we're re-saving the frame + // pointer. This happens when the PrologEpilogInserter has inserted an extra + // "PUSH" of the frame pointer -- the "emitPrologue" method automatically + // generates one when frame pointers are used. If we generate a "machine + // move" for this extra "PUSH", the linker will lose track of the fact that + // the frame pointer should have the value of the first "PUSH" when it's + // trying to unwind. + // + // FIXME: This looks inelegant. It's possibly correct, but it's covering up + // another bug. I.e., one where we generate a prolog like this: + // + // pushl %ebp + // movl %esp, %ebp + // pushl %ebp + // pushl %esi + // ... + // + // The immediate re-push of EBP is unnecessary. At the least, it's an + // optimization bug. EBP can be used as a scratch register in certain + // cases, but probably not when we have a frame pointer. + if (HasFP && FramePtr == Reg) + continue; + MachineLocation CSDst(MachineLocation::VirtualFP, Offset); MachineLocation CSSrc(Reg); - Moves.push_back(MachineMove(FrameLabelId, CSDst, CSSrc)); - } - - if (hasFP(MF)) { - // Save FP - MachineLocation FPDst(MachineLocation::VirtualFP, 2*stackGrowth); - MachineLocation FPSrc(FramePtr); - Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc)); + Moves.push_back(MachineMove(LabelId, CSDst, CSSrc)); } - - MachineLocation FPDst(hasFP(MF) ? FramePtr : StackPtr); - MachineLocation FPSrc(MachineLocation::VirtualFP); - Moves.push_back(MachineMove(ReadyLabelId, FPDst, FPSrc)); } - void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { MachineBasicBlock &MBB = MF.front(); // Prolog goes in entry BB MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -648,11 +731,12 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { bool needsFrameMoves = (MMI && MMI->hasDebugInfo()) || !Fn->doesNotThrow() || UnwindTablesMandatory; - // Prepare for frame info. - unsigned FrameLabelId = 0; + bool HasFP = hasFP(MF); + DebugLoc DL; // Get the number of bytes to allocate from the FrameInfo. uint64_t StackSize = MFI->getStackSize(); + // Get desired stack alignment uint64_t MaxAlign = MFI->getMaxAlignment(); @@ -662,16 +746,44 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { X86FI->setCalleeSavedFrameSize( X86FI->getCalleeSavedFrameSize() +(-TailCallReturnAddrDelta)); + // If this is x86-64 and the Red Zone is not disabled, if we are a leaf + // function, and use up to 128 bytes of stack space, don't have a frame + // pointer, calls, or dynamic alloca then we do not need to adjust the + // stack pointer (we fit in the Red Zone). + bool DisableRedZone = Fn->hasFnAttr(Attribute::NoRedZone); + if (Is64Bit && !DisableRedZone && + !needsStackRealignment(MF) && + !MFI->hasVarSizedObjects() && // No dynamic alloca. + !MFI->hasCalls() && // No calls. + !Subtarget->isTargetWin64()) { // Win64 has no Red Zone + uint64_t MinSize = X86FI->getCalleeSavedFrameSize(); + if (HasFP) MinSize += SlotSize; + StackSize = std::max(MinSize, + StackSize > 128 ? StackSize - 128 : 0); + MFI->setStackSize(StackSize); + } + // Insert stack pointer adjustment for later moving of return addr. Only // applies to tail call optimized functions where the callee argument stack // size is bigger than the callers. if (TailCallReturnAddrDelta < 0) { - BuildMI(MBB, MBBI, TII.get(Is64Bit? X86::SUB64ri32 : X86::SUB32ri), - StackPtr).addReg(StackPtr).addImm(-TailCallReturnAddrDelta); + MachineInstr *MI = + BuildMI(MBB, MBBI, DL, TII.get(Is64Bit? X86::SUB64ri32 : X86::SUB32ri), + StackPtr).addReg(StackPtr).addImm(-TailCallReturnAddrDelta); + // The EFLAGS implicit def is dead. + MI->getOperand(3).setIsDead(); } + // uint64_t StackSize = MFI->getStackSize(); + std::vector &Moves = MMI->getFrameMoves(); + const TargetData *TD = MF.getTarget().getTargetData(); + int stackGrowth = + (MF.getTarget().getFrameInfo()->getStackGrowthDirection() == + TargetFrameInfo::StackGrowsUp ? + TD->getPointerSize() : -TD->getPointerSize()); + uint64_t NumBytes = 0; - if (hasFP(MF)) { + if (HasFP) { // Calculate required stack adjustment uint64_t FrameSize = StackSize - SlotSize; if (needsStackRealignment(MF)) @@ -679,95 +791,166 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { NumBytes = FrameSize - X86FI->getCalleeSavedFrameSize(); - // Get the offset of the stack slot for the EBP register... which is + // 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(-NumBytes); - // Save EBP into the appropriate stack slot... - BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) - .addReg(FramePtr); + // Save EBP/RBP into the appropriate stack slot... + BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::PUSH64r : X86::PUSH32r)) + .addReg(FramePtr, RegState::Kill); if (needsFrameMoves) { // Mark effective beginning of when frame pointer becomes valid. - FrameLabelId = MMI->NextLabelID(); - BuildMI(MBB, MBBI, TII.get(X86::LABEL)).addImm(FrameLabelId).addImm(0); + unsigned FrameLabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(FrameLabelId); + + // Define the current CFA rule to use the provided offset. + if (StackSize) { + MachineLocation SPDst(MachineLocation::VirtualFP); + MachineLocation SPSrc(MachineLocation::VirtualFP, + HasFP ? 2 * stackGrowth : + -StackSize + stackGrowth); + Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); + } else { + // FIXME: Verify & implement for FP + MachineLocation SPDst(StackPtr); + MachineLocation SPSrc(StackPtr, stackGrowth); + Moves.push_back(MachineMove(FrameLabelId, SPDst, SPSrc)); + } + + // Change the rule for the FramePtr to be an "offset" rule. + MachineLocation FPDst(MachineLocation::VirtualFP, 2 * stackGrowth); + MachineLocation FPSrc(FramePtr); + Moves.push_back(MachineMove(FrameLabelId, FPDst, FPSrc)); } // Update EBP with the new base value... - BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr) - .addReg(StackPtr); + BuildMI(MBB, MBBI, DL, + TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), FramePtr) + .addReg(StackPtr); + + if (needsFrameMoves) { + unsigned FrameLabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(FrameLabelId); + + // Define the current CFA to use the EBP/RBP register. + MachineLocation FPDst(FramePtr); + MachineLocation FPSrc(MachineLocation::VirtualFP); + Moves.push_back(MachineMove(FrameLabelId, FPDst, FPSrc)); + } + + // Mark the FramePtr as live-in in every block except the entry. + for (MachineFunction::iterator I = next(MF.begin()), E = MF.end(); + I != E; ++I) + I->addLiveIn(FramePtr); // Realign stack - if (needsStackRealignment(MF)) - BuildMI(MBB, MBBI, - TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri), - StackPtr).addReg(StackPtr).addImm(-MaxAlign); - } else + if (needsStackRealignment(MF)) { + MachineInstr *MI = + BuildMI(MBB, MBBI, DL, + TII.get(Is64Bit ? X86::AND64ri32 : X86::AND32ri), + StackPtr).addReg(StackPtr).addImm(-MaxAlign); + + // The EFLAGS implicit def is dead. + MI->getOperand(3).setIsDead(); + } + } else { NumBytes = StackSize - X86FI->getCalleeSavedFrameSize(); - - unsigned ReadyLabelId = 0; - if (needsFrameMoves) { - // Mark effective beginning of when frame pointer is ready. - ReadyLabelId = MMI->NextLabelID(); - BuildMI(MBB, MBBI, TII.get(X86::LABEL)).addImm(ReadyLabelId).addImm(0); } // Skip the callee-saved push instructions. + bool RegsSaved = false; while (MBBI != MBB.end() && (MBBI->getOpcode() == X86::PUSH32r || - MBBI->getOpcode() == X86::PUSH64r)) + MBBI->getOpcode() == X86::PUSH64r)) { + RegsSaved = true; ++MBBI; + } + + if (RegsSaved && needsFrameMoves) { + // Mark end of callee-saved push instructions. + unsigned LabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(LabelId); - if (NumBytes) { // adjust stack pointer: ESP -= numbytes - if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) { - // Check, whether EAX is livein for this function - bool isEAXAlive = false; - for (MachineRegisterInfo::livein_iterator + // Emit DWARF info specifying the offsets of the callee-saved registers. + emitCalleeSavedFrameMoves(MF, LabelId, HasFP ? FramePtr : StackPtr); + } + + if (MBBI != MBB.end()) + DL = MBBI->getDebugLoc(); + + // Adjust stack pointer: ESP -= numbytes. + if (NumBytes >= 4096 && Subtarget->isTargetCygMing()) { + // Check, whether EAX is livein for this function. + bool isEAXAlive = false; + for (MachineRegisterInfo::livein_iterator II = MF.getRegInfo().livein_begin(), EE = MF.getRegInfo().livein_end(); (II != EE) && !isEAXAlive; ++II) { - unsigned Reg = II->first; - isEAXAlive = (Reg == X86::EAX || Reg == X86::AX || - Reg == X86::AH || Reg == X86::AL); - } + unsigned Reg = II->first; + isEAXAlive = (Reg == X86::EAX || Reg == X86::AX || + Reg == X86::AH || Reg == X86::AL); + } - // Function prologue calls _alloca to probe the stack when allocating - // more than 4k bytes in one go. Touching the stack at 4K increments is - // necessary to ensure that the guard pages used by the OS virtual memory - // manager are allocated in correct sequence. - if (!isEAXAlive) { - BuildMI(MBB, MBBI, TII.get(X86::MOV32ri), X86::EAX).addImm(NumBytes); - BuildMI(MBB, MBBI, TII.get(X86::CALLpcrel32)) - .addExternalSymbol("_alloca"); - } else { - // Save EAX - BuildMI(MBB, MBBI, TII.get(X86::PUSH32r), X86::EAX); - // Allocate NumBytes-4 bytes on stack. We'll also use 4 already - // allocated bytes for EAX. - BuildMI(MBB, MBBI, TII.get(X86::MOV32ri), X86::EAX).addImm(NumBytes-4); - BuildMI(MBB, MBBI, TII.get(X86::CALLpcrel32)) - .addExternalSymbol("_alloca"); - // Restore EAX - MachineInstr *MI = addRegOffset(BuildMI(TII.get(X86::MOV32rm),X86::EAX), - StackPtr, NumBytes-4); - MBB.insert(MBBI, MI); - } + // Function prologue calls _alloca to probe the stack when allocating more + // than 4k bytes in one go. Touching the stack at 4K increments is necessary + // to ensure that the guard pages used by the OS virtual memory manager are + // allocated in correct sequence. + if (!isEAXAlive) { + BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) + .addImm(NumBytes); + BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32)) + .addExternalSymbol("_alloca"); } else { - // If there is an SUB32ri of ESP immediately before this instruction, - // merge the two. This can be the case when tail call elimination is - // enabled and the callee has more arguments then the caller. - NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true); - // If there is an ADD32ri or SUB32ri of ESP immediately after this - // instruction, merge the two instructions. - mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes); - - if (NumBytes) - emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII); + // Save EAX + BuildMI(MBB, MBBI, DL, TII.get(X86::PUSH32r)) + .addReg(X86::EAX, RegState::Kill); + + // Allocate NumBytes-4 bytes on stack. We'll also use 4 already + // allocated bytes for EAX. + BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX) + .addImm(NumBytes - 4); + BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32)) + .addExternalSymbol("_alloca"); + + // Restore EAX + MachineInstr *MI = addRegOffset(BuildMI(MF, DL, TII.get(X86::MOV32rm), + X86::EAX), + StackPtr, false, NumBytes - 4); + MBB.insert(MBBI, MI); } + } else if (NumBytes) { + // If there is an SUB32ri of ESP immediately before this instruction, merge + // the two. This can be the case when tail call elimination is enabled and + // the callee has more arguments then the caller. + NumBytes -= mergeSPUpdates(MBB, MBBI, StackPtr, true); + + // If there is an ADD32ri or SUB32ri of ESP immediately after this + // instruction, merge the two instructions. + mergeSPUpdatesDown(MBB, MBBI, StackPtr, &NumBytes); + + if (NumBytes) + emitSPUpdate(MBB, MBBI, StackPtr, -(int64_t)NumBytes, Is64Bit, TII); } - if (needsFrameMoves) - emitFrameMoves(MF, FrameLabelId, ReadyLabelId); + if (!HasFP && needsFrameMoves && NumBytes) { + // Mark end of stack pointer adjustment. + unsigned LabelId = MMI->NextLabelID(); + BuildMI(MBB, MBBI, DL, TII.get(X86::DBG_LABEL)).addImm(LabelId); + + // Define the current CFA rule to use the provided offset. + if (StackSize) { + MachineLocation SPDst(MachineLocation::VirtualFP); + MachineLocation SPSrc(MachineLocation::VirtualFP, + -StackSize + stackGrowth); + Moves.push_back(MachineMove(LabelId, SPDst, SPSrc)); + } else { + // FIXME: Verify & implement for FP + MachineLocation SPDst(StackPtr); + MachineLocation SPSrc(StackPtr, stackGrowth); + Moves.push_back(MachineMove(LabelId, SPDst, SPSrc)); + } + } } void X86RegisterInfo::emitEpilogue(MachineFunction &MF, @@ -776,6 +959,7 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF, X86MachineFunctionInfo *X86FI = MF.getInfo(); MachineBasicBlock::iterator MBBI = prior(MBB.end()); unsigned RetOpcode = MBBI->getOpcode(); + DebugLoc DL = MBBI->getDebugLoc(); switch (RetOpcode) { case X86::RET: @@ -785,11 +969,12 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF, case X86::TCRETURNri64: case X86::TCRETURNdi64: case X86::EH_RETURN: + case X86::EH_RETURN64: case X86::TAILJMPd: case X86::TAILJMPr: case X86::TAILJMPm: break; // These are ok default: - assert(0 && "Can only insert epilog into returning blocks"); + LLVM_UNREACHABLE("Can only insert epilog into returning blocks"); } // Get the number of bytes to allocate from the FrameInfo @@ -807,9 +992,11 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF, NumBytes = FrameSize - CSSize; // pop EBP. - BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr); - } else + BuildMI(MBB, MBBI, DL, + TII.get(Is64Bit ? X86::POP64r : X86::POP32r), FramePtr); + } else { NumBytes = StackSize - CSSize; + } // Skip the callee-saved pop instructions. MachineBasicBlock::iterator LastCSPop = MBBI; @@ -822,6 +1009,8 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF, --MBBI; } + DL = MBBI->getDebugLoc(); + // If there is an ADD32ri or SUB32ri of ESP immediately before this // instruction, merge the two instructions. if (NumBytes || MFI->hasVarSizedObjects()) @@ -838,18 +1027,18 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF, MBBI = prior(LastCSPop); } - BuildMI(MBB, MBBI, + BuildMI(MBB, MBBI, DL, 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); + MachineInstr *MI = addLeaRegOffset(BuildMI(MF, DL, TII.get(Opc), StackPtr), + FramePtr, false, -CSSize); MBB.insert(MBBI, MI); } else - BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),StackPtr). - addReg(FramePtr); + BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), + StackPtr).addReg(FramePtr); } else { // adjust stack pointer back: ESP += numbytes @@ -858,19 +1047,20 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF, } // We're returning from function via eh_return. - if (RetOpcode == X86::EH_RETURN) { + if (RetOpcode == X86::EH_RETURN || RetOpcode == X86::EH_RETURN64) { MBBI = prior(MBB.end()); MachineOperand &DestAddr = MBBI->getOperand(0); - assert(DestAddr.isRegister() && "Offset should be in register!"); - BuildMI(MBB, MBBI, TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr),StackPtr). - addReg(DestAddr.getReg()); + assert(DestAddr.isReg() && "Offset should be in register!"); + BuildMI(MBB, MBBI, DL, + TII.get(Is64Bit ? X86::MOV64rr : X86::MOV32rr), + StackPtr).addReg(DestAddr.getReg()); // Tail call return: adjust the stack pointer and jump to callee } else if (RetOpcode == X86::TCRETURNri || RetOpcode == X86::TCRETURNdi || RetOpcode== X86::TCRETURNri64 || RetOpcode == X86::TCRETURNdi64) { MBBI = prior(MBB.end()); MachineOperand &JumpTarget = MBBI->getOperand(0); MachineOperand &StackAdjust = MBBI->getOperand(1); - assert( StackAdjust.isImmediate() && "Expecting immediate value."); + assert(StackAdjust.isImm() && "Expecting immediate value."); // Adjust stack pointer. int StackAdj = StackAdjust.getImm(); @@ -880,19 +1070,22 @@ void X86RegisterInfo::emitEpilogue(MachineFunction &MF, // Incoporate the retaddr area. Offset = StackAdj-MaxTCDelta; assert(Offset >= 0 && "Offset should never be negative"); + if (Offset) { // Check for possible merge with preceeding ADD instruction. Offset += mergeSPUpdates(MBB, MBBI, StackPtr, true); emitSPUpdate(MBB, MBBI, StackPtr, Offset, Is64Bit, TII); } + // Jump to label or value in register. if (RetOpcode == X86::TCRETURNdi|| RetOpcode == X86::TCRETURNdi64) - BuildMI(MBB, MBBI, TII.get(X86::TAILJMPd)). + BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPd)). addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset()); - else if (RetOpcode== X86::TCRETURNri64) { - BuildMI(MBB, MBBI, TII.get(X86::TAILJMPr64), JumpTarget.getReg()); - } else - BuildMI(MBB, MBBI, TII.get(X86::TAILJMPr), JumpTarget.getReg()); + else if (RetOpcode== X86::TCRETURNri64) + BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr64), JumpTarget.getReg()); + else + BuildMI(MBB, MBBI, DL, TII.get(X86::TAILJMPr), JumpTarget.getReg()); + // Delete the pseudo instruction TCRETURN. MBB.erase(MBBI); } else if ((RetOpcode == X86::RET || RetOpcode == X86::RETI) && @@ -934,12 +1127,12 @@ void X86RegisterInfo::getInitialFrameState(std::vector &Moves) } unsigned X86RegisterInfo::getEHExceptionRegister() const { - assert(0 && "What is the exception register"); + LLVM_UNREACHABLE("What is the exception register"); return 0; } unsigned X86RegisterInfo::getEHHandlerRegister() const { - assert(0 && "What is the exception handler register"); + LLVM_UNREACHABLE("What is the exception handler register"); return 0; } @@ -1116,7 +1309,7 @@ unsigned getX86SubSuperRegister(unsigned Reg, MVT VT, bool High) { namespace { struct VISIBILITY_HIDDEN MSAC : public MachineFunctionPass { static char ID; - MSAC() : MachineFunctionPass((intptr_t)&ID) {} + MSAC() : MachineFunctionPass(&ID) {} virtual bool runOnMachineFunction(MachineFunction &MF) { MachineFrameInfo *FFI = MF.getFrameInfo();