summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2015-11-13 19:06:01 +0000
committerReid Kleckner <rnk@google.com>2015-11-13 19:06:01 +0000
commit94b57065c67c9d578bcff2c4b8d08f22e6c3fe81 (patch)
tree73b8318d84091389e005ee4d7307b7cd7f620ff1 /llvm/lib
parent1d37e60dc5a703bf6c7ed2330846e28175dc7b2c (diff)
downloadbcm5719-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.cpp43
-rw-r--r--llvm/lib/Target/X86/X86FrameLowering.h3
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp15
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
OpenPOWER on IntegriCloud