diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/WinException.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.cpp | 34 | ||||
-rw-r--r-- | llvm/lib/Target/X86/X86FrameLowering.h | 4 |
3 files changed, 43 insertions, 9 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp index 319320a09e0..fab5b3a59eb 100644 --- a/llvm/lib/CodeGen/AsmPrinter/WinException.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/WinException.cpp @@ -710,6 +710,13 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { OS.EmitValue(create32bitRef(HandlerMapXData), 4); // HandlerArray } + // All funclets use the same parent frame offset currently. + unsigned ParentFrameOffset = 0; + if (shouldEmitPersonality) { + const TargetFrameLowering *TFI = MF->getSubtarget().getFrameLowering(); + ParentFrameOffset = TFI->getWinEHParentFrameOffset(*MF); + } + for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) { WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I]; MCSymbol *HandlerMapXData = HandlerMaps[I]; @@ -749,13 +756,8 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) { OS.EmitValue(create32bitRef(HT.TypeDescriptor), 4); // Type OS.EmitValue(FrameAllocOffsetRef, 4); // CatchObjOffset OS.EmitValue(create32bitRef(HandlerSym), 4); // Handler - - if (shouldEmitPersonality) { - // Keep this in sync with X86FrameLowering::emitPrologue. - int ParentFrameOffset = - 16 + 8 + MF->getFrameInfo()->getMaxCallFrameSize(); + if (shouldEmitPersonality) OS.EmitIntValue(ParentFrameOffset, 4); // ParentFrameOffset - } } } } diff --git a/llvm/lib/Target/X86/X86FrameLowering.cpp b/llvm/lib/Target/X86/X86FrameLowering.cpp index 83a4acd7a4a..b4dccb60ccc 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.cpp +++ b/llvm/lib/Target/X86/X86FrameLowering.cpp @@ -786,7 +786,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF, // NumBytes value that we would've used for the parent frame. unsigned ParentFrameNumBytes = NumBytes; if (IsFunclet) - NumBytes = MFI->getMaxCallFrameSize(); + NumBytes = getWinEHFuncletFrameSize(MF); // Skip the callee-saved push instructions. bool PushedRegs = false; @@ -1039,6 +1039,22 @@ static bool isFuncletReturnInstr(MachineInstr *MI) { llvm_unreachable("impossible"); } +unsigned X86FrameLowering::getWinEHFuncletFrameSize(const MachineFunction &MF) const { + // This is the size of the pushed CSRs. + unsigned CSSize = + MF.getInfo<X86MachineFunctionInfo>()->getCalleeSavedFrameSize(); + // This is the amount of stack a funclet needs to allocate. + unsigned MaxCallSize = MF.getFrameInfo()->getMaxCallFrameSize(); + // RBP is not included in the callee saved register block. After pushing RBP, + // everything is 16 byte aligned. Everything we allocate before an outgoing + // call must also be 16 byte aligned. + unsigned FrameSizeMinusRBP = + RoundUpToAlignment(CSSize + MaxCallSize, getStackAlignment()); + // Subtract out the size of the callee saved registers. This is how much stack + // each funclet will allocate. + return FrameSizeMinusRBP - CSSize; +} + void X86FrameLowering::emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const { const MachineFrameInfo *MFI = MF.getFrameInfo(); @@ -1067,7 +1083,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, uint64_t NumBytes = 0; if (MBBI->getOpcode() == X86::CATCHRET) { - NumBytes = MFI->getMaxCallFrameSize(); + NumBytes = getWinEHFuncletFrameSize(MF); assert(hasFP(MF) && "EH funclets without FP not yet implemented"); MachineBasicBlock *TargetMBB = MBBI->getOperand(0).getMBB(); @@ -1107,7 +1123,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF, .addMBB(TargetMBB); } } else if (MBBI->getOpcode() == X86::CLEANUPRET) { - NumBytes = MFI->getMaxCallFrameSize(); + NumBytes = getWinEHFuncletFrameSize(MF); assert(hasFP(MF) && "EH funclets without FP not yet implemented"); BuildMI(MBB, MBBI, DL, TII.get(Is64Bit ? X86::POP64r : X86::POP32r), MachineFramePtr) @@ -2211,3 +2227,15 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers( } return MBBI; } + +unsigned X86FrameLowering::getWinEHParentFrameOffset(const MachineFunction &MF) const { + // RDX, the parent frame pointer, is homed into 16(%rsp) in the prologue. + unsigned Offset = 16; + // RBP is immediately pushed. + Offset += SlotSize; + // All callee-saved registers are then pushed. + Offset += MF.getInfo<X86MachineFunctionInfo>()->getCalleeSavedFrameSize(); + // Every funclet allocates enough stack space for the largest outgoing call. + Offset += getWinEHFuncletFrameSize(MF); + return Offset; +} diff --git a/llvm/lib/Target/X86/X86FrameLowering.h b/llvm/lib/Target/X86/X86FrameLowering.h index b9cf3a99bb3..59c6a062810 100644 --- a/llvm/lib/Target/X86/X86FrameLowering.h +++ b/llvm/lib/Target/X86/X86FrameLowering.h @@ -101,6 +101,8 @@ public: MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const override; + unsigned getWinEHParentFrameOffset(const MachineFunction &MF) 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 @@ -152,6 +154,8 @@ private: restoreWin32EHStackPointers(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, DebugLoc DL, bool RestoreSP = false) const; + + unsigned getWinEHFuncletFrameSize(const MachineFunction &MF) const; }; } // End llvm namespace |