llvm.org GIT mirror llvm / 595419d
[WinEH] Move WinEHFuncInfo from MachineModuleInfo to MachineFunction Summary: Now that there is a one-to-one mapping from MachineFunction to WinEHFuncInfo, we don't need to use a DenseMap to select the right WinEHFuncInfo for the current funclet. The main challenge here is that X86WinEHStatePass is an IR pass that doesn't have access to the MachineFunction. I gave it its own WinEHFuncInfo object that it uses to calculate state numbers, which it then throws away. As long as nobody creates or removes EH pads between this pass and SDAG construction, we will get the same state numbers. The other thing X86WinEHStatePass does is to mark the EH registration node. Instead of communicating which alloca was the registration through WinEHFuncInfo, I added the llvm.x86.seh.ehregnode intrinsic. This intrinsic generates no code and simply marks the alloca in use. Reviewers: JCTremoulet Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D14668 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253378 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 4 years ago
15 changed file(s) with 121 addition(s) and 194 deletion(s). Raw diff Collapse all Expand all
4242 class TargetSubtargetInfo;
4343 class TargetRegisterClass;
4444 struct MachinePointerInfo;
45 struct WinEHFuncInfo;
4546
4647 template <>
4748 struct ilist_traits
106107 // Keep track of jump tables for switch instructions
107108 MachineJumpTableInfo *JumpTableInfo;
108109
110 // Keeps track of Windows exception handling related data. This will be null
111 // for functions that aren't using a funclet-based EH personality.
112 WinEHFuncInfo *WinEHInfo = nullptr;
113
109114 // Function-level unique numbering for MachineBasicBlocks. When a
110115 // MachineBasicBlock is inserted into a MachineFunction is it automatically
111116 // numbered and this vector keeps track of the mapping from ID's to MBB's.
219224 ///
220225 MachineConstantPool *getConstantPool() { return ConstantPool; }
221226 const MachineConstantPool *getConstantPool() const { return ConstantPool; }
227
228 /// getWinEHFuncInfo - Return information about how the current function uses
229 /// Windows exception handling. Returns null for functions that don't use
230 /// funclets for exception handling.
231 const WinEHFuncInfo *getWinEHFuncInfo() const { return WinEHInfo; }
232 WinEHFuncInfo *getWinEHFuncInfo() { return WinEHInfo; }
222233
223234 /// getAlignment - Return the alignment (log2, not bytes) of the function.
224235 ///
5858 class Module;
5959 class PointerType;
6060 class StructType;
61 struct WinEHFuncInfo;
6261
6362 struct SEHHandler {
6463 // Filter or finally function. Null indicates a catch-all.
7978 SmallVector SEHHandlers; // SEH handlers active at this lpad.
8079 MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
8180 std::vector TypeIds; // List of type ids (filters negative).
82 int WinEHState; // WinEH specific state number.
8381
8482 explicit LandingPadInfo(MachineBasicBlock *MBB)
85 : LandingPadBlock(MBB), LandingPadLabel(nullptr),
86 WinEHState(-1) {}
83 : LandingPadBlock(MBB), LandingPadLabel(nullptr) {}
8784 };
8885
8986 //===----------------------------------------------------------------------===//
181178
182179 EHPersonality PersonalityTypeCache;
183180
184 DenseMap> FuncInfoMap;
185
186181 public:
187182 static char ID; // Pass identification, replacement for typeid
188183
219214 void setModule(const Module *M) { TheModule = M; }
220215 const Module *getModule() const { return TheModule; }
221216
222 WinEHFuncInfo &getWinEHFuncInfo(const Function *F);
223 bool hasWinEHFuncInfo(const Function *F) const {
224 return FuncInfoMap.count(F) > 0;
225 }
226
227217 /// getInfo - Keep track of various per-function pieces of information for
228218 /// backends that would like to do so.
229219 ///
326316 /// information.
327317 void addPersonality(const Function *Personality);
328318
329 void addWinEHState(MachineBasicBlock *LandingPad, int State);
330
331319 /// getPersonalities - Return array of personality functions ever seen.
332320 const std::vector& getPersonalities() const {
333321 return Personalities;
5959
6060 struct WinEHHandlerType {
6161 int Adjectives;
62 /// The CatchObj starts out life as an LLVM alloca, is turned into a frame
63 /// index, and after PEI, becomes a raw offset.
62 /// The CatchObj starts out life as an LLVM alloca and is eventually turned
63 /// frame index.
6464 union {
6565 const AllocaInst *Alloca;
6666 int FrameIndex;
102102 void addIPToStateRange(const BasicBlock *PadBB, MCSymbol *InvokeBegin,
103103 MCSymbol *InvokeEnd);
104104
105 /// localescape index of the 32-bit EH registration node. Set by
106 /// WinEHStatePass and used indirectly by SEH filter functions of the parent.
107 int EHRegNodeEscapeIndex = INT_MAX;
108 const AllocaInst *EHRegNode = nullptr;
109105 int EHRegNodeFrameIndex = INT_MAX;
110106 int EHRegNodeEndOffset = INT_MAX;
111107
2020 // SEH intrinsics for Windows
2121 let TargetPrefix = "x86" in {
2222 def int_x86_seh_lsda : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>;
23
24 // Marks the EH registration node created in LLVM IR prior to code generation.
25 def int_x86_seh_ehregnode : Intrinsic<[], [llvm_ptr_ty], []>;
2326
2427 // Restores the frame, base, and stack pointers as necessary after recovering
2528 // from an exception. Any block resuming control flow in the parent function
298298 Asm->OutContext);
299299 }
300300
301 int WinException::getFrameIndexOffset(int FrameIndex, WinEHFuncInfo &FuncInfo) {
301 int WinException::getFrameIndexOffset(int FrameIndex,
302 const WinEHFuncInfo &FuncInfo) {
302303 const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
303304 unsigned UnusedReg;
304305 if (Asm->MAI->usesWindowsCFI())
339340 /// reported is the first change to something other than NullState, and a
340341 /// change back to NullState is always reported at the end of iteration).
341342 class InvokeStateChangeIterator {
342 InvokeStateChangeIterator(WinEHFuncInfo &EHInfo,
343 InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,
343344 MachineFunction::const_iterator MFI,
344345 MachineFunction::const_iterator MFE,
345346 MachineBasicBlock::const_iterator MBBI)
352353
353354 public:
354355 static iterator_range
355 range(WinEHFuncInfo &EHInfo, const MachineFunction &MF) {
356 range(const WinEHFuncInfo &EHInfo, const MachineFunction &MF) {
356357 // Reject empty MFs to simplify bookkeeping by ensuring that we can get the
357358 // end of the last block.
358359 assert(!MF.empty());
365366 InvokeStateChangeIterator(EHInfo, FuncEnd, FuncEnd, BlockEnd));
366367 }
367368 static iterator_range
368 range(WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin,
369 range(const WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin,
369370 MachineFunction::const_iterator End) {
370371 // Reject empty ranges to simplify bookkeeping by ensuring that we can get
371372 // the end of the last block.
401402 private:
402403 InvokeStateChangeIterator &scan();
403404
404 WinEHFuncInfo &EHInfo;
405 const WinEHFuncInfo &EHInfo;
405406 const MCSymbol *CurrentEndLabel = nullptr;
406407 MachineFunction::const_iterator MFI;
407408 MachineFunction::const_iterator MFE;
520521 auto &OS = *Asm->OutStreamer;
521522 MCContext &Ctx = Asm->OutContext;
522523
523 WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(MF->getFunction());
524 const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
524525 // Use the assembler to compute the number of table entries through label
525526 // difference and division.
526527 MCSymbol *TableBegin =
563564 OS.EmitLabel(TableEnd);
564565 }
565566
566 void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
567 void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
567568 const MCSymbol *BeginLabel,
568569 const MCSymbol *EndLabel, int State) {
569570 auto &OS = *Asm->OutStreamer;
571572
572573 assert(BeginLabel && EndLabel);
573574 while (State != -1) {
574 SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
575 const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
575576 const MCExpr *FilterOrFinally;
576577 const MCExpr *ExceptOrNull;
577578 auto *Handler = UME.Handler.get();
599600 void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
600601 const Function *F = MF->getFunction();
601602 auto &OS = *Asm->OutStreamer;
602 WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
603 const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
603604
604605 StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());
605606
687688 OS.EmitLabel(TryBlockMapXData);
688689 SmallVector HandlerMaps;
689690 for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
690 WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
691 const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
691692
692693 MCSymbol *HandlerMapXData = nullptr;
693694 if (!TBME.HandlerArray.empty())
720721 }
721722
722723 for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
723 WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
724 const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
724725 MCSymbol *HandlerMapXData = HandlerMaps[I];
725726 if (!HandlerMapXData)
726727 continue;
771772 }
772773
773774 void WinException::computeIP2StateTable(
774 const MachineFunction *MF, WinEHFuncInfo &FuncInfo,
775 const MachineFunction *MF, const WinEHFuncInfo &FuncInfo,
775776 SmallVectorImpl> &IPToStateTable) {
776777 // Indicate that all calls from the prologue to the first invoke unwind to
777778 // caller. We handle this as a special case since other ranges starting at end
802803 // registration in order to recover the parent frame pointer. Now that we know
803804 // we've code generated the parent, we can emit the label assignment that
804805 // those helpers use to get the offset of the registration node.
805 assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX &&
806 "no EH reg node localescape index");
806 MCContext &Ctx = Asm->OutContext;
807807 MCSymbol *ParentFrameOffset =
808 Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName);
809 MCSymbol *RegistrationOffsetSym = Asm->OutContext.getOrCreateFrameAllocSymbol(
810 FLinkageName, FuncInfo.EHRegNodeEscapeIndex);
811 const MCExpr *RegistrationOffsetSymRef =
812 MCSymbolRefExpr::create(RegistrationOffsetSym, Asm->OutContext);
813 Asm->OutStreamer->EmitAssignment(ParentFrameOffset, RegistrationOffsetSymRef);
808 Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
809 unsigned UnusedReg;
810 const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
811 int64_t Offset = TFI->getFrameIndexReference(
812 *Asm->MF, FuncInfo.EHRegNodeFrameIndex, UnusedReg);
813 const MCExpr *MCOffset = MCConstantExpr::create(Offset, Ctx);
814 Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset);
814815 }
815816
816817 /// Emit the language-specific data that _except_handler3 and 4 expect. This is
821822 const Function *F = MF->getFunction();
822823 StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName());
823824
824 WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
825 const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
825826 emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
826827
827828 // Emit the __ehtable label that we use for llvm.x86.seh.lsda.
856857 }
857858
858859 assert(!FuncInfo.SEHUnwindMap.empty());
859 for (SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
860 for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
860861 MCSymbol *ExceptOrFinally =
861862 UME.Handler.get()->getSymbol();
862863 // -1 is usually the base state for "unwind to caller", but for
868869 }
869870 }
870871
871 static int getRank(WinEHFuncInfo &FuncInfo, int State) {
872 static int getRank(const WinEHFuncInfo &FuncInfo, int State) {
872873 int Rank = 0;
873874 while (State != -1) {
874875 ++Rank;
877878 return Rank;
878879 }
879880
880 static int getAncestor(WinEHFuncInfo &FuncInfo, int Left, int Right) {
881 static int getAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right) {
881882 int LeftRank = getRank(FuncInfo, Left);
882883 int RightRank = getRank(FuncInfo, Right);
883884
904905 // states, handlers, and funclets all have 1:1 mappings between them, and a
905906 // handler/funclet's "state" is its index in the ClrEHUnwindMap.
906907 MCStreamer &OS = *Asm->OutStreamer;
907 const Function *F = MF->getFunction();
908 WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
908 const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
909909 MCSymbol *FuncBeginSym = Asm->getFunctionBegin();
910910 MCSymbol *FuncEndSym = Asm->getFunctionEnd();
911911
10841084 getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);
10851085 const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);
10861086
1087 ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
1087 const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
10881088 MachineBasicBlock *HandlerBlock = Entry.Handler.get();
10891089 MCSymbol *BeginSym = getMCSymbolForMBB(Asm, HandlerBlock);
10901090 const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
4141
4242 void emitCSpecificHandlerTable(const MachineFunction *MF);
4343
44 void emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
44 void emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
4545 const MCSymbol *BeginLabel,
4646 const MCSymbol *EndLabel, int State);
4747
5757 void emitCLRExceptionTable(const MachineFunction *MF);
5858
5959 void computeIP2StateTable(
60 const MachineFunction *MF, WinEHFuncInfo &FuncInfo,
60 const MachineFunction *MF, const WinEHFuncInfo &FuncInfo,
6161 SmallVectorImpl> &IPToStateTable);
6262
6363 /// Emits the label used with llvm.x86.seh.recoverfp, which is used by
7676 /// given index. For targets using CFI (Win64, etc), this is relative to the
7777 /// established SP at the end of the prologue. For targets without CFI (Win32
7878 /// only), it is relative to the frame pointer.
79 int getFrameIndexOffset(int FrameIndex, WinEHFuncInfo &FuncInfo);
79 int getFrameIndexOffset(int FrameIndex, const WinEHFuncInfo &FuncInfo);
8080
8181 public:
8282 //===--------------------------------------------------------------------===//
1616 #include "llvm/ADT/STLExtras.h"
1717 #include "llvm/ADT/SmallString.h"
1818 #include "llvm/Analysis/ConstantFolding.h"
19 #include "llvm/Analysis/LibCallSemantics.h"
1920 #include "llvm/CodeGen/MachineConstantPool.h"
2021 #include "llvm/CodeGen/MachineFrameInfo.h"
2122 #include "llvm/CodeGen/MachineFunctionInitializer.h"
2627 #include "llvm/CodeGen/MachineRegisterInfo.h"
2728 #include "llvm/CodeGen/Passes.h"
2829 #include "llvm/CodeGen/PseudoSourceValue.h"
30 #include "llvm/CodeGen/WinEHFuncInfo.h"
2931 #include "llvm/IR/DataLayout.h"
3032 #include "llvm/IR/DebugInfo.h"
3133 #include "llvm/IR/Function.h"
8789 FunctionNumber = FunctionNum;
8890 JumpTableInfo = nullptr;
8991
92 if (isFuncletEHPersonality(classifyEHPersonality(
93 F->hasPersonalityFn() ? F->getPersonalityFn() : nullptr))) {
94 WinEHInfo = new (Allocator) WinEHFuncInfo();
95 }
96
9097 assert(TM.isCompatibleDataLayout(getDataLayout()) &&
9198 "Can't create a MachineFunction using a Module with a "
9299 "Target-incompatible DataLayout attached\n");
123130 if (JumpTableInfo) {
124131 JumpTableInfo->~MachineJumpTableInfo();
125132 Allocator.Deallocate(JumpTableInfo);
133 }
134
135 if (WinEHInfo) {
136 WinEHInfo->~WinEHFuncInfo();
137 Allocator.Deallocate(WinEHInfo);
126138 }
127139 }
128140
88
99 #include "llvm/CodeGen/MachineModuleInfo.h"
1010 #include "llvm/ADT/PointerUnion.h"
11 #include "llvm/ADT/TinyPtrVector.h"
1112 #include "llvm/Analysis/LibCallSemantics.h"
1213 #include "llvm/Analysis/ValueTracking.h"
1314 #include "llvm/CodeGen/MachineFunction.h"
1415 #include "llvm/CodeGen/MachineFunctionPass.h"
1516 #include "llvm/CodeGen/Passes.h"
16 #include "llvm/CodeGen/WinEHFuncInfo.h"
1717 #include "llvm/IR/Constants.h"
1818 #include "llvm/IR/DerivedTypes.h"
1919 #include "llvm/IR/GlobalVariable.h"
320320 Personalities.push_back(Personality);
321321 }
322322
323 void MachineModuleInfo::addWinEHState(MachineBasicBlock *LandingPad,
324 int State) {
325 LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
326 LP.WinEHState = State;
327 }
328
329323 /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
330324 ///
331325 void MachineModuleInfo::
465459 FilterIds.push_back(0); // terminator
466460 return FilterID;
467461 }
468
469 WinEHFuncInfo &MachineModuleInfo::getWinEHFuncInfo(const Function *F) {
470 auto &Ptr = FuncInfoMap[F];
471 if (!Ptr)
472 Ptr.reset(new WinEHFuncInfo);
473 return *Ptr;
474 }
286286 return;
287287
288288 // Calculate state numbers if we haven't already.
289 WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
289 WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo();
290290 if (Personality == EHPersonality::MSVC_CXX)
291291 calculateWinCXXEHStateNumbers(&fn, EHInfo);
292292 else if (isAsynchronousEHPersonality(Personality))
319319 for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) {
320320 const BasicBlock *BB = CME.Handler.get();
321321 CME.Handler = MBBMap[BB];
322 }
323
324 // If there's an explicit EH registration node on the stack, record its
325 // frame index.
326 if (EHInfo.EHRegNode && EHInfo.EHRegNode->getParent()->getParent() == Fn) {
327 assert(StaticAllocaMap.count(EHInfo.EHRegNode));
328 EHInfo.EHRegNodeFrameIndex = StaticAllocaMap[EHInfo.EHRegNode];
329 }
330
331 // Copy the state numbers to LandingPadInfo for the current function, which
332 // could be a handler or the parent. This should happen for 32-bit SEH and
333 // C++ EH.
334 if (Personality == EHPersonality::MSVC_CXX ||
335 Personality == EHPersonality::MSVC_X86SEH) {
336 for (const LandingPadInst *LP : LPads) {
337 MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
338 MMI.addWinEHState(LPadMBB, EHInfo.EHPadStateMap[LP]);
339 }
340322 }
341323 }
342324
12201220 // Figure out the funclet membership for the catchret's successor.
12211221 // This will be used by the FuncletLayout pass to determine how to order the
12221222 // BB's.
1223 MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
1224 WinEHFuncInfo &EHInfo =
1225 MMI.getWinEHFuncInfo(DAG.getMachineFunction().getFunction());
1226 const BasicBlock *SuccessorColor = EHInfo.CatchRetSuccessorColorMap[&I];
1223 WinEHFuncInfo *EHInfo = DAG.getMachineFunction().getWinEHFuncInfo();
1224 const BasicBlock *SuccessorColor = EHInfo->CatchRetSuccessorColorMap[&I];
12271225 assert(SuccessorColor && "No parent funclet for catchret!");
12281226 MachineBasicBlock *SuccessorColorMBB = FuncInfo.MBBMap[SuccessorColor];
12291227 assert(SuccessorColorMBB && "No MBB for SuccessorColor!");
53405338
53415339 // Inform MachineModuleInfo of range.
53425340 if (MMI.hasEHFunclets()) {
5343 WinEHFuncInfo &EHInfo =
5344 MMI.getWinEHFuncInfo(DAG.getMachineFunction().getFunction());
5345 EHInfo.addIPToStateRange(EHPadBB, BeginLabel, EndLabel);
5341 WinEHFuncInfo *EHInfo = DAG.getMachineFunction().getWinEHFuncInfo();
5342 EHInfo->addIPToStateRange(EHPadBB, BeginLabel, EndLabel);
53465343 } else {
53475344 MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
53485345 }
12511251 assert(classifyEHPersonality(Fn->getPersonalityFn()) ==
12521252 EHPersonality::MSVC_CXX);
12531253 unsigned FrameReg;
1254 int FI = MMI.getWinEHFuncInfo(Fn).EHRegNodeFrameIndex;
1254 int FI = MF.getWinEHFuncInfo()->EHRegNodeFrameIndex;
12551255 int64_t EHRegOffset = getFrameIndexReference(MF, FI, FrameReg);
12561256 // ESP is the first field, so no extra displacement is needed.
12571257 addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32mr)), FrameReg,
12911291 // and the GC can recover it.
12921292 unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
12931293 auto PSPInfo = MachinePointerInfo::getFixedStack(
1294 MF, MF.getMMI().getWinEHFuncInfo(Fn).PSPSymFrameIdx);
1294 MF, MF.getWinEHFuncInfo()->PSPSymFrameIdx);
12951295 addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64mr)), StackPtr, false,
12961296 PSPSlotOffset)
12971297 .addReg(StackPtr)
14001400 // frame with only a single offset reported for the entire method.
14011401 unsigned
14021402 X86FrameLowering::getPSPSlotOffsetFromSP(const MachineFunction &MF) const {
1403 MachineModuleInfo &MMI = MF.getMMI();
1404 WinEHFuncInfo &Info = MMI.getWinEHFuncInfo(MF.getFunction());
1403 const WinEHFuncInfo &Info = *MF.getWinEHFuncInfo();
14051404 // getFrameIndexReferenceFromSP has an out ref parameter for the stack
14061405 // pointer register; pass a dummy that we ignore
14071406 unsigned SPReg;
25912590 MachineFunction &MF = *MBB.getParent();
25922591 unsigned FramePtr = TRI->getFrameRegister(MF);
25932592 unsigned BasePtr = TRI->getBaseRegister();
2594 MachineModuleInfo &MMI = MF.getMMI();
2595 const Function *Fn = MF.getFunction();
2596 WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(Fn);
2593 WinEHFuncInfo &FuncInfo = *MF.getWinEHFuncInfo();
25972594 X86MachineFunctionInfo *X86FI = MF.getInfo();
25982595 MachineFrameInfo *MFI = MF.getFrameInfo();
25992596
26782675 int64_t UnwindHelpOffset = MinFixedObjOffset - SlotSize;
26792676 int UnwindHelpFI =
26802677 MFI->CreateFixedObject(SlotSize, UnwindHelpOffset, /*Immutable=*/false);
2681 MF.getMMI().getWinEHFuncInfo(Fn).UnwindHelpFrameIdx = UnwindHelpFI;
2678 MF.getWinEHFuncInfo()->UnwindHelpFrameIdx = UnwindHelpFI;
26822679
26832680 // Store -2 into UnwindHelp on function entry. We have to scan forwards past
26842681 // other frame setup instructions.
27202720 MFI->CreateFixedObject(1, StackSize, true));
27212721 }
27222722
2723 MachineModuleInfo &MMI = MF.getMMI();
2724
27252723 // Figure out if XMM registers are in use.
27262724 assert(!(Subtarget->useSoftFloat() &&
27272725 Fn->hasFnAttribute(Attribute::NoImplicitFloat)) &&
28772875
28782876 FuncInfo->setArgumentStackSize(StackSize);
28792877
2880 if (MMI.hasWinEHFuncInfo(Fn)) {
2878 if (WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo()) {
28812879 EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
28822880 if (Personality == EHPersonality::CoreCLR) {
28832881 assert(Is64Bit);
28902888 // how far this slot is from the bottom (since they allocate just enough
28912889 // space to accomodate holding this slot at the correct offset).
28922890 int PSPSymFI = MFI->CreateStackObject(8, 8, /*isSS=*/false);
2893 MMI.getWinEHFuncInfo(MF.getFunction()).PSPSymFrameIdx = PSPSymFI;
2891 EHInfo->PSPSymFrameIdx = PSPSymFI;
28942892 }
28952893 }
28962894
1693916937 return Chain;
1694016938 }
1694116939
16940 static SDValue MarkEHRegistrationNode(SDValue Op, SelectionDAG &DAG) {
16941 MachineFunction &MF = DAG.getMachineFunction();
16942 SDValue Chain = Op.getOperand(0);
16943 SDValue RegNode = Op.getOperand(2);
16944 WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo();
16945 if (!EHInfo)
16946 report_fatal_error("EH registrations only live in functions using WinEH");
16947
16948 // Cast the operand to an alloca, and remember the frame index.
16949 auto *FINode = dyn_cast(RegNode);
16950 if (!FINode)
16951 report_fatal_error("llvm.x86.seh.ehregnode expects a static alloca");
16952 EHInfo->EHRegNodeFrameIndex = FINode->getIndex();
16953
16954 // Return the chain operand without making any DAG nodes.
16955 return Chain;
16956 }
16957
1694216958 /// \brief Lower intrinsics for TRUNCATE_TO_MEM case
1694316959 /// return truncate Store/MaskedStore Node
1694416960 static SDValue LowerINTRINSIC_TRUNCATE_TO_MEM(const SDValue & Op,
1698417000 if (!IntrData) {
1698517001 if (IntNo == llvm::Intrinsic::x86_seh_restoreframe)
1698617002 return LowerSEHRESTOREFRAME(Op, Subtarget, DAG);
17003 else if (IntNo == llvm::Intrinsic::x86_seh_ehregnode)
17004 return MarkEHRegistrationNode(Op, DAG);
1698717005 return SDValue();
1698817006 }
1698917007
6565
6666 void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
6767 void unlinkExceptionRegistration(IRBuilder<> &Builder);
68 void addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo);
69 void addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo);
70 void addStateStoresToFunclet(Value *ParentRegNode, WinEHFuncInfo &FuncInfo,
71 Function &F, int BaseState);
68 void addStateStores(Function &F, WinEHFuncInfo &FuncInfo);
7269 void insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State);
7370
7471 Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
7572
7673 Function *generateLSDAInEAXThunk(Function *ParentFunc);
77
78 int escapeRegNode(Function &F);
7974
8075 // Module-level type getters.
8176 Type *getEHLinkRegistrationType();
177172
178173 emitExceptionRegistrationRecord(&F);
179174
180 auto *MMI = getAnalysisIfAvailable();
181 // If MMI is null, create our own WinEHFuncInfo. This only happens in opt
182 // tests.
183 std::unique_ptr FuncInfoPtr;
184 if (!MMI)
185 FuncInfoPtr.reset(new WinEHFuncInfo());
186 WinEHFuncInfo &FuncInfo =
187 *(MMI ? &MMI->getWinEHFuncInfo(&F) : FuncInfoPtr.get());
188
189 FuncInfo.EHRegNode = RegNode;
190
191 switch (Personality) {
192 default: llvm_unreachable("unexpected personality function");
193 case EHPersonality::MSVC_CXX:
194 addCXXStateStores(F, FuncInfo);
195 break;
196 case EHPersonality::MSVC_X86SEH:
197 addSEHStateStores(F, FuncInfo);
198 break;
199 }
175 // The state numbers calculated here in IR must agree with what we calculate
176 // later on for the MachineFunction. In particular, if an IR pass deletes an
177 // unreachable EH pad after this point before machine CFG construction, we
178 // will be in trouble. If this assumption is ever broken, we should turn the
179 // numbers into an immutable analysis pass.
180 WinEHFuncInfo FuncInfo;
181 addStateStores(F, FuncInfo);
200182
201183 // Reset per-function state.
202184 PersonalityFn = nullptr;
417399 Builder.CreateStore(Next, FSZero);
418400 }
419401
420 void WinEHStatePass::addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
421 // Set up RegNodeEscapeIndex
422 int RegNodeEscapeIndex = escapeRegNode(F);
423 FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
424
425 calculateWinCXXEHStateNumbers(&F, FuncInfo);
426 addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
427 }
428
429 /// Assign every distinct landingpad a unique state number for SEH. Unlike C++
430 /// EH, we can use this very simple algorithm while C++ EH cannot because catch
431 /// handlers aren't outlined and the runtime doesn't have to figure out which
432 /// catch handler frame to unwind to.
433 void WinEHStatePass::addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
434 // Remember and return the index that we used. We save it in WinEHFuncInfo so
435 // that we can lower llvm.x86.seh.recoverfp later in filter functions without
436 // too much trouble.
437 int RegNodeEscapeIndex = escapeRegNode(F);
438 FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
439
440 calculateSEHStateNumbers(&F, FuncInfo);
441 addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
442 }
443
444 /// Escape RegNode so that we can access it from child handlers. Find the call
445 /// to localescape, if any, in the entry block and append RegNode to the list
446 /// of arguments.
447 int WinEHStatePass::escapeRegNode(Function &F) {
448 // Find the call to localescape and extract its arguments.
449 IntrinsicInst *EscapeCall = nullptr;
450 for (Instruction &I : F.getEntryBlock()) {
451 IntrinsicInst *II = dyn_cast(&I);
452 if (II && II->getIntrinsicID() == Intrinsic::localescape) {
453 EscapeCall = II;
454 break;
455 }
456 }
457 SmallVector Args;
458 if (EscapeCall) {
459 auto Ops = EscapeCall->arg_operands();
460 Args.append(Ops.begin(), Ops.end());
461 }
462 Args.push_back(RegNode);
463
464 // Replace the call (if it exists) with new one. Otherwise, insert at the end
465 // of the entry block.
466 Instruction *InsertPt = EscapeCall;
467 if (!EscapeCall)
468 InsertPt = F.getEntryBlock().getTerminator();
469 IRBuilder<> Builder(InsertPt);
470 Builder.CreateCall(FrameEscape, Args);
471 if (EscapeCall)
472 EscapeCall->eraseFromParent();
473 return Args.size() - 1;
474 }
475
476 void WinEHStatePass::addStateStoresToFunclet(Value *ParentRegNode,
477 WinEHFuncInfo &FuncInfo,
478 Function &F, int BaseState) {
402 void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
403 // Mark the registration node. The backend needs to know which alloca it is so
404 // that it can recover the original frame pointer.
405 IRBuilder<> Builder(RegNode->getParent(), std::next(RegNode->getIterator()));
406 Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
407 Builder.CreateCall(
408 Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
409 {RegNodeI8});
410
411 // Calculate state numbers.
412 if (isAsynchronousEHPersonality(Personality))
413 calculateSEHStateNumbers(&F, FuncInfo);
414 else
415 calculateWinCXXEHStateNumbers(&F, FuncInfo);
416
479417 // Iterate all the instructions and emit state number stores.
480418 for (BasicBlock &BB : F) {
481419 for (Instruction &I : BB) {
484422 // an unwind. Ensure they are in the -1 state.
485423 if (CI->doesNotThrow())
486424 continue;
487 insertStateNumberStore(ParentRegNode, CI, BaseState);
425 insertStateNumberStore(RegNode, CI, -1);
488426 } else if (auto *II = dyn_cast(&I)) {
489427 // Look up the state number of the landingpad this unwinds to.
490428 Instruction *PadInst = II->getUnwindDest()->getFirstNonPHI();
491429 // FIXME: Why does this assertion fail?
492430 //assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
493431 int State = FuncInfo.EHPadStateMap[PadInst];
494 insertStateNumberStore(ParentRegNode, II, State);
432 insertStateNumberStore(RegNode, II, State);
495433 }
496434 }
497435 }
6363 ; CHECK: pushl %esi
6464
6565 ; CHECK: Lmain$frame_escape_0 = [[code_offs:[-0-9]+]]
66 ; CHECK: Lmain$frame_escape_1 = [[reg_offs:[-0-9]+]]
67 ; CHECK: movl %esp, [[reg_offs]](%ebp)
66 ; CHECK: movl %esp, [[reg_offs:[-0-9]+]](%ebp)
6867 ; CHECK: movl $L__ehtable$main,
6968 ; EH state 0
7069 ; CHECK: movl $0, -16(%ebp)
8382 ; CHECK: calll _printf
8483
8584 ; CHECK: .section .xdata,"dr"
86 ; CHECK: Lmain$parent_frame_offset = Lmain$frame_escape_1
85 ; CHECK: Lmain$parent_frame_offset = [[reg_offs]]
8786 ; CHECK: .align 4
8887 ; CHECK: L__ehtable$main
8988 ; CHECK-NEXT: .long -1
5656
5757 ; CHECK-LABEL: _main:
5858 ; CHECK: Lmain$frame_escape_0 = [[code_offs:[-0-9]+]]
59 ; CHECK: Lmain$frame_escape_1 = [[reg_offs:[-0-9]+]]
60 ; CHECK: movl %esp, [[reg_offs]](%esi)
59 ; CHECK: movl %esp, [[reg_offs:[-0-9]+]](%esi)
6160 ; CHECK: movl $L__ehtable$main,
6261 ; EH state 0
6362 ; CHECK: movl $0, 40(%esi)
7675 ; CHECK: calll _printf
7776
7877 ; CHECK: .section .xdata,"dr"
79 ; CHECK: Lmain$parent_frame_offset = Lmain$frame_escape_1
78 ; CHECK: Lmain$parent_frame_offset = [[reg_offs]]
8079 ; CHECK: L__ehtable$main
8180 ; CHECK-NEXT: .long -1
8281 ; CHECK-NEXT: .long _filt$main