[llvm] r245331 - [WinEH] Calculate state numbers for the new EH representation

David Majnemer via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 18 12:07:12 PDT 2015


Author: majnemer
Date: Tue Aug 18 14:07:12 2015
New Revision: 245331

URL: http://llvm.org/viewvc/llvm-project?rev=245331&view=rev
Log:
[WinEH] Calculate state numbers for the new EH representation

State numbers are calculated by performing a walk from the innermost
funclet to the outermost funclet.   Rudimentary support for the new EH
constructs has been added to the assembly printer, just enough to test
the new machinery.

Differential Revision: http://reviews.llvm.org/D12098

Added:
    llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
    llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h
    llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
    llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
    llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
    llvm/trunk/lib/Target/X86/X86WinEHState.cpp

Modified: llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h?rev=245331&r1=245330&r2=245331&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/WinEHFuncInfo.h Tue Aug 18 14:07:12 2015
@@ -115,19 +115,20 @@ void parseEHActions(const IntrinsicInst
 
 struct WinEHUnwindMapEntry {
   int ToState;
-  Function *Cleanup;
+  const Value *Cleanup;
 };
 
 struct WinEHHandlerType {
   int Adjectives;
   GlobalVariable *TypeDescriptor;
   int CatchObjRecoverIdx;
-  Function *Handler;
+  const Value *Handler;
 };
 
 struct WinEHTryBlockMapEntry {
   int TryLow;
   int TryHigh;
+  int CatchHigh = -1;
   SmallVector<WinEHHandlerType, 1> HandlerArray;
 };
 
@@ -136,7 +137,7 @@ struct WinEHFuncInfo {
   DenseMap<const Function *, const InvokeInst *> LastInvoke;
   DenseMap<const Function *, int> HandlerEnclosedState;
   DenseMap<const Function *, bool> LastInvokeVisited;
-  DenseMap<const LandingPadInst *, int> LandingPadStateMap;
+  DenseMap<const Instruction *, int> EHPadStateMap;
   DenseMap<const Function *, int> CatchHandlerParentFrameObjIdx;
   DenseMap<const Function *, int> CatchHandlerParentFrameObjOffset;
   DenseMap<const Function *, int> CatchHandlerMaxState;
@@ -148,6 +149,8 @@ struct WinEHFuncInfo {
   int UnwindHelpFrameOffset = -1;
   unsigned NumIPToStateFuncsVisited = 0;
 
+  int getLastStateNumber() const { return UnwindMap.size() - 1; }
+
   /// 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;

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp?rev=245331&r1=245330&r2=245331&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.cpp Tue Aug 18 14:07:12 2015
@@ -182,10 +182,10 @@ const MCExpr *WinException::create32bitR
                                  Asm->OutContext);
 }
 
-const MCExpr *WinException::create32bitRef(const GlobalValue *GV) {
-  if (!GV)
+const MCExpr *WinException::create32bitRef(const Value *V) {
+  if (!V)
     return MCConstantExpr::create(0, Asm->OutContext);
-  return create32bitRef(Asm->getSymbol(GV));
+  return create32bitRef(Asm->getSymbol(cast<GlobalValue>(V)));
 }
 
 /// Emit the language-specific data that __C_specific_handler expects.  This
@@ -413,7 +413,8 @@ void WinException::emitCXXFrameHandler3T
       int CatchHigh = -1;
       for (WinEHHandlerType &HT : TBME.HandlerArray)
         CatchHigh =
-            std::max(CatchHigh, FuncInfo.CatchHandlerMaxState[HT.Handler]);
+            std::max(CatchHigh,
+                     FuncInfo.CatchHandlerMaxState[cast<Function>(HT.Handler)]);
 
       assert(TBME.TryLow <= TBME.TryHigh);
       OS.EmitIntValue(TBME.TryLow, 4);                    // TryLow

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h?rev=245331&r1=245330&r2=245331&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/WinException.h Tue Aug 18 14:07:12 2015
@@ -18,9 +18,9 @@
 
 namespace llvm {
 class Function;
-class GlobalValue;
 class MachineFunction;
 class MCExpr;
+class Value;
 struct WinEHFuncInfo;
 
 class LLVM_LIBRARY_VISIBILITY WinException : public EHStreamer {
@@ -56,7 +56,7 @@ class LLVM_LIBRARY_VISIBILITY WinExcepti
                                      StringRef FLinkageName);
 
   const MCExpr *create32bitRef(const MCSymbol *Value);
-  const MCExpr *create32bitRef(const GlobalValue *GV);
+  const MCExpr *create32bitRef(const Value *V);
 
 public:
   //===--------------------------------------------------------------------===//

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp?rev=245331&r1=245330&r2=245331&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp Tue Aug 18 14:07:12 2015
@@ -283,7 +283,7 @@ void FunctionLoweringInfo::set(const Fun
       Personality == EHPersonality::MSVC_X86SEH) {
     for (const LandingPadInst *LP : LPads) {
       MachineBasicBlock *LPadMBB = MBBMap[LP->getParent()];
-      MMI.addWinEHState(LPadMBB, EHInfo.LandingPadStateMap[LP]);
+      MMI.addWinEHState(LPadMBB, EHInfo.EHPadStateMap[LP]);
     }
   }
 }

Modified: llvm/trunk/lib/CodeGen/WinEHPrepare.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/WinEHPrepare.cpp?rev=245331&r1=245330&r2=245331&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/WinEHPrepare.cpp (original)
+++ llvm/trunk/lib/CodeGen/WinEHPrepare.cpp Tue Aug 18 14:07:12 2015
@@ -2575,14 +2575,52 @@ struct WinEHNumbering {
 };
 }
 
-void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) {
+static int addUnwindMapEntry(WinEHFuncInfo &FuncInfo, int ToState,
+                             const Value *V) {
   WinEHUnwindMapEntry UME;
   UME.ToState = ToState;
-  if (auto *CH = dyn_cast_or_null<CleanupHandler>(AH))
-    UME.Cleanup = cast<Function>(CH->getHandlerBlockOrFunc());
-  else
-    UME.Cleanup = nullptr;
+  UME.Cleanup = V;
   FuncInfo.UnwindMap.push_back(UME);
+  return FuncInfo.getLastStateNumber();
+}
+
+static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
+                                int TryHigh, int CatchHigh,
+                                ArrayRef<const CatchPadInst *> Handlers) {
+  WinEHTryBlockMapEntry TBME;
+  TBME.TryLow = TryLow;
+  TBME.TryHigh = TryHigh;
+  TBME.CatchHigh = CatchHigh;
+  assert(TBME.TryLow <= TBME.TryHigh);
+  for (const CatchPadInst *CPI : Handlers) {
+    WinEHHandlerType HT;
+    Constant *TypeInfo = cast<Constant>(CPI->getArgOperand(0));
+    if (TypeInfo->isNullValue()) {
+      HT.Adjectives = 0x40;
+      HT.TypeDescriptor = nullptr;
+    } else {
+      auto *GV = cast<GlobalVariable>(TypeInfo->stripPointerCasts());
+      // Selectors are always pointers to GlobalVariables with 'struct' type.
+      // The struct has two fields, adjectives and a type descriptor.
+      auto *CS = cast<ConstantStruct>(GV->getInitializer());
+      HT.Adjectives =
+          cast<ConstantInt>(CS->getAggregateElement(0U))->getZExtValue();
+      HT.TypeDescriptor =
+          cast<GlobalVariable>(CS->getAggregateElement(1)->stripPointerCasts());
+    }
+    HT.Handler = CPI->getParent();
+    // FIXME: Pass CPI->getArgOperand(1).
+    HT.CatchObjRecoverIdx = -1;
+    TBME.HandlerArray.push_back(HT);
+  }
+  FuncInfo.TryBlockMap.push_back(TBME);
+}
+
+void WinEHNumbering::createUnwindMapEntry(int ToState, ActionHandler *AH) {
+  Value *V = nullptr;
+  if (auto *CH = dyn_cast_or_null<CleanupHandler>(AH))
+    V = cast<Function>(CH->getHandlerBlockOrFunc());
+  addUnwindMapEntry(FuncInfo, ToState, V);
 }
 
 void WinEHNumbering::createTryBlockMapEntry(int TryLow, int TryHigh,
@@ -2838,7 +2876,7 @@ void WinEHNumbering::calculateStateNumbe
       continue;
     processCallSite(ActionList, II);
     ActionList.clear();
-    FuncInfo.LandingPadStateMap[LPI] = currentEHNumber();
+    FuncInfo.EHPadStateMap[LPI] = currentEHNumber();
     DEBUG(dbgs() << "Assigning state " << currentEHNumber()
                   << " to landing pad at " << LPI->getParent()->getName()
                   << '\n');
@@ -2902,10 +2940,114 @@ void WinEHNumbering::findActionRootLPads
   }
 }
 
+static const BasicBlock *getSingleCatchPadPredecessor(const BasicBlock &BB) {
+  for (const BasicBlock *PredBlock : predecessors(&BB))
+    if (isa<CatchPadInst>(PredBlock->getFirstNonPHI()))
+      return PredBlock;
+  return nullptr;
+}
+
+// Given BB which ends in an unwind edge, return the EHPad that this BB belongs
+// to. If the unwind edge came from an invoke, return null.
+static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB) {
+  const TerminatorInst *TI = BB->getTerminator();
+  if (isa<InvokeInst>(TI))
+    return nullptr;
+  if (isa<CatchPadInst>(TI) || isa<CatchEndPadInst>(TI) ||
+      isa<TerminatePadInst>(TI))
+    return BB;
+  return cast<CleanupPadInst>(cast<CleanupReturnInst>(TI)->getReturnValue())
+      ->getParent();
+}
+
+static void calculateExplicitStateNumbers(WinEHFuncInfo &FuncInfo,
+                                          const BasicBlock &BB,
+                                          int ParentState) {
+  assert(BB.isEHPad());
+  const Instruction *FirstNonPHI = BB.getFirstNonPHI();
+  // All catchpad instructions will be handled when we process their
+  // respective catchendpad instruction.
+  if (isa<CatchPadInst>(FirstNonPHI))
+    return;
+
+  if (isa<CatchEndPadInst>(FirstNonPHI)) {
+    const BasicBlock *TryPad = &BB;
+    const BasicBlock *LastTryPad = nullptr;
+    SmallVector<const CatchPadInst *, 2> Handlers;
+    do {
+      LastTryPad = TryPad;
+      TryPad = getSingleCatchPadPredecessor(*TryPad);
+      if (TryPad)
+        Handlers.push_back(cast<CatchPadInst>(TryPad->getFirstNonPHI()));
+    } while (TryPad);
+    // We've pushed these back into reverse source order.  Reverse them to get
+    // the list back into source order.
+    std::reverse(Handlers.begin(), Handlers.end());
+    int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
+    FuncInfo.EHPadStateMap[Handlers.front()] = TryLow;
+    for (const BasicBlock *PredBlock : predecessors(LastTryPad))
+      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
+        calculateExplicitStateNumbers(FuncInfo, *PredBlock, TryLow);
+    int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
+    FuncInfo.EHPadStateMap[FirstNonPHI] = CatchLow;
+    int TryHigh = CatchLow - 1;
+    for (const BasicBlock *PredBlock : predecessors(&BB))
+      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
+        calculateExplicitStateNumbers(FuncInfo, *PredBlock, CatchLow);
+    int CatchHigh = FuncInfo.getLastStateNumber();
+    addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
+    DEBUG(dbgs() << "TryLow[" << LastTryPad->getName() << "]: " << TryLow
+                 << '\n');
+    DEBUG(dbgs() << "TryHigh[" << LastTryPad->getName() << "]: " << TryHigh
+                 << '\n');
+    DEBUG(dbgs() << "CatchHigh[" << LastTryPad->getName() << "]: " << CatchHigh
+                 << '\n');
+  } else if (isa<CleanupPadInst>(FirstNonPHI)) {
+    int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, &BB);
+    FuncInfo.EHPadStateMap[FirstNonPHI] = CleanupState;
+    DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
+                 << BB.getName() << '\n');
+    for (const BasicBlock *PredBlock : predecessors(&BB))
+      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
+        calculateExplicitStateNumbers(FuncInfo, *PredBlock, CleanupState);
+  } else if (isa<TerminatePadInst>(FirstNonPHI)) {
+    report_fatal_error("Not yet implemented!");
+  } else {
+    llvm_unreachable("unexpected EH Pad!");
+  }
+}
+
 void llvm::calculateWinCXXEHStateNumbers(const Function *ParentFn,
                                          WinEHFuncInfo &FuncInfo) {
   // Return if it's already been done.
-  if (!FuncInfo.LandingPadStateMap.empty())
+  if (!FuncInfo.EHPadStateMap.empty())
+    return;
+
+  bool IsExplicit = false;
+  for (const BasicBlock &BB : *ParentFn) {
+    if (!BB.isEHPad())
+      continue;
+    // Check if the EH Pad has no exceptional successors (i.e. it unwinds to
+    // caller).  Cleanups are a little bit of a special case because their
+    // control flow cannot be determined by looking at the pad but instead by
+    // the pad's users.
+    bool HasNoSuccessors = false;
+    const Instruction *FirstNonPHI = BB.getFirstNonPHI();
+    if (FirstNonPHI->mayThrow()) {
+      HasNoSuccessors = true;
+    } else if (auto *CPI = dyn_cast<CleanupPadInst>(FirstNonPHI)) {
+      HasNoSuccessors =
+          CPI->use_empty() ||
+          cast<CleanupReturnInst>(CPI->user_back())->unwindsToCaller();
+    }
+
+    if (!HasNoSuccessors)
+      continue;
+    calculateExplicitStateNumbers(FuncInfo, BB, -1);
+    IsExplicit = true;
+  }
+
+  if (IsExplicit)
     return;
 
   WinEHNumbering Num(FuncInfo);
@@ -3141,6 +3283,7 @@ bool WinEHPrepare::prepareExplicitEH(Fun
 
   BlockColors.clear();
   FuncletBlocks.clear();
+
   return true;
 }
 

Modified: llvm/trunk/lib/Target/X86/X86TargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?rev=245331&r1=245330&r2=245331&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86TargetMachine.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86TargetMachine.cpp Tue Aug 18 14:07:12 2015
@@ -28,10 +28,17 @@ static cl::opt<bool> EnableMachineCombin
                                cl::desc("Enable the machine combiner pass"),
                                cl::init(true), cl::Hidden);
 
+namespace llvm {
+void initializeWinEHStatePassPass(PassRegistry &);
+}
+
 extern "C" void LLVMInitializeX86Target() {
   // Register the target.
   RegisterTargetMachine<X86TargetMachine> X(TheX86_32Target);
   RegisterTargetMachine<X86TargetMachine> Y(TheX86_64Target);
+
+  PassRegistry &PR = *PassRegistry::getPassRegistry();
+  initializeWinEHStatePassPass(PR);
 }
 
 static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) {

Modified: llvm/trunk/lib/Target/X86/X86WinEHState.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86WinEHState.cpp?rev=245331&r1=245330&r2=245331&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86WinEHState.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86WinEHState.cpp Tue Aug 18 14:07:12 2015
@@ -38,12 +38,16 @@ using namespace llvm::PatternMatch;
 
 #define DEBUG_TYPE "winehstate"
 
+namespace llvm { void initializeWinEHStatePassPass(PassRegistry &); }
+
 namespace {
 class WinEHStatePass : public FunctionPass {
 public:
   static char ID; // Pass identification, replacement for typeid.
 
-  WinEHStatePass() : FunctionPass(ID) {}
+  WinEHStatePass() : FunctionPass(ID) {
+    initializeWinEHStatePassPass(*PassRegistry::getPassRegistry());
+  }
 
   bool runOnFunction(Function &Fn) override;
 
@@ -62,8 +66,8 @@ private:
 
   void linkExceptionRegistration(IRBuilder<> &Builder, Function *Handler);
   void unlinkExceptionRegistration(IRBuilder<> &Builder);
-  void addCXXStateStores(Function &F, MachineModuleInfo &MMI);
-  void addSEHStateStores(Function &F, MachineModuleInfo &MMI);
+  void addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo);
+  void addSEHStateStores(Function &F, WinEHFuncInfo &FuncInfo);
   void addCXXStateStoresToFunclet(Value *ParentRegNode, WinEHFuncInfo &FuncInfo,
                                   Function &F, int BaseState);
   void insertStateNumberStore(Value *ParentRegNode, Instruction *IP, int State);
@@ -111,6 +115,9 @@ FunctionPass *llvm::createX86WinEHStateP
 
 char WinEHStatePass::ID = 0;
 
+INITIALIZE_PASS(WinEHStatePass, "x86-winehstate",
+                "Insert stores for EH state numbers", false, false)
+
 bool WinEHStatePass::doInitialization(Module &M) {
   TheModule = &M;
   FrameEscape = Intrinsic::getDeclaration(TheModule, Intrinsic::localescape);
@@ -163,13 +170,23 @@ bool WinEHStatePass::runOnFunction(Funct
 
   emitExceptionRegistrationRecord(&F);
 
-  auto *MMIPtr = getAnalysisIfAvailable<MachineModuleInfo>();
-  assert(MMIPtr && "MachineModuleInfo should always be available");
-  MachineModuleInfo &MMI = *MMIPtr;
+  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());
+
   switch (Personality) {
   default: llvm_unreachable("unexpected personality function");
-  case EHPersonality::MSVC_CXX:    addCXXStateStores(F, MMI); break;
-  case EHPersonality::MSVC_X86SEH: addSEHStateStores(F, MMI); break;
+  case EHPersonality::MSVC_CXX:
+    addCXXStateStores(F, FuncInfo);
+    break;
+  case EHPersonality::MSVC_X86SEH:
+    addSEHStateStores(F, FuncInfo);
+    break;
   }
 
   // Reset per-function state.
@@ -391,8 +408,7 @@ void WinEHStatePass::unlinkExceptionRegi
   Builder.CreateStore(Next, FSZero);
 }
 
-void WinEHStatePass::addCXXStateStores(Function &F, MachineModuleInfo &MMI) {
-  WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(&F);
+void WinEHStatePass::addCXXStateStores(Function &F, WinEHFuncInfo &FuncInfo) {
   calculateWinCXXEHStateNumbers(&F, FuncInfo);
 
   // The base state for the parent is -1.
@@ -466,10 +482,10 @@ void WinEHStatePass::addCXXStateStoresTo
         insertStateNumberStore(ParentRegNode, CI, BaseState);
       } else if (auto *II = dyn_cast<InvokeInst>(&I)) {
         // Look up the state number of the landingpad this unwinds to.
-        LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst();
+        Instruction *PadInst = II->getUnwindDest()->getFirstNonPHI();
         // FIXME: Why does this assertion fail?
-        //assert(FuncInfo.LandingPadStateMap.count(LPI) && "LP has no state!");
-        int State = FuncInfo.LandingPadStateMap[LPI];
+        //assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
+        int State = FuncInfo.EHPadStateMap[PadInst];
         insertStateNumberStore(ParentRegNode, II, State);
       }
     }
@@ -481,9 +497,7 @@ void WinEHStatePass::addCXXStateStoresTo
 /// handlers aren't outlined and the runtime doesn't have to figure out which
 /// catch handler frame to unwind to.
 /// FIXME: __finally blocks are outlined, so this approach may break down there.
-void WinEHStatePass::addSEHStateStores(Function &F, MachineModuleInfo &MMI) {
-  WinEHFuncInfo &FuncInfo = MMI.getWinEHFuncInfo(&F);
-
+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.
@@ -507,7 +521,7 @@ void WinEHStatePass::addSEHStateStores(F
         // Look up the state number of the landingpad this unwinds to.
         LandingPadInst *LPI = II->getUnwindDest()->getLandingPadInst();
         auto InsertionPair =
-            FuncInfo.LandingPadStateMap.insert(std::make_pair(LPI, CurState));
+            FuncInfo.EHPadStateMap.insert(std::make_pair(LPI, CurState));
         auto Iter = InsertionPair.first;
         int &State = Iter->second;
         bool Inserted = InsertionPair.second;

Added: llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll?rev=245331&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll (added)
+++ llvm/trunk/test/CodeGen/WinEH/wineh-statenumbering.ll Tue Aug 18 14:07:12 2015
@@ -0,0 +1,96 @@
+; RUN: opt -mtriple=i686-pc-windows-msvc -S -x86-winehstate  < %s | FileCheck %s
+
+target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
+target triple = "i686-pc-windows-msvc"
+
+%rtti.TypeDescriptor2 = type { i8**, i8*, [3 x i8] }
+%eh.CatchableType = type { i32, i8*, i32, i32, i32, i32, i8* }
+%eh.CatchableTypeArray.1 = type { i32, [1 x %eh.CatchableType*] }
+%eh.ThrowInfo = type { i32, i8*, i8*, i8* }
+
+$"\01??_R0H at 8" = comdat any
+
+$"_CT??_R0H at 84" = comdat any
+
+$_CTA1H = comdat any
+
+$_TI1H = comdat any
+
+@"\01??_7type_info@@6B@" = external constant i8*
+@"\01??_R0H at 8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat
+@"_CT??_R0H at 84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H at 8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat
+ at _CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0H at 84"] }, section ".xdata", comdat
+ at _TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1H to i8*) }, section ".xdata", comdat
+
+define i32 @main() #0 personality i32 (...)* @__CxxFrameHandler3 {
+entry:
+  %tmp = alloca i32, align 4
+  ; CHECK: entry:
+  ; CHECK:   store i32 -1
+  ; CHECK:   call void @g(i32 3)
+  call void @g(i32 3)
+  store i32 0, i32* %tmp, align 4
+  %0 = bitcast i32* %tmp to i8*
+  ; CHECK:   store i32 0
+  ; CHECK:   invoke void @_CxxThrowException(
+  invoke void @_CxxThrowException(i8* %0, %eh.ThrowInfo* nonnull @_TI1H) #1
+          to label %unreachable.for.entry unwind label %catch.dispatch
+
+catch.dispatch:                                   ; preds = %entry
+  %1 = catchpad token [i8* null, i8* null] to label %catch unwind label %catchendblock
+
+catch:                                            ; preds = %catch.dispatch
+  ; CHECK: catch:
+  ; CHECK:   store i32 2
+  ; CHECK:   invoke void @_CxxThrowException(
+  invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #1
+          to label %unreachable unwind label %catch.dispatch.1
+
+catch.dispatch.1:                                 ; preds = %catch
+  %2 = catchpad token [i8* null, i8* null] to label %catch.3 unwind label %catchendblock.2
+
+catch.3:                                          ; preds = %catch.dispatch.1
+  ; CHECK: catch.3:
+  ; CHECK:   store i32 3
+  ; CHECK:   invoke void @g(i32 1)
+  invoke void @g(i32 1)
+          to label %invoke.cont unwind label %catchendblock.2
+
+invoke.cont:                                      ; preds = %catch.3
+  catchret token %2 to label %try.cont
+
+try.cont:                                         ; preds = %invoke.cont
+  ; CHECK: try.cont:
+  ; CHECK:   store i32 1
+  ; CHECK:   invoke void @g(i32 2)
+  invoke void @g(i32 2)
+          to label %invoke.cont.4 unwind label %catchendblock
+
+invoke.cont.4:                                    ; preds = %try.cont
+  unreachable
+
+catchendblock.2:                                  ; preds = %catch.3, %catch.dispatch.1
+  catchendpad unwind label %catchendblock
+
+catchendblock:                                    ; preds = %catchendblock.2, %try.cont, %catch.dispatch
+  catchendpad unwind to caller
+
+unreachable:                                      ; preds = %catch
+  unreachable
+
+unreachable.for.entry:                            ; preds = %entry
+  unreachable
+}
+
+declare void @g(i32) #0
+
+declare x86_stdcallcc void @_CxxThrowException(i8*, %eh.ThrowInfo*)
+
+declare i32 @__CxxFrameHandler3(...)
+
+attributes #0 = { "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-realign-stack" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+attributes #1 = { noreturn }
+
+!llvm.ident = !{!0}
+
+!0 = !{!"clang version 3.8.0 (trunk 245153) (llvm/trunk 245238)"}




More information about the llvm-commits mailing list