[WinEH] Move WinEHFuncInfo from MachineModuleInfo to MachineFunction
authorReid Kleckner <rnk@google.com>
Tue, 17 Nov 2015 21:10:25 +0000 (21:10 +0000)
committerReid Kleckner <rnk@google.com>
Tue, 17 Nov 2015 21:10:25 +0000 (21:10 +0000)
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

15 files changed:
include/llvm/CodeGen/MachineFunction.h
include/llvm/CodeGen/MachineModuleInfo.h
include/llvm/CodeGen/WinEHFuncInfo.h
include/llvm/IR/IntrinsicsX86.td
lib/CodeGen/AsmPrinter/WinException.cpp
lib/CodeGen/AsmPrinter/WinException.h
lib/CodeGen/MachineFunction.cpp
lib/CodeGen/MachineModuleInfo.cpp
lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/Target/X86/X86FrameLowering.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86WinEHState.cpp
test/CodeGen/X86/seh-catch-all-win32.ll
test/CodeGen/X86/seh-stack-realign.ll

index d163c971d4bb85897a06e28d20fa447c5c1fde89..82c30d39afd68c34fea2006a077a6f2081e9f143 100644 (file)
@@ -43,6 +43,7 @@ class TargetMachine;
 class TargetSubtargetInfo;
 class TargetRegisterClass;
 struct MachinePointerInfo;
 class TargetSubtargetInfo;
 class TargetRegisterClass;
 struct MachinePointerInfo;
+struct WinEHFuncInfo;
 
 template <>
 struct ilist_traits<MachineBasicBlock>
 
 template <>
 struct ilist_traits<MachineBasicBlock>
@@ -107,6 +108,10 @@ class MachineFunction {
   // Keep track of jump tables for switch instructions
   MachineJumpTableInfo *JumpTableInfo;
 
   // Keep track of jump tables for switch instructions
   MachineJumpTableInfo *JumpTableInfo;
 
+  // Keeps track of Windows exception handling related data. This will be null
+  // for functions that aren't using a funclet-based EH personality.
+  WinEHFuncInfo *WinEHInfo = nullptr;
+
   // Function-level unique numbering for MachineBasicBlocks.  When a
   // MachineBasicBlock is inserted into a MachineFunction is it automatically
   // numbered and this vector keeps track of the mapping from ID's to MBB's.
   // Function-level unique numbering for MachineBasicBlocks.  When a
   // MachineBasicBlock is inserted into a MachineFunction is it automatically
   // numbered and this vector keeps track of the mapping from ID's to MBB's.
@@ -221,6 +226,12 @@ public:
   MachineConstantPool *getConstantPool() { return ConstantPool; }
   const MachineConstantPool *getConstantPool() const { return ConstantPool; }
 
   MachineConstantPool *getConstantPool() { return ConstantPool; }
   const MachineConstantPool *getConstantPool() const { return ConstantPool; }
 
+  /// getWinEHFuncInfo - Return information about how the current function uses
+  /// Windows exception handling. Returns null for functions that don't use
+  /// funclets for exception handling.
+  const WinEHFuncInfo *getWinEHFuncInfo() const { return WinEHInfo; }
+  WinEHFuncInfo *getWinEHFuncInfo() { return WinEHInfo; }
+
   /// getAlignment - Return the alignment (log2, not bytes) of the function.
   ///
   unsigned getAlignment() const { return Alignment; }
   /// getAlignment - Return the alignment (log2, not bytes) of the function.
   ///
   unsigned getAlignment() const { return Alignment; }
index 4df580f0dbae3da4032d9a854a6ad7ac2b084796..fd42b46476c52e6a081b8e4578f4c096157c60e5 100644 (file)
@@ -59,7 +59,6 @@ class MachineFunction;
 class Module;
 class PointerType;
 class StructType;
 class Module;
 class PointerType;
 class StructType;
-struct WinEHFuncInfo;
 
 struct SEHHandler {
   // Filter or finally function. Null indicates a catch-all.
 
 struct SEHHandler {
   // Filter or finally function. Null indicates a catch-all.
@@ -80,11 +79,9 @@ struct LandingPadInfo {
   SmallVector<SEHHandler, 1> SEHHandlers;  // SEH handlers active at this lpad.
   MCSymbol *LandingPadLabel;               // Label at beginning of landing pad.
   std::vector<int> TypeIds;               // List of type ids (filters negative).
   SmallVector<SEHHandler, 1> SEHHandlers;  // SEH handlers active at this lpad.
   MCSymbol *LandingPadLabel;               // Label at beginning of landing pad.
   std::vector<int> TypeIds;               // List of type ids (filters negative).
-  int WinEHState;                         // WinEH specific state number.
 
   explicit LandingPadInfo(MachineBasicBlock *MBB)
 
   explicit LandingPadInfo(MachineBasicBlock *MBB)
-      : LandingPadBlock(MBB), LandingPadLabel(nullptr),
-        WinEHState(-1) {}
+      : LandingPadBlock(MBB), LandingPadLabel(nullptr) {}
 };
 
 //===----------------------------------------------------------------------===//
 };
 
 //===----------------------------------------------------------------------===//
@@ -182,8 +179,6 @@ class MachineModuleInfo : public ImmutablePass {
 
   EHPersonality PersonalityTypeCache;
 
 
   EHPersonality PersonalityTypeCache;
 
-  DenseMap<const Function *, std::unique_ptr<WinEHFuncInfo>> FuncInfoMap;
-
 public:
   static char ID; // Pass identification, replacement for typeid
 
 public:
   static char ID; // Pass identification, replacement for typeid
 
@@ -220,11 +215,6 @@ public:
   void setModule(const Module *M) { TheModule = M; }
   const Module *getModule() const { return TheModule; }
 
   void setModule(const Module *M) { TheModule = M; }
   const Module *getModule() const { return TheModule; }
 
-  WinEHFuncInfo &getWinEHFuncInfo(const Function *F);
-  bool hasWinEHFuncInfo(const Function *F) const {
-    return FuncInfoMap.count(F) > 0;
-  }
-
   /// getInfo - Keep track of various per-function pieces of information for
   /// backends that would like to do so.
   ///
   /// getInfo - Keep track of various per-function pieces of information for
   /// backends that would like to do so.
   ///
@@ -327,8 +317,6 @@ public:
   /// information.
   void addPersonality(const Function *Personality);
 
   /// information.
   void addPersonality(const Function *Personality);
 
-  void addWinEHState(MachineBasicBlock *LandingPad, int State);
-
   /// getPersonalities - Return array of personality functions ever seen.
   const std::vector<const Function *>& getPersonalities() const {
     return Personalities;
   /// getPersonalities - Return array of personality functions ever seen.
   const std::vector<const Function *>& getPersonalities() const {
     return Personalities;
index 782119e84e24876743c2e6fcd00df091445e4490..5def70692ba5481401ec5c63f4d2e4bddc2138e9 100644 (file)
@@ -60,8 +60,8 @@ struct SEHUnwindMapEntry {
 
 struct WinEHHandlerType {
   int Adjectives;
 
 struct WinEHHandlerType {
   int Adjectives;
-  /// The CatchObj starts out life as an LLVM alloca, is turned into a frame
-  /// index, and after PEI, becomes a raw offset.
+  /// The CatchObj starts out life as an LLVM alloca and is eventually turned
+  /// frame index.
   union {
     const AllocaInst *Alloca;
     int FrameIndex;
   union {
     const AllocaInst *Alloca;
     int FrameIndex;
@@ -103,10 +103,6 @@ struct WinEHFuncInfo {
   void addIPToStateRange(const BasicBlock *PadBB, MCSymbol *InvokeBegin,
                          MCSymbol *InvokeEnd);
 
   void addIPToStateRange(const BasicBlock *PadBB, MCSymbol *InvokeBegin,
                          MCSymbol *InvokeEnd);
 
-  /// localescape index of the 32-bit EH registration node. Set by
-  /// WinEHStatePass and used indirectly by SEH filter functions of the parent.
-  int EHRegNodeEscapeIndex = INT_MAX;
-  const AllocaInst *EHRegNode = nullptr;
   int EHRegNodeFrameIndex = INT_MAX;
   int EHRegNodeEndOffset = INT_MAX;
 
   int EHRegNodeFrameIndex = INT_MAX;
   int EHRegNodeEndOffset = INT_MAX;
 
index 3d6fa1c066244642e33068382ddf1b77b53a4bd8..2b5577cdad99f08058c652cff56e469df89f442c 100644 (file)
@@ -22,6 +22,9 @@ let TargetPrefix = "x86" in {  // All intrinsics start with "llvm.x86.".
 let TargetPrefix = "x86" in {
   def int_x86_seh_lsda : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>;
 
 let TargetPrefix = "x86" in {
   def int_x86_seh_lsda : Intrinsic<[llvm_ptr_ty], [llvm_ptr_ty], [IntrNoMem]>;
 
+  // Marks the EH registration node created in LLVM IR prior to code generation.
+  def int_x86_seh_ehregnode : Intrinsic<[], [llvm_ptr_ty], []>;
+
   // Restores the frame, base, and stack pointers as necessary after recovering
   // from an exception. Any block resuming control flow in the parent function
   // should call this before accessing any stack memory.
   // Restores the frame, base, and stack pointers as necessary after recovering
   // from an exception. Any block resuming control flow in the parent function
   // should call this before accessing any stack memory.
index 33eb3906fceecc6395693cd86824ebdbb8419757..cd1f3f51bc4c3bc3eab9004a172da038533a86f7 100644 (file)
@@ -299,7 +299,8 @@ const MCExpr *WinException::getOffsetPlusOne(const MCSymbol *OffsetOf,
                                  Asm->OutContext);
 }
 
                                  Asm->OutContext);
 }
 
-int WinException::getFrameIndexOffset(int FrameIndex, WinEHFuncInfo &FuncInfo) {
+int WinException::getFrameIndexOffset(int FrameIndex,
+                                      const WinEHFuncInfo &FuncInfo) {
   const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
   unsigned UnusedReg;
   if (Asm->MAI->usesWindowsCFI())
   const TargetFrameLowering &TFI = *Asm->MF->getSubtarget().getFrameLowering();
   unsigned UnusedReg;
   if (Asm->MAI->usesWindowsCFI())
@@ -340,7 +341,7 @@ struct InvokeStateChange {
 /// reported is the first change to something other than NullState, and a
 /// change back to NullState is always reported at the end of iteration).
 class InvokeStateChangeIterator {
 /// reported is the first change to something other than NullState, and a
 /// change back to NullState is always reported at the end of iteration).
 class InvokeStateChangeIterator {
-  InvokeStateChangeIterator(WinEHFuncInfo &EHInfo,
+  InvokeStateChangeIterator(const WinEHFuncInfo &EHInfo,
                             MachineFunction::const_iterator MFI,
                             MachineFunction::const_iterator MFE,
                             MachineBasicBlock::const_iterator MBBI)
                             MachineFunction::const_iterator MFI,
                             MachineFunction::const_iterator MFE,
                             MachineBasicBlock::const_iterator MBBI)
@@ -353,7 +354,7 @@ class InvokeStateChangeIterator {
 
 public:
   static iterator_range<InvokeStateChangeIterator>
 
 public:
   static iterator_range<InvokeStateChangeIterator>
-  range(WinEHFuncInfo &EHInfo, const MachineFunction &MF) {
+  range(const WinEHFuncInfo &EHInfo, const MachineFunction &MF) {
     // Reject empty MFs to simplify bookkeeping by ensuring that we can get the
     // end of the last block.
     assert(!MF.empty());
     // Reject empty MFs to simplify bookkeeping by ensuring that we can get the
     // end of the last block.
     assert(!MF.empty());
@@ -366,7 +367,7 @@ public:
         InvokeStateChangeIterator(EHInfo, FuncEnd, FuncEnd, BlockEnd));
   }
   static iterator_range<InvokeStateChangeIterator>
         InvokeStateChangeIterator(EHInfo, FuncEnd, FuncEnd, BlockEnd));
   }
   static iterator_range<InvokeStateChangeIterator>
-  range(WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin,
+  range(const WinEHFuncInfo &EHInfo, MachineFunction::const_iterator Begin,
         MachineFunction::const_iterator End) {
     // Reject empty ranges to simplify bookkeeping by ensuring that we can get
     // the end of the last block.
         MachineFunction::const_iterator End) {
     // Reject empty ranges to simplify bookkeeping by ensuring that we can get
     // the end of the last block.
@@ -402,7 +403,7 @@ public:
 private:
   InvokeStateChangeIterator &scan();
 
 private:
   InvokeStateChangeIterator &scan();
 
-  WinEHFuncInfo &EHInfo;
+  const WinEHFuncInfo &EHInfo;
   const MCSymbol *CurrentEndLabel = nullptr;
   MachineFunction::const_iterator MFI;
   MachineFunction::const_iterator MFE;
   const MCSymbol *CurrentEndLabel = nullptr;
   MachineFunction::const_iterator MFI;
   MachineFunction::const_iterator MFE;
@@ -521,7 +522,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
   auto &OS = *Asm->OutStreamer;
   MCContext &Ctx = Asm->OutContext;
 
   auto &OS = *Asm->OutStreamer;
   MCContext &Ctx = Asm->OutContext;
 
-  WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(MF->getFunction());
+  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
   // Use the assembler to compute the number of table entries through label
   // difference and division.
   MCSymbol *TableBegin =
   // Use the assembler to compute the number of table entries through label
   // difference and division.
   MCSymbol *TableBegin =
@@ -564,7 +565,7 @@ void WinException::emitCSpecificHandlerTable(const MachineFunction *MF) {
   OS.EmitLabel(TableEnd);
 }
 
   OS.EmitLabel(TableEnd);
 }
 
-void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
+void WinException::emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
                                           const MCSymbol *BeginLabel,
                                           const MCSymbol *EndLabel, int State) {
   auto &OS = *Asm->OutStreamer;
                                           const MCSymbol *BeginLabel,
                                           const MCSymbol *EndLabel, int State) {
   auto &OS = *Asm->OutStreamer;
@@ -572,7 +573,7 @@ void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
 
   assert(BeginLabel && EndLabel);
   while (State != -1) {
 
   assert(BeginLabel && EndLabel);
   while (State != -1) {
-    SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
+    const SEHUnwindMapEntry &UME = FuncInfo.SEHUnwindMap[State];
     const MCExpr *FilterOrFinally;
     const MCExpr *ExceptOrNull;
     auto *Handler = UME.Handler.get<MachineBasicBlock *>();
     const MCExpr *FilterOrFinally;
     const MCExpr *ExceptOrNull;
     auto *Handler = UME.Handler.get<MachineBasicBlock *>();
@@ -600,7 +601,7 @@ void WinException::emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
 void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
   const Function *F = MF->getFunction();
   auto &OS = *Asm->OutStreamer;
 void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
   const Function *F = MF->getFunction();
   auto &OS = *Asm->OutStreamer;
-  WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
+  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
 
   StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());
 
 
   StringRef FuncLinkageName = GlobalValue::getRealLinkageName(F->getName());
 
@@ -688,7 +689,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
     OS.EmitLabel(TryBlockMapXData);
     SmallVector<MCSymbol *, 1> HandlerMaps;
     for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
     OS.EmitLabel(TryBlockMapXData);
     SmallVector<MCSymbol *, 1> HandlerMaps;
     for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
-      WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
+      const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
 
       MCSymbol *HandlerMapXData = nullptr;
       if (!TBME.HandlerArray.empty())
 
       MCSymbol *HandlerMapXData = nullptr;
       if (!TBME.HandlerArray.empty())
@@ -721,7 +722,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
     }
 
     for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
     }
 
     for (size_t I = 0, E = FuncInfo.TryBlockMap.size(); I != E; ++I) {
-      WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
+      const WinEHTryBlockMapEntry &TBME = FuncInfo.TryBlockMap[I];
       MCSymbol *HandlerMapXData = HandlerMaps[I];
       if (!HandlerMapXData)
         continue;
       MCSymbol *HandlerMapXData = HandlerMaps[I];
       if (!HandlerMapXData)
         continue;
@@ -772,7 +773,7 @@ void WinException::emitCXXFrameHandler3Table(const MachineFunction *MF) {
 }
 
 void WinException::computeIP2StateTable(
 }
 
 void WinException::computeIP2StateTable(
-    const MachineFunction *MF, WinEHFuncInfo &FuncInfo,
+    const MachineFunction *MF, const WinEHFuncInfo &FuncInfo,
     SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {
   // Indicate that all calls from the prologue to the first invoke unwind to
   // caller. We handle this as a special case since other ranges starting at end
     SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable) {
   // Indicate that all calls from the prologue to the first invoke unwind to
   // caller. We handle this as a special case since other ranges starting at end
@@ -803,15 +804,15 @@ void WinException::emitEHRegistrationOffsetLabel(const WinEHFuncInfo &FuncInfo,
   // registration in order to recover the parent frame pointer. Now that we know
   // we've code generated the parent, we can emit the label assignment that
   // those helpers use to get the offset of the registration node.
   // registration in order to recover the parent frame pointer. Now that we know
   // we've code generated the parent, we can emit the label assignment that
   // those helpers use to get the offset of the registration node.
-  assert(FuncInfo.EHRegNodeEscapeIndex != INT_MAX &&
-         "no EH reg node localescape index");
+  MCContext &Ctx = Asm->OutContext;
   MCSymbol *ParentFrameOffset =
   MCSymbol *ParentFrameOffset =
-      Asm->OutContext.getOrCreateParentFrameOffsetSymbol(FLinkageName);
-  MCSymbol *RegistrationOffsetSym = Asm->OutContext.getOrCreateFrameAllocSymbol(
-      FLinkageName, FuncInfo.EHRegNodeEscapeIndex);
-  const MCExpr *RegistrationOffsetSymRef =
-      MCSymbolRefExpr::create(RegistrationOffsetSym, Asm->OutContext);
-  Asm->OutStreamer->EmitAssignment(ParentFrameOffset, RegistrationOffsetSymRef);
+      Ctx.getOrCreateParentFrameOffsetSymbol(FLinkageName);
+  unsigned UnusedReg;
+  const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
+  int64_t Offset = TFI->getFrameIndexReference(
+      *Asm->MF, FuncInfo.EHRegNodeFrameIndex, UnusedReg);
+  const MCExpr *MCOffset = MCConstantExpr::create(Offset, Ctx);
+  Asm->OutStreamer->EmitAssignment(ParentFrameOffset, MCOffset);
 }
 
 /// Emit the language-specific data that _except_handler3 and 4 expect. This is
 }
 
 /// Emit the language-specific data that _except_handler3 and 4 expect. This is
@@ -822,7 +823,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
   const Function *F = MF->getFunction();
   StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName());
 
   const Function *F = MF->getFunction();
   StringRef FLinkageName = GlobalValue::getRealLinkageName(F->getName());
 
-  WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
+  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
   emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
 
   // Emit the __ehtable label that we use for llvm.x86.seh.lsda.
   emitEHRegistrationOffsetLabel(FuncInfo, FLinkageName);
 
   // Emit the __ehtable label that we use for llvm.x86.seh.lsda.
@@ -857,7 +858,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
   }
 
   assert(!FuncInfo.SEHUnwindMap.empty());
   }
 
   assert(!FuncInfo.SEHUnwindMap.empty());
-  for (SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
+  for (const SEHUnwindMapEntry &UME : FuncInfo.SEHUnwindMap) {
     MCSymbol *ExceptOrFinally =
         UME.Handler.get<MachineBasicBlock *>()->getSymbol();
     // -1 is usually the base state for "unwind to caller", but for
     MCSymbol *ExceptOrFinally =
         UME.Handler.get<MachineBasicBlock *>()->getSymbol();
     // -1 is usually the base state for "unwind to caller", but for
@@ -869,7 +870,7 @@ void WinException::emitExceptHandlerTable(const MachineFunction *MF) {
   }
 }
 
   }
 }
 
-static int getRank(WinEHFuncInfo &FuncInfo, int State) {
+static int getRank(const WinEHFuncInfo &FuncInfo, int State) {
   int Rank = 0;
   while (State != -1) {
     ++Rank;
   int Rank = 0;
   while (State != -1) {
     ++Rank;
@@ -878,7 +879,7 @@ static int getRank(WinEHFuncInfo &FuncInfo, int State) {
   return Rank;
 }
 
   return Rank;
 }
 
-static int getAncestor(WinEHFuncInfo &FuncInfo, int Left, int Right) {
+static int getAncestor(const WinEHFuncInfo &FuncInfo, int Left, int Right) {
   int LeftRank = getRank(FuncInfo, Left);
   int RightRank = getRank(FuncInfo, Right);
 
   int LeftRank = getRank(FuncInfo, Left);
   int RightRank = getRank(FuncInfo, Right);
 
@@ -905,8 +906,7 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
   // states, handlers, and funclets all have 1:1 mappings between them, and a
   // handler/funclet's "state" is its index in the ClrEHUnwindMap.
   MCStreamer &OS = *Asm->OutStreamer;
   // states, handlers, and funclets all have 1:1 mappings between them, and a
   // handler/funclet's "state" is its index in the ClrEHUnwindMap.
   MCStreamer &OS = *Asm->OutStreamer;
-  const Function *F = MF->getFunction();
-  WinEHFuncInfo &FuncInfo = MMI->getWinEHFuncInfo(F);
+  const WinEHFuncInfo &FuncInfo = *MF->getWinEHFuncInfo();
   MCSymbol *FuncBeginSym = Asm->getFunctionBegin();
   MCSymbol *FuncEndSym = Asm->getFunctionEnd();
 
   MCSymbol *FuncBeginSym = Asm->getFunctionBegin();
   MCSymbol *FuncEndSym = Asm->getFunctionEnd();
 
@@ -1085,7 +1085,7 @@ void WinException::emitCLRExceptionTable(const MachineFunction *MF) {
         getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);
     const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);
 
         getOffsetPlusOne(Clause.StartLabel, FuncBeginSym);
     const MCExpr *ClauseEnd = getOffsetPlusOne(Clause.EndLabel, FuncBeginSym);
 
-    ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
+    const ClrEHUnwindMapEntry &Entry = FuncInfo.ClrEHUnwindMap[Clause.State];
     MachineBasicBlock *HandlerBlock = Entry.Handler.get<MachineBasicBlock *>();
     MCSymbol *BeginSym = getMCSymbolForMBB(Asm, HandlerBlock);
     const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
     MachineBasicBlock *HandlerBlock = Entry.Handler.get<MachineBasicBlock *>();
     MCSymbol *BeginSym = getMCSymbolForMBB(Asm, HandlerBlock);
     const MCExpr *HandlerBegin = getOffset(BeginSym, FuncBeginSym);
index 54c5f3a9a0e8f141abdc0142f8597c045200fd84..acb301016910a1fc172ed8ffc36246e9e518ad33 100644 (file)
@@ -42,7 +42,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
 
   void emitCSpecificHandlerTable(const MachineFunction *MF);
 
 
   void emitCSpecificHandlerTable(const MachineFunction *MF);
 
-  void emitSEHActionsForRange(WinEHFuncInfo &FuncInfo,
+  void emitSEHActionsForRange(const WinEHFuncInfo &FuncInfo,
                               const MCSymbol *BeginLabel,
                               const MCSymbol *EndLabel, int State);
 
                               const MCSymbol *BeginLabel,
                               const MCSymbol *EndLabel, int State);
 
@@ -58,7 +58,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
   void emitCLRExceptionTable(const MachineFunction *MF);
 
   void computeIP2StateTable(
   void emitCLRExceptionTable(const MachineFunction *MF);
 
   void computeIP2StateTable(
-      const MachineFunction *MF, WinEHFuncInfo &FuncInfo,
+      const MachineFunction *MF, const WinEHFuncInfo &FuncInfo,
       SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable);
 
   /// Emits the label used with llvm.x86.seh.recoverfp, which is used by
       SmallVectorImpl<std::pair<const MCExpr *, int>> &IPToStateTable);
 
   /// Emits the label used with llvm.x86.seh.recoverfp, which is used by
@@ -77,7 +77,7 @@ class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
   /// given index. For targets using CFI (Win64, etc), this is relative to the
   /// established SP at the end of the prologue. For targets without CFI (Win32
   /// only), it is relative to the frame pointer.
   /// given index. For targets using CFI (Win64, etc), this is relative to the
   /// established SP at the end of the prologue. For targets without CFI (Win32
   /// only), it is relative to the frame pointer.
-  int getFrameIndexOffset(int FrameIndex, WinEHFuncInfo &FuncInfo);
+  int getFrameIndexOffset(int FrameIndex, const WinEHFuncInfo &FuncInfo);
 
 public:
   //===--------------------------------------------------------------------===//
 
 public:
   //===--------------------------------------------------------------------===//
index fa6849fcfdc6d236b3bb18225674de00fde166d7..7e4c9b779f293300c43c754f064fadbbdebea377 100644 (file)
@@ -17,6 +17,7 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Analysis/ConstantFolding.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Analysis/LibCallSemantics.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunctionInitializer.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunctionInitializer.h"
@@ -27,6 +28,7 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/CodeGen/WinEHFuncInfo.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
 #include "llvm/IR/Function.h"
@@ -88,6 +90,11 @@ MachineFunction::MachineFunction(const Function *F, const TargetMachine &TM,
   FunctionNumber = FunctionNum;
   JumpTableInfo = nullptr;
 
   FunctionNumber = FunctionNum;
   JumpTableInfo = nullptr;
 
+  if (isFuncletEHPersonality(classifyEHPersonality(
+          F->hasPersonalityFn() ? F->getPersonalityFn() : nullptr))) {
+    WinEHInfo = new (Allocator) WinEHFuncInfo();
+  }
+
   assert(TM.isCompatibleDataLayout(getDataLayout()) &&
          "Can't create a MachineFunction using a Module with a "
          "Target-incompatible DataLayout attached\n");
   assert(TM.isCompatibleDataLayout(getDataLayout()) &&
          "Can't create a MachineFunction using a Module with a "
          "Target-incompatible DataLayout attached\n");
@@ -125,6 +132,11 @@ MachineFunction::~MachineFunction() {
     JumpTableInfo->~MachineJumpTableInfo();
     Allocator.Deallocate(JumpTableInfo);
   }
     JumpTableInfo->~MachineJumpTableInfo();
     Allocator.Deallocate(JumpTableInfo);
   }
+
+  if (WinEHInfo) {
+    WinEHInfo->~WinEHFuncInfo();
+    Allocator.Deallocate(WinEHInfo);
+  }
 }
 
 const DataLayout &MachineFunction::getDataLayout() const {
 }
 
 const DataLayout &MachineFunction::getDataLayout() const {
index 33db3edffb70439fd63cf147c33c3ff8d7d1d06a..18efcf39c453989b2d3e3833fcec5024ee048554 100644 (file)
@@ -9,12 +9,12 @@
 
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/ADT/PointerUnion.h"
 
 #include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/ADT/PointerUnion.h"
+#include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/Analysis/LibCallSemantics.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/Passes.h"
 #include "llvm/Analysis/LibCallSemantics.h"
 #include "llvm/Analysis/ValueTracking.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFunctionPass.h"
 #include "llvm/CodeGen/Passes.h"
-#include "llvm/CodeGen/WinEHFuncInfo.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/GlobalVariable.h"
@@ -321,12 +321,6 @@ void MachineModuleInfo::addPersonality(const Function *Personality) {
   Personalities.push_back(Personality);
 }
 
   Personalities.push_back(Personality);
 }
 
-void MachineModuleInfo::addWinEHState(MachineBasicBlock *LandingPad,
-                                      int State) {
-  LandingPadInfo &LP = getOrCreateLandingPadInfo(LandingPad);
-  LP.WinEHState = State;
-}
-
 /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
 ///
 void MachineModuleInfo::
 /// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
 ///
 void MachineModuleInfo::
@@ -466,10 +460,3 @@ try_next:;
   FilterIds.push_back(0); // terminator
   return FilterID;
 }
   FilterIds.push_back(0); // terminator
   return FilterID;
 }
-
-WinEHFuncInfo &MachineModuleInfo::getWinEHFuncInfo(const Function *F) {
-  auto &Ptr = FuncInfoMap[F];
-  if (!Ptr)
-    Ptr.reset(new WinEHFuncInfo);
-  return *Ptr;
-}
index 52216c2c1e8224593c6294d29d86d7bad7d00622..8d42dcef14015802f39b930958f9d04df8b66dfb 100644 (file)
@@ -287,7 +287,7 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
     return;
 
   // Calculate state numbers if we haven't already.
     return;
 
   // Calculate state numbers if we haven't already.
-  WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
+  WinEHFuncInfo &EHInfo = *MF->getWinEHFuncInfo();
   if (Personality == EHPersonality::MSVC_CXX)
     calculateWinCXXEHStateNumbers(&fn, EHInfo);
   else if (isAsynchronousEHPersonality(Personality))
   if (Personality == EHPersonality::MSVC_CXX)
     calculateWinCXXEHStateNumbers(&fn, EHInfo);
   else if (isAsynchronousEHPersonality(Personality))
@@ -321,24 +321,6 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
     const BasicBlock *BB = CME.Handler.get<const BasicBlock *>();
     CME.Handler = MBBMap[BB];
   }
     const BasicBlock *BB = CME.Handler.get<const BasicBlock *>();
     CME.Handler = MBBMap[BB];
   }
-
-  // If there's an explicit EH registration node on the stack, record its
-  // frame index.
-  if (EHInfo.EHRegNode && EHInfo.EHRegNode->getParent()->getParent() == Fn) {
-    assert(StaticAllocaMap.count(EHInfo.EHRegNode));
-    EHInfo.EHRegNodeFrameIndex = StaticAllocaMap[EHInfo.EHRegNode];
-  }
-
-  // Copy the state numbers to LandingPadInfo for the current function, which
-  // could be a handler or the parent. This should happen for 32-bit SEH and
-  // C++ EH.
-  if (Personality == EHPersonality::MSVC_CXX ||
-      Personality == EHPersonality::MSVC_X86SEH) {
-    for (const LandingPadInst *LP : LPads) {
-      MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
-      MMI.addWinEHState(LPadMBB, EHInfo.EHPadStateMap[LP]);
-    }
-  }
 }
 
 /// clear - Clear out all the function-specific state. This returns this
 }
 
 /// clear - Clear out all the function-specific state. This returns this
index 63b5d02a65a22711f757f4839fa2f173081d19ef..a699f9c56f21397760e2d571e8376fe3c2cab5a9 100644 (file)
@@ -1221,10 +1221,8 @@ void SelectionDAGBuilder::visitCatchRet(const CatchReturnInst &I) {
   // Figure out the funclet membership for the catchret's successor.
   // This will be used by the FuncletLayout pass to determine how to order the
   // BB's.
   // Figure out the funclet membership for the catchret's successor.
   // This will be used by the FuncletLayout pass to determine how to order the
   // BB's.
-  MachineModuleInfo &MMI = DAG.getMachineFunction().getMMI();
-  WinEHFuncInfo &EHInfo =
-      MMI.getWinEHFuncInfo(DAG.getMachineFunction().getFunction());
-  const BasicBlock *SuccessorColor = EHInfo.CatchRetSuccessorColorMap[&I];
+  WinEHFuncInfo *EHInfo = DAG.getMachineFunction().getWinEHFuncInfo();
+  const BasicBlock *SuccessorColor = EHInfo->CatchRetSuccessorColorMap[&I];
   assert(SuccessorColor && "No parent funclet for catchret!");
   MachineBasicBlock *SuccessorColorMBB = FuncInfo.MBBMap[SuccessorColor];
   assert(SuccessorColorMBB && "No MBB for SuccessorColor!");
   assert(SuccessorColor && "No parent funclet for catchret!");
   MachineBasicBlock *SuccessorColorMBB = FuncInfo.MBBMap[SuccessorColor];
   assert(SuccessorColorMBB && "No MBB for SuccessorColor!");
@@ -5341,9 +5339,8 @@ SelectionDAGBuilder::lowerInvokable(TargetLowering::CallLoweringInfo &CLI,
 
     // Inform MachineModuleInfo of range.
     if (MMI.hasEHFunclets()) {
 
     // Inform MachineModuleInfo of range.
     if (MMI.hasEHFunclets()) {
-      WinEHFuncInfo &EHInfo =
-          MMI.getWinEHFuncInfo(DAG.getMachineFunction().getFunction());
-      EHInfo.addIPToStateRange(EHPadBB, BeginLabel, EndLabel);
+      WinEHFuncInfo *EHInfo = DAG.getMachineFunction().getWinEHFuncInfo();
+      EHInfo->addIPToStateRange(EHPadBB, BeginLabel, EndLabel);
     } else {
       MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
     }
     } else {
       MMI.addInvoke(FuncInfo.MBBMap[EHPadBB], BeginLabel, EndLabel);
     }
index 72baa078661ad2051d6cc0eda53b4f256b89810e..4fbe3613d1e5f0599c7d7cb4909001277af0905f 100644 (file)
@@ -1252,7 +1252,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
       assert(classifyEHPersonality(Fn->getPersonalityFn()) ==
              EHPersonality::MSVC_CXX);
       unsigned FrameReg;
       assert(classifyEHPersonality(Fn->getPersonalityFn()) ==
              EHPersonality::MSVC_CXX);
       unsigned FrameReg;
-      int FI = MMI.getWinEHFuncInfo(Fn).EHRegNodeFrameIndex;
+      int FI = MF.getWinEHFuncInfo()->EHRegNodeFrameIndex;
       int64_t EHRegOffset = getFrameIndexReference(MF, FI, FrameReg);
       // ESP is the first field, so no extra displacement is needed.
       addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32mr)), FrameReg,
       int64_t EHRegOffset = getFrameIndexReference(MF, FI, FrameReg);
       // ESP is the first field, so no extra displacement is needed.
       addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32mr)), FrameReg,
@@ -1292,7 +1292,7 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
     // and the GC can recover it.
     unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
     auto PSPInfo = MachinePointerInfo::getFixedStack(
     // and the GC can recover it.
     unsigned PSPSlotOffset = getPSPSlotOffsetFromSP(MF);
     auto PSPInfo = MachinePointerInfo::getFixedStack(
-        MF, MF.getMMI().getWinEHFuncInfo(Fn).PSPSymFrameIdx);
+        MF, MF.getWinEHFuncInfo()->PSPSymFrameIdx);
     addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64mr)), StackPtr, false,
                  PSPSlotOffset)
         .addReg(StackPtr)
     addRegOffset(BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64mr)), StackPtr, false,
                  PSPSlotOffset)
         .addReg(StackPtr)
@@ -1401,8 +1401,7 @@ static bool isFuncletReturnInstr(MachineInstr *MI) {
 // frame with only a single offset reported for the entire method.
 unsigned
 X86FrameLowering::getPSPSlotOffsetFromSP(const MachineFunction &MF) const {
 // frame with only a single offset reported for the entire method.
 unsigned
 X86FrameLowering::getPSPSlotOffsetFromSP(const MachineFunction &MF) const {
-  MachineModuleInfo &MMI = MF.getMMI();
-  WinEHFuncInfo &Info = MMI.getWinEHFuncInfo(MF.getFunction());
+  const WinEHFuncInfo &Info = *MF.getWinEHFuncInfo();
   // getFrameIndexReferenceFromSP has an out ref parameter for the stack
   // pointer register; pass a dummy that we ignore
   unsigned SPReg;
   // getFrameIndexReferenceFromSP has an out ref parameter for the stack
   // pointer register; pass a dummy that we ignore
   unsigned SPReg;
@@ -2592,9 +2591,7 @@ MachineBasicBlock::iterator X86FrameLowering::restoreWin32EHStackPointers(
   MachineFunction &MF = *MBB.getParent();
   unsigned FramePtr = TRI->getFrameRegister(MF);
   unsigned BasePtr = TRI->getBaseRegister();
   MachineFunction &MF = *MBB.getParent();
   unsigned FramePtr = TRI->getFrameRegister(MF);
   unsigned BasePtr = TRI->getBaseRegister();
-  MachineModuleInfo &MMI = MF.getMMI();
-  const Function *Fn = MF.getFunction();
-  WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(Fn);
+  WinEHFuncInfo &FuncInfo = *MF.getWinEHFuncInfo();
   X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
   MachineFrameInfo *MFI = MF.getFrameInfo();
 
   X86MachineFunctionInfo *X86FI = MF.getInfo<X86MachineFunctionInfo>();
   MachineFrameInfo *MFI = MF.getFrameInfo();
 
@@ -2679,7 +2676,7 @@ void X86FrameLowering::processFunctionBeforeFrameFinalized(
   int64_t UnwindHelpOffset = MinFixedObjOffset - SlotSize;
   int UnwindHelpFI =
       MFI->CreateFixedObject(SlotSize, UnwindHelpOffset, /*Immutable=*/false);
   int64_t UnwindHelpOffset = MinFixedObjOffset - SlotSize;
   int UnwindHelpFI =
       MFI->CreateFixedObject(SlotSize, UnwindHelpOffset, /*Immutable=*/false);
-  MF.getMMI().getWinEHFuncInfo(Fn).UnwindHelpFrameIdx = UnwindHelpFI;
+  MF.getWinEHFuncInfo()->UnwindHelpFrameIdx = UnwindHelpFI;
 
   // Store -2 into UnwindHelp on function entry. We have to scan forwards past
   // other frame setup instructions.
 
   // Store -2 into UnwindHelp on function entry. We have to scan forwards past
   // other frame setup instructions.
index c944e3deec50b60d2b96f905155bfaf6159d1364..2be35511f18352dbd47516bc8db0abee14642565 100644 (file)
@@ -2721,8 +2721,6 @@ SDValue X86TargetLowering::LowerFormalArguments(
         MFI->CreateFixedObject(1, StackSize, true));
   }
 
         MFI->CreateFixedObject(1, StackSize, true));
   }
 
-  MachineModuleInfo &MMI = MF.getMMI();
-
   // Figure out if XMM registers are in use.
   assert(!(Subtarget->useSoftFloat() &&
            Fn->hasFnAttribute(Attribute::NoImplicitFloat)) &&
   // Figure out if XMM registers are in use.
   assert(!(Subtarget->useSoftFloat() &&
            Fn->hasFnAttribute(Attribute::NoImplicitFloat)) &&
@@ -2878,7 +2876,7 @@ SDValue X86TargetLowering::LowerFormalArguments(
 
   FuncInfo->setArgumentStackSize(StackSize);
 
 
   FuncInfo->setArgumentStackSize(StackSize);
 
-  if (MMI.hasWinEHFuncInfo(Fn)) {
+  if (WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo()) {
     EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
     if (Personality == EHPersonality::CoreCLR) {
       assert(Is64Bit);
     EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
     if (Personality == EHPersonality::CoreCLR) {
       assert(Is64Bit);
@@ -2891,7 +2889,7 @@ SDValue X86TargetLowering::LowerFormalArguments(
       // how far this slot is from the bottom (since they allocate just enough
       // space to accomodate holding this slot at the correct offset).
       int PSPSymFI = MFI->CreateStackObject(8, 8, /*isSS=*/false);
       // how far this slot is from the bottom (since they allocate just enough
       // space to accomodate holding this slot at the correct offset).
       int PSPSymFI = MFI->CreateStackObject(8, 8, /*isSS=*/false);
-      MMI.getWinEHFuncInfo(MF.getFunction()).PSPSymFrameIdx = PSPSymFI;
+      EHInfo->PSPSymFrameIdx = PSPSymFI;
     }
   }
 
     }
   }
 
@@ -16940,6 +16938,24 @@ static SDValue LowerSEHRESTOREFRAME(SDValue Op, const X86Subtarget *Subtarget,
   return Chain;
 }
 
   return Chain;
 }
 
+static SDValue MarkEHRegistrationNode(SDValue Op, SelectionDAG &DAG) {
+  MachineFunction &MF = DAG.getMachineFunction();
+  SDValue Chain = Op.getOperand(0);
+  SDValue RegNode = Op.getOperand(2);
+  WinEHFuncInfo *EHInfo = MF.getWinEHFuncInfo();
+  if (!EHInfo)
+    report_fatal_error("EH registrations only live in functions using WinEH");
+
+  // Cast the operand to an alloca, and remember the frame index.
+  auto *FINode = dyn_cast<FrameIndexSDNode>(RegNode);
+  if (!FINode)
+    report_fatal_error("llvm.x86.seh.ehregnode expects a static alloca");
+  EHInfo->EHRegNodeFrameIndex = FINode->getIndex();
+
+  // Return the chain operand without making any DAG nodes.
+  return Chain;
+}
+
 /// \brief Lower intrinsics for TRUNCATE_TO_MEM case
 /// return truncate Store/MaskedStore Node
 static SDValue LowerINTRINSIC_TRUNCATE_TO_MEM(const SDValue & Op,
 /// \brief Lower intrinsics for TRUNCATE_TO_MEM case
 /// return truncate Store/MaskedStore Node
 static SDValue LowerINTRINSIC_TRUNCATE_TO_MEM(const SDValue & Op,
@@ -16985,6 +17001,8 @@ static SDValue LowerINTRINSIC_W_CHAIN(SDValue Op, const X86Subtarget *Subtarget,
   if (!IntrData) {
     if (IntNo == llvm::Intrinsic::x86_seh_restoreframe)
       return LowerSEHRESTOREFRAME(Op, Subtarget, DAG);
   if (!IntrData) {
     if (IntNo == llvm::Intrinsic::x86_seh_restoreframe)
       return LowerSEHRESTOREFRAME(Op, Subtarget, DAG);
+    else if (IntNo == llvm::Intrinsic::x86_seh_ehregnode)
+      return MarkEHRegistrationNode(Op, DAG);
     return SDValue();
   }
 
     return SDValue();
   }
 
index db717385da62ced19e3ba09e2cef806391db76ba..8a5aa40bc7f20b644df557e74fb90062f668d4e9 100644 (file)
@@ -66,18 +66,13 @@ private:
 
   void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
   void unlinkExceptionRegistration(IRBuilder<> &Builder);
 
   void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
   void unlinkExceptionRegistration(IRBuilder<> &Builder);
-  void addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo);
-  void addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo);
-  void addStateStoresToFunclet(Value *ParentRegNode, WinEHFuncInfo &FuncInfo,
-                               Function &F, int BaseState);
+  void addStateStores(Function &F, WinEHFuncInfo &FuncInfo);
   void insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State);
 
   Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
 
   Function *generateLSDAInEAXThunk(Function *ParentFunc);
 
   void insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State);
 
   Value *emitEHLSDA(IRBuilder<> &Builder, Function *F);
 
   Function *generateLSDAInEAXThunk(Function *ParentFunc);
 
-  int escapeRegNode(Function &F);
-
   // Module-level type getters.
   Type *getEHLinkRegistrationType();
   Type *getSEHRegistrationType();
   // Module-level type getters.
   Type *getEHLinkRegistrationType();
   Type *getSEHRegistrationType();
@@ -178,26 +173,13 @@ bool WinEHStatePass::runOnFunction(Function &F) {
 
   emitExceptionRegistrationRecord(&F);
 
 
   emitExceptionRegistrationRecord(&F);
 
-  auto *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
-  // If MMI is null, create our own WinEHFuncInfo.  This only happens in opt
-  // tests.
-  std::unique_ptr<WinEHFuncInfo> FuncInfoPtr;
-  if (!MMI)
-    FuncInfoPtr.reset(new WinEHFuncInfo());
-  WinEHFuncInfo &FuncInfo =
-      *(MMI ? &MMI->getWinEHFuncInfo(&F) : FuncInfoPtr.get());
-
-  FuncInfo.EHRegNode = RegNode;
-
-  switch (Personality) {
-  default: llvm_unreachable("unexpected personality function");
-  case EHPersonality::MSVC_CXX:
-    addCXXStateStores(F, FuncInfo);
-    break;
-  case EHPersonality::MSVC_X86SEH:
-    addSEHStateStores(F, FuncInfo);
-    break;
-  }
+  // The state numbers calculated here in IR must agree with what we calculate
+  // later on for the MachineFunction. In particular, if an IR pass deletes an
+  // unreachable EH pad after this point before machine CFG construction, we
+  // will be in trouble. If this assumption is ever broken, we should turn the
+  // numbers into an immutable analysis pass.
+  WinEHFuncInfo FuncInfo;
+  addStateStores(F, FuncInfo);
 
   // Reset per-function state.
   PersonalityFn = nullptr;
 
   // Reset per-function state.
   PersonalityFn = nullptr;
@@ -418,65 +400,21 @@ void WinEHStatePass::unlinkExceptionRegistration(IRBuilder<> &Builder) {
   Builder.CreateStore(Next, FSZero);
 }
 
   Builder.CreateStore(Next, FSZero);
 }
 
-void WinEHStatePass::addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
-  // Set up RegNodeEscapeIndex
-  int RegNodeEscapeIndex = escapeRegNode(F);
-  FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
-
-  calculateWinCXXEHStateNumbers(&F, FuncInfo);
-  addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
-}
-
-/// Assign every distinct landingpad a unique state number for SEH. Unlike C++
-/// EH, we can use this very simple algorithm while C++ EH cannot because catch
-/// handlers aren't outlined and the runtime doesn't have to figure out which
-/// catch handler frame to unwind to.
-void WinEHStatePass::addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
-  // Remember and return the index that we used. We save it in WinEHFuncInfo so
-  // that we can lower llvm.x86.seh.recoverfp later in filter functions without
-  // too much trouble.
-  int RegNodeEscapeIndex = escapeRegNode(F);
-  FuncInfo.EHRegNodeEscapeIndex = RegNodeEscapeIndex;
-
-  calculateSEHStateNumbers(&F, FuncInfo);
-  addStateStoresToFunclet(RegNode, FuncInfo, F, -1);
-}
-
-/// Escape RegNode so that we can access it from child handlers. Find the call
-/// to localescape, if any, in the entry block and append RegNode to the list
-/// of arguments.
-int WinEHStatePass::escapeRegNode(Function &F) {
-  // Find the call to localescape and extract its arguments.
-  IntrinsicInst *EscapeCall = nullptr;
-  for (Instruction &I : F.getEntryBlock()) {
-    IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
-    if (II && II->getIntrinsicID() == Intrinsic::localescape) {
-      EscapeCall = II;
-      break;
-    }
-  }
-  SmallVector<Value *, 8> Args;
-  if (EscapeCall) {
-    auto Ops = EscapeCall->arg_operands();
-    Args.append(Ops.begin(), Ops.end());
-  }
-  Args.push_back(RegNode);
-
-  // Replace the call (if it exists) with new one. Otherwise, insert at the end
-  // of the entry block.
-  Instruction *InsertPt = EscapeCall;
-  if (!EscapeCall)
-    InsertPt = F.getEntryBlock().getTerminator();
-  IRBuilder<> Builder(InsertPt);
-  Builder.CreateCall(FrameEscape, Args);
-  if (EscapeCall)
-    EscapeCall->eraseFromParent();
-  return Args.size() - 1;
-}
+void WinEHStatePass::addStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
+  // Mark the registration node. The backend needs to know which alloca it is so
+  // that it can recover the original frame pointer.
+  IRBuilder<> Builder(RegNode->getParent(), std::next(RegNode->getIterator()));
+  Value *RegNodeI8 = Builder.CreateBitCast(RegNode, Builder.getInt8PtrTy());
+  Builder.CreateCall(
+      Intrinsic::getDeclaration(TheModule, Intrinsic::x86_seh_ehregnode),
+      {RegNodeI8});
+
+  // Calculate state numbers.
+  if (isAsynchronousEHPersonality(Personality))
+    calculateSEHStateNumbers(&F, FuncInfo);
+  else
+    calculateWinCXXEHStateNumbers(&F, FuncInfo);
 
 
-void WinEHStatePass::addStateStoresToFunclet(Value *ParentRegNode,
-                                             WinEHFuncInfo &FuncInfo,
-                                             Function &F, int BaseState) {
   // Iterate all the instructions and emit state number stores.
   for (BasicBlock &BB : F) {
     for (Instruction &I : BB) {
   // Iterate all the instructions and emit state number stores.
   for (BasicBlock &BB : F) {
     for (Instruction &I : BB) {
@@ -485,14 +423,14 @@ void WinEHStatePass::addStateStoresToFunclet(Value *ParentRegNode,
         // an unwind. Ensure they are in the -1 state.
         if (CI->doesNotThrow())
           continue;
         // an unwind. Ensure they are in the -1 state.
         if (CI->doesNotThrow())
           continue;
-        insertStateNumberStore(ParentRegNode, CI, BaseState);
+        insertStateNumberStore(RegNode, CI, -1);
       } else if (auto *II = dyn_cast<InvokeInst>(&I)) {
         // Look up the state number of the landingpad this unwinds to.
         Instruction *PadInst = II->getUnwindDest()->getFirstNonPHI();
         // FIXME: Why does this assertion fail?
         //assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
         int State = FuncInfo.EHPadStateMap[PadInst];
       } else if (auto *II = dyn_cast<InvokeInst>(&I)) {
         // Look up the state number of the landingpad this unwinds to.
         Instruction *PadInst = II->getUnwindDest()->getFirstNonPHI();
         // FIXME: Why does this assertion fail?
         //assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
         int State = FuncInfo.EHPadStateMap[PadInst];
-        insertStateNumberStore(ParentRegNode, II, State);
+        insertStateNumberStore(RegNode, II, State);
       }
     }
   }
       }
     }
   }
index 0ad385375f72d7498b0a7fbc60887814777d6241..5d9d50383850c7b4cd9304ce93e912bc3919c95a 100644 (file)
@@ -64,8 +64,7 @@ entry:
 ; CHECK: pushl %esi
 
 ; CHECK: Lmain$frame_escape_0 = [[code_offs:[-0-9]+]]
 ; CHECK: pushl %esi
 
 ; CHECK: Lmain$frame_escape_0 = [[code_offs:[-0-9]+]]
-; CHECK: Lmain$frame_escape_1 = [[reg_offs:[-0-9]+]]
-; CHECK: movl %esp, [[reg_offs]](%ebp)
+; CHECK: movl %esp, [[reg_offs:[-0-9]+]](%ebp)
 ; CHECK: movl $L__ehtable$main,
 ;       EH state 0
 ; CHECK: movl $0, -16(%ebp)
 ; CHECK: movl $L__ehtable$main,
 ;       EH state 0
 ; CHECK: movl $0, -16(%ebp)
@@ -84,7 +83,7 @@ entry:
 ; CHECK: calll _printf
 
 ; CHECK: .section .xdata,"dr"
 ; CHECK: calll _printf
 
 ; CHECK: .section .xdata,"dr"
-; CHECK: Lmain$parent_frame_offset = Lmain$frame_escape_1
+; CHECK: Lmain$parent_frame_offset = [[reg_offs]]
 ; CHECK: .align 4
 ; CHECK: L__ehtable$main
 ; CHECK-NEXT: .long -1
 ; CHECK: .align 4
 ; CHECK: L__ehtable$main
 ; CHECK-NEXT: .long -1
index a06b2360fff8e7b17661eb048690e38b6b034934..8494cadddb7bd491af40abb33de4211aa714048c 100644 (file)
@@ -57,8 +57,7 @@ entry:
 
 ; CHECK-LABEL: _main:
 ; CHECK: Lmain$frame_escape_0 = [[code_offs:[-0-9]+]]
 
 ; CHECK-LABEL: _main:
 ; CHECK: Lmain$frame_escape_0 = [[code_offs:[-0-9]+]]
-; CHECK: Lmain$frame_escape_1 = [[reg_offs:[-0-9]+]]
-; CHECK: movl %esp, [[reg_offs]](%esi)
+; CHECK: movl %esp, [[reg_offs:[-0-9]+]](%esi)
 ; CHECK: movl $L__ehtable$main,
 ;       EH state 0
 ; CHECK: movl $0, 40(%esi)
 ; CHECK: movl $L__ehtable$main,
 ;       EH state 0
 ; CHECK: movl $0, 40(%esi)
@@ -77,7 +76,7 @@ entry:
 ; CHECK: calll _printf
 
 ; CHECK: .section .xdata,"dr"
 ; CHECK: calll _printf
 
 ; CHECK: .section .xdata,"dr"
-; CHECK: Lmain$parent_frame_offset = Lmain$frame_escape_1
+; CHECK: Lmain$parent_frame_offset = [[reg_offs]]
 ; CHECK: L__ehtable$main
 ; CHECK-NEXT: .long -1
 ; CHECK-NEXT: .long _filt$main
 ; CHECK: L__ehtable$main
 ; CHECK-NEXT: .long -1
 ; CHECK-NEXT: .long _filt$main