[WinEH] Implement state numbering for CoreCLR
[oota-llvm.git] / lib / CodeGen / SelectionDAG / FunctionLoweringInfo.cpp
index 7bbb194ac19ac5407104290087f2e2d26816a7b7..d718ede35cde2abdc9bd1abf607a171f5e0a69e7 100644 (file)
@@ -223,8 +223,6 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
         assert(&*BB->begin() == I &&
                "WinEHPrepare failed to remove PHIs from imaginary BBs");
         continue;
-      } else if (!isa<LandingPadInst>(I)) {
-        llvm_unreachable("unhandled EH pad in MBB graph");
       }
     }
 
@@ -269,17 +267,17 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
   SmallVector<const LandingPadInst *, 4> LPads;
   for (BB = Fn->begin(); BB != EB; ++BB) {
     const Instruction *FNP = BB->getFirstNonPHI();
-    if (BB->isEHPad() && !isa<CatchPadInst>(FNP) && !isa<CatchEndPadInst>(FNP))
+    if (BB->isEHPad() && MBBMap.count(BB))
       MBBMap[BB]->setIsEHPad();
     if (const auto *LPI = dyn_cast<LandingPadInst>(FNP))
       LPads.push_back(LPI);
   }
 
-  // If this is an MSVC EH personality, we need to do a bit more work.
+  // If this personality uses funclets, we need to do a bit more work.
   if (!Fn->hasPersonalityFn())
     return;
   EHPersonality Personality = classifyEHPersonality(Fn->getPersonalityFn());
-  if (!isMSVCEHPersonality(Personality))
+  if (!isFuncletEHPersonality(Personality))
     return;
 
   if (Personality == EHPersonality::MSVC_Win64SEH ||
@@ -287,22 +285,50 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
     addSEHHandlersForLPads(LPads);
   }
 
+  // Calculate state numbers if we haven't already.
   WinEHFuncInfo &EHInfo = MMI.getWinEHFuncInfo(&fn);
-  if (Personality == EHPersonality::MSVC_CXX) {
-    // Calculate state numbers and then map from funclet BBs to MBBs.
-    const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
+  const Function *WinEHParentFn = MMI.getWinEHParent(&fn);
+  if (Personality == EHPersonality::MSVC_CXX)
     calculateWinCXXEHStateNumbers(WinEHParentFn, EHInfo);
-    for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap)
-      for (WinEHHandlerType &H : TBME.HandlerArray)
-        if (const auto *BB = dyn_cast<BasicBlock>(H.Handler))
-          H.HandlerMBB = 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];
+  else if (isAsynchronousEHPersonality(Personality))
+    calculateSEHStateNumbers(WinEHParentFn, EHInfo);
+  else if (Personality == EHPersonality::CoreCLR)
+    calculateClrEHStateNumbers(WinEHParentFn, EHInfo);
+
+  calculateCatchReturnSuccessorColors(WinEHParentFn, EHInfo);
+
+  // Map all BB references in the WinEH data to MBBs.
+  for (WinEHTryBlockMapEntry &TBME : EHInfo.TryBlockMap) {
+    for (WinEHHandlerType &H : TBME.HandlerArray) {
+      if (H.CatchObjRecoverIdx == -2 && H.CatchObj.Alloca) {
+        assert(StaticAllocaMap.count(H.CatchObj.Alloca));
+        H.CatchObj.FrameIndex = StaticAllocaMap[H.CatchObj.Alloca];
+      } else {
+        H.CatchObj.FrameIndex = INT_MAX;
+      }
+      if (const auto *BB = dyn_cast<BasicBlock>(H.Handler.get<const Value *>()))
+        H.Handler = MBBMap[BB];
     }
   }
+  for (WinEHUnwindMapEntry &UME : EHInfo.UnwindMap)
+    if (UME.Cleanup)
+      if (const auto *BB = dyn_cast<BasicBlock>(UME.Cleanup.get<const Value *>()))
+        UME.Cleanup = MBBMap[BB];
+  for (SEHUnwindMapEntry &UME : EHInfo.SEHUnwindMap) {
+    const BasicBlock *BB = UME.Handler.get<const BasicBlock *>();
+    UME.Handler = MBBMap[BB];
+  }
+  for (ClrEHUnwindMapEntry &CME : EHInfo.ClrEHUnwindMap) {
+    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