diff options
author | Reid Kleckner <rnk@google.com> | 2015-11-13 19:06:01 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2015-11-13 19:06:01 +0000 |
commit | 94b57065c67c9d578bcff2c4b8d08f22e6c3fe81 (patch) | |
tree | 73b8318d84091389e005ee4d7307b7cd7f620ff1 /llvm/lib | |
parent | 1d37e60dc5a703bf6c7ed2330846e28175dc7b2c (diff) | |
download | bcm5719-llvm-94b57065c67c9d578bcff2c4b8d08f22e6c3fe81.tar.gz bcm5719-llvm-94b57065c67c9d578bcff2c4b8d08f22e6c3fe81.zip |
[WinEH] Make UnwindHelp a fixed stack object allocated after XMM CSRs
Now the offset of UnwindHelp in our EH tables and the offset that we
store to in the prologue agree.
llvm-svn: 253059
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 43 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.h | 3 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86ISelLowering.cpp | 15 |
3 files changed, 45 insertions, 16 deletions
diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index da48a871930..302fc936744 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -1696,10 +1696,11 @@ int X86FrameLowering::getFrameIndexReferenceFromSP(const MachineFunction &MF, // RETADDR // PUSH RBP <-- RBP points here // PUSH CSRs - // ~~~~~~~ <-- optional stack realignment dynamic adjustment + // ~~~~~~~ <-- possible stack realignment (non-win64) // ... // STACK OBJECTS // ... <-- RSP after prologue points here + // ~~~~~~~ <-- possible stack realignment (win64) // // if (hasVarSizedObjects()): // ... <-- "base pointer" (ESI/RBX) points here @@ -1721,7 +1722,8 @@ int X86FrameLowering::getFrameIndexReferenceFromSP(const MachineFunction &MF, // answer we give is relative to the SP after the prologue, and not the // SP in the middle of the function. - assert((!TRI->needsStackRealignment(MF) || !MFI->isFixedObjectIndex(FI)) && + assert((!MFI->isFixedObjectIndex(FI) || !TRI->needsStackRealignment(MF) || + STI.isTargetWin64()) && "offset from fixed object to SP is not static"); // We don't handle tail calls, and shouldn't be seeing them either. @@ -2642,3 +2644,40 @@ unsigned X86FrameLowering::getWinEHParentFrameOffset(const MachineFunction &MF) Offset += getWinEHFuncletFrameSize(MF); return Offset; } + +void X86FrameLowering::processFunctionBeforeFrameFinalized( + MachineFunction &MF, RegScavenger *RS) const { + // If this function isn't doing Win64-style C++ EH, we don't need to do + // anything. + const Function *Fn = MF.getFunction(); + if (!STI.is64Bit() || !Fn->hasPersonalityFn() || + classifyEHPersonality(MF.getFunction()->getPersonalityFn()) != + EHPersonality::MSVC_CXX) + return; + + // Win64 C++ EH needs to allocate the UnwindHelp object at some fixed offset + // relative to RSP after the prologue. Find the offset of the last fixed + // object, so that we can allocate a slot immediately following it. Fixed + // objects have negative frame indices. + MachineFrameInfo *MFI = MF.getFrameInfo(); + int64_t MinFixedObjOffset = 0; + for (int I = MFI->getObjectIndexBegin(); I < 0; ++I) + MinFixedObjOffset = std::min(MinFixedObjOffset, MFI->getObjectOffset(I)); + + int64_t UnwindHelpOffset = MinFixedObjOffset - SlotSize; + int UnwindHelpFI = + MFI->CreateFixedObject(SlotSize, UnwindHelpOffset, /*Immutable=*/false); + MF.getMMI().getWinEHFuncInfo(Fn).UnwindHelpFrameIdx = UnwindHelpFI; + + // Store -2 into UnwindHelp on function entry. We have to scan forwards past + // other frame setup instructions. + MachineBasicBlock &MBB = MF.front(); + auto MBBI = MBB.begin(); + while (MBBI != MBB.end() && MBBI->getFlag(MachineInstr::FrameSetup)) + ++MBBI; + + DebugLoc DL = MBB.findDebugLoc(MBBI); + addFrameReference(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64mi32)), + UnwindHelpFI) + .addImm(-2); +} diff --git a/llvm/lib/Target/X86/X86FrameLowering.h b/llvm/lib/Target/X86/X86FrameLowering.h index 753d155657d..68dc8edfd43 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.h +++ b/llvm/lib/Target/X86/X86FrameLowering.h @@ -109,6 +109,9 @@ public: unsigned getWinEHParentFrameOffset(const MachineFunction &MF) const override; + void processFunctionBeforeFrameFinalized(MachineFunction &MF, + RegScavenger *RS) const override; + /// Check the instruction before/after the passed instruction. If /// it is an ADD/SUB/LEA instruction it is deleted argument and the /// stack adjustment is returned as a positive value for ADD/LEA and diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index fdb716ebca4..93a4dc291f5 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2880,20 +2880,7 @@ SDValue X86TargetLowering::LowerFormalArguments( if (MMI.hasWinEHFuncInfo(Fn)) { EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn()); - if (Personality == EHPersonality::MSVC_CXX) { - if (Is64Bit) { - int UnwindHelpFI = MFI->CreateStackObject(8, 8, /*isSS=*/false); - SDValue StackSlot = DAG.getFrameIndex(UnwindHelpFI, MVT::i64); - MMI.getWinEHFuncInfo(MF.getFunction()).UnwindHelpFrameIdx = - UnwindHelpFI; - SDValue Neg2 = DAG.getConstant(-2, dl, MVT::i64); - Chain = DAG.getStore(Chain, dl, Neg2, StackSlot, - MachinePointerInfo::getFixedStack( - DAG.getMachineFunction(), UnwindHelpFI), - /*isVolatile=*/true, - /*isNonTemporal=*/false, /*Alignment=*/0); - } - } else if (Personality == EHPersonality::CoreCLR) { + if (Personality == EHPersonality::CoreCLR) { assert(Is64Bit); // TODO: Add a mechanism to frame lowering that will allow us to indicate // that we'd prefer this slot be allocated towards the bottom of the frame |