[WinEH] Update catchrets with cloned successors
[oota-llvm.git] / lib / CodeGen / WinEHPrepare.cpp
index 7175ae5aefdec8166b47cef2ed32e07848b695d9..3d1c38031946a2c7bcfcdc9f24d604f8e59df41a 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/Passes.h"
+#include "llvm/ADT/MapVector.h"
 #include "llvm/Analysis/CFG.h"
-#include "llvm/Analysis/LibCallSemantics.h"
+#include "llvm/Analysis/EHPersonalities.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
 #include "llvm/CodeGen/WinEHFuncInfo.h"
+#include "llvm/IR/Verifier.h"
+#include "llvm/MC/MCSymbol.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
@@ -44,7 +48,7 @@ static cl::opt<bool> DisableCleanups(
     cl::init(false));
 
 namespace {
-
+  
 class WinEHPrepare : public FunctionPass {
 public:
   static char ID; // Pass identification, replacement for typeid.
@@ -68,52 +72,20 @@ private:
   AllocaInst *insertPHILoads(PHINode *PN, Function &F);
   void replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
                           DenseMap<BasicBlock *, Value *> &Loads, Function &F);
-  void demoteNonlocalUses(Value *V, std::set<BasicBlock *> &ColorsForBB,
-                          Function &F);
-  bool prepareExplicitEH(Function &F,
-                         SmallVectorImpl<BasicBlock *> &EntryBlocks);
-  void replaceTerminatePadWithCleanup(Function &F);
-  void colorFunclets(Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks);
-  void resolveFuncletAncestry(Function &F,
-                              SmallVectorImpl<BasicBlock *> &EntryBlocks);
-  void resolveFuncletAncestryForPath(
-      Function &F, SmallVectorImpl<BasicBlock *> &FuncletPath,
-      std::map<BasicBlock *, BasicBlock *> &IdentityMap);
-  void makeFuncletEdgeUnreachable(BasicBlock *Parent, BasicBlock *Child);
-  BasicBlock *cloneFuncletForParent(Function &F, BasicBlock *FuncletEntry,
-                                    BasicBlock *Parent);
-  void updateTerminatorsAfterFuncletClone(
-      Function &F, BasicBlock *OrigFunclet, BasicBlock *CloneFunclet,
-      BasicBlock *OrigBlock, BasicBlock *CloneBlock, BasicBlock *CloneParent,
-      ValueToValueMapTy &VMap,
-      std::map<BasicBlock *, BasicBlock *> &Orig2Clone);
+  bool prepareExplicitEH(Function &F);
+  void colorFunclets(Function &F);
 
   void demotePHIsOnFunclets(Function &F);
-  void demoteUsesBetweenFunclets(Function &F);
-  void demoteArgumentUses(Function &F);
-  void cloneCommonBlocks(Function &F,
-                         SmallVectorImpl<BasicBlock *> &EntryBlocks);
-  void removeImplausibleTerminators(Function &F);
+  void cloneCommonBlocks(Function &F);
+  void removeImplausibleInstructions(Function &F);
   void cleanupPreparedFunclets(Function &F);
   void verifyPreparedFunclets(Function &F);
 
   // All fields are reset by runOnFunction.
   EHPersonality Personality = EHPersonality::Unknown;
 
-  std::map<BasicBlock *, std::set<BasicBlock *>> BlockColors;
-  std::map<BasicBlock *, std::set<BasicBlock *>> FuncletBlocks;
-  std::map<BasicBlock *, std::vector<BasicBlock *>> FuncletChildren;
-  std::map<BasicBlock *, std::vector<BasicBlock *>> FuncletParents;
-
-  // This is a flag that indicates an uncommon situation where we need to
-  // clone funclets has been detected.
-  bool FuncletCloningRequired = false;
-  // When a funclet with multiple parents contains a catchret, the block to
-  // which it returns will be cloned so that there is a copy in each parent
-  // but one of the copies will not be properly linked to the catchret and
-  // in most cases will have no predecessors.  This double map allows us
-  // to find these cloned blocks when we clone the child funclet.
-  std::map<BasicBlock *, std::map<BasicBlock *, BasicBlock*>> EstrangedBlocks;
+  DenseMap<BasicBlock *, ColorVector> BlockColors;
+  MapVector<BasicBlock *, std::vector<BasicBlock *>> FuncletBlocks;
 };
 
 } // end anonymous namespace
@@ -126,21 +98,6 @@ FunctionPass *llvm::createWinEHPass(const TargetMachine *TM) {
   return new WinEHPrepare(TM);
 }
 
-static void findFuncletEntryPoints(Function &Fn,
-                                   SmallVectorImpl<BasicBlock *> &EntryBlocks) {
-  EntryBlocks.push_back(&Fn.getEntryBlock());
-  for (BasicBlock &BB : Fn) {
-    Instruction *First = BB.getFirstNonPHI();
-    if (!First->isEHPad())
-      continue;
-    assert(!isa<LandingPadInst>(First) &&
-           "landingpad cannot be used with funclet EH personality");
-    // Find EH pad blocks that represent funclet start points.
-    if (!isa<CatchEndPadInst>(First) && !isa<CleanupEndPadInst>(First))
-      EntryBlocks.push_back(&BB);
-  }
-}
-
 bool WinEHPrepare::runOnFunction(Function &Fn) {
   if (!Fn.hasPersonalityFn())
     return false;
@@ -152,14 +109,7 @@ bool WinEHPrepare::runOnFunction(Function &Fn) {
   if (!isFuncletEHPersonality(Personality))
     return false;
 
-  // Remove unreachable blocks.  It is not valuable to assign them a color and
-  // their existence can trick us into thinking values are alive when they are
-  // not.
-  removeUnreachableBlocks(Fn);
-
-  SmallVector<BasicBlock *, 4> EntryBlocks;
-  findFuncletEntryPoints(Fn, EntryBlocks);
-  return prepareExplicitEH(Fn, EntryBlocks);
+  return prepareExplicitEH(Fn);
 }
 
 bool WinEHPrepare::doFinalization(Module &M) { return false; }
@@ -201,117 +151,146 @@ static void addTryBlockMapEntry(WinEHFuncInfo &FuncInfo, int TryLow,
   FuncInfo.TryBlockMap.push_back(TBME);
 }
 
-static const CatchPadInst *getSingleCatchPadPredecessor(const BasicBlock *BB) {
-  for (const BasicBlock *PredBlock : predecessors(BB))
-    if (auto *CPI = dyn_cast<CatchPadInst>(PredBlock->getFirstNonPHI()))
-      return CPI;
+static BasicBlock *getCleanupRetUnwindDest(const CleanupPadInst *CleanupPad) {
+  for (const User *U : CleanupPad->users())
+    if (const auto *CRI = dyn_cast<CleanupReturnInst>(U))
+      return CRI->getUnwindDest();
   return nullptr;
 }
 
-/// Find all the catchpads that feed directly into the catchendpad. Frontends
-/// using this personality should ensure that each catchendpad and catchpad has
-/// one or zero catchpad predecessors.
-///
-/// The following C++ generates the IR after it:
-///   try {
-///   } catch (A) {
-///   } catch (B) {
-///   }
-///
-/// IR:
-///   %catchpad.A
-///     catchpad [i8* A typeinfo]
-///         to label %catch.A unwind label %catchpad.B
-///   %catchpad.B
-///     catchpad [i8* B typeinfo]
-///         to label %catch.B unwind label %endcatches
-///   %endcatches
-///     catchendblock unwind to caller
-static void
-findCatchPadsForCatchEndPad(const BasicBlock *CatchEndBB,
-                            SmallVectorImpl<const CatchPadInst *> &Handlers) {
-  const CatchPadInst *CPI = getSingleCatchPadPredecessor(CatchEndBB);
-  while (CPI) {
-    Handlers.push_back(CPI);
-    CPI = getSingleCatchPadPredecessor(CPI->getParent());
+static void calculateStateNumbersForInvokes(const Function *Fn,
+                                            WinEHFuncInfo &FuncInfo) {
+  auto *F = const_cast<Function *>(Fn);
+  DenseMap<BasicBlock *, ColorVector> BlockColors = colorEHFunclets(*F);
+  for (BasicBlock &BB : *F) {
+    auto *II = dyn_cast<InvokeInst>(BB.getTerminator());
+    if (!II)
+      continue;
+
+    auto &BBColors = BlockColors[&BB];
+    assert(BBColors.size() == 1 && "multi-color BB not removed by preparation");
+    BasicBlock *FuncletEntryBB = BBColors.front();
+
+    BasicBlock *FuncletUnwindDest;
+    auto *FuncletPad =
+        dyn_cast<FuncletPadInst>(FuncletEntryBB->getFirstNonPHI());
+    assert(FuncletPad || FuncletEntryBB == &Fn->getEntryBlock());
+    if (!FuncletPad)
+      FuncletUnwindDest = nullptr;
+    else if (auto *CatchPad = dyn_cast<CatchPadInst>(FuncletPad))
+      FuncletUnwindDest = CatchPad->getCatchSwitch()->getUnwindDest();
+    else if (auto *CleanupPad = dyn_cast<CleanupPadInst>(FuncletPad))
+      FuncletUnwindDest = getCleanupRetUnwindDest(CleanupPad);
+    else
+      llvm_unreachable("unexpected funclet pad!");
+
+    BasicBlock *InvokeUnwindDest = II->getUnwindDest();
+    int BaseState = -1;
+    if (FuncletUnwindDest == InvokeUnwindDest) {
+      auto BaseStateI = FuncInfo.FuncletBaseStateMap.find(FuncletPad);
+      if (BaseStateI != FuncInfo.FuncletBaseStateMap.end())
+        BaseState = BaseStateI->second;
+    }
+
+    if (BaseState != -1) {
+      FuncInfo.InvokeStateMap[II] = BaseState;
+    } else {
+      Instruction *PadInst = InvokeUnwindDest->getFirstNonPHI();
+      assert(FuncInfo.EHPadStateMap.count(PadInst) && "EH Pad has no state!");
+      FuncInfo.InvokeStateMap[II] = FuncInfo.EHPadStateMap[PadInst];
+    }
   }
-  // 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());
 }
 
 // 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) {
+static const BasicBlock *getEHPadFromPredecessor(const BasicBlock *BB,
+                                                 Value *ParentPad) {
   const TerminatorInst *TI = BB->getTerminator();
   if (isa<InvokeInst>(TI))
     return nullptr;
-  if (TI->isEHPad())
+  if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(TI)) {
+    if (CatchSwitch->getParentPad() != ParentPad)
+      return nullptr;
     return BB;
-  return cast<CleanupReturnInst>(TI)->getCleanupPad()->getParent();
+  }
+  assert(!TI->isEHPad() && "unexpected EHPad!");
+  auto *CleanupPad = cast<CleanupReturnInst>(TI)->getCleanupPad();
+  if (CleanupPad->getParentPad() != ParentPad)
+    return nullptr;
+  return CleanupPad->getParent();
 }
 
-static void calculateExplicitCXXStateNumbers(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;
+static void calculateCXXStateNumbers(WinEHFuncInfo &FuncInfo,
+                                     const Instruction *FirstNonPHI,
+                                     int ParentState) {
+  const BasicBlock *BB = FirstNonPHI->getParent();
+  assert(BB->isEHPad() && "not a funclet!");
+
+  if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
+    assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
+           "shouldn't revist catch funclets!");
 
-  if (isa<CatchEndPadInst>(FirstNonPHI)) {
     SmallVector<const CatchPadInst *, 2> Handlers;
-    findCatchPadsForCatchEndPad(&BB, Handlers);
-    const BasicBlock *FirstTryPad = Handlers.front()->getParent();
+    for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
+      auto *CatchPad = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
+      Handlers.push_back(CatchPad);
+    }
     int TryLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
-    FuncInfo.EHPadStateMap[Handlers.front()] = TryLow;
-    for (const BasicBlock *PredBlock : predecessors(FirstTryPad))
-      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
-        calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, TryLow);
+    FuncInfo.EHPadStateMap[CatchSwitch] = TryLow;
+    for (const BasicBlock *PredBlock : predecessors(BB))
+      if ((PredBlock = getEHPadFromPredecessor(PredBlock,
+                                               CatchSwitch->getParentPad())))
+        calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
+                                 TryLow);
     int CatchLow = addUnwindMapEntry(FuncInfo, ParentState, nullptr);
 
     // catchpads are separate funclets in C++ EH due to the way rethrow works.
-    // In SEH, they aren't, so no invokes will unwind to the catchendpad.
-    FuncInfo.EHPadStateMap[FirstNonPHI] = CatchLow;
     int TryHigh = CatchLow - 1;
-    for (const BasicBlock *PredBlock : predecessors(&BB))
-      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
-        calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, CatchLow);
+    for (const auto *CatchPad : Handlers) {
+      FuncInfo.FuncletBaseStateMap[CatchPad] = CatchLow;
+      for (const User *U : CatchPad->users()) {
+        const auto *UserI = cast<Instruction>(U);
+        if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
+          if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
+            calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
+        if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
+          if (getCleanupRetUnwindDest(InnerCleanupPad) ==
+              CatchSwitch->getUnwindDest())
+            calculateCXXStateNumbers(FuncInfo, UserI, CatchLow);
+      }
+    }
     int CatchHigh = FuncInfo.getLastStateNumber();
     addTryBlockMapEntry(FuncInfo, TryLow, TryHigh, CatchHigh, Handlers);
-    DEBUG(dbgs() << "TryLow[" << FirstTryPad->getName() << "]: " << TryLow
-                 << '\n');
-    DEBUG(dbgs() << "TryHigh[" << FirstTryPad->getName() << "]: " << TryHigh
+    DEBUG(dbgs() << "TryLow[" << BB->getName() << "]: " << TryLow << '\n');
+    DEBUG(dbgs() << "TryHigh[" << BB->getName() << "]: " << TryHigh << '\n');
+    DEBUG(dbgs() << "CatchHigh[" << BB->getName() << "]: " << CatchHigh
                  << '\n');
-    DEBUG(dbgs() << "CatchHigh[" << FirstTryPad->getName() << "]: " << CatchHigh
-                 << '\n');
-  } else if (isa<CleanupPadInst>(FirstNonPHI)) {
-    // A cleanup can have multiple exits; don't re-process after the first.
-    if (FuncInfo.EHPadStateMap.count(FirstNonPHI))
+  } else {
+    auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
+
+    // It's possible for a cleanup to be visited twice: it might have multiple
+    // cleanupret instructions.
+    if (FuncInfo.EHPadStateMap.count(CleanupPad))
       return;
-    int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, &BB);
-    FuncInfo.EHPadStateMap[FirstNonPHI] = CleanupState;
+
+    int CleanupState = addUnwindMapEntry(FuncInfo, ParentState, BB);
+    FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
     DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
-                 << BB.getName() << '\n');
-    for (const BasicBlock *PredBlock : predecessors(&BB))
-      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
-        calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, CleanupState);
-  } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(FirstNonPHI)) {
-    // Propagate ParentState to the cleanuppad in case it doesn't have
-    // any cleanuprets.
-    BasicBlock *CleanupBlock = CEPI->getCleanupPad()->getParent();
-    calculateExplicitCXXStateNumbers(FuncInfo, *CleanupBlock, ParentState);
-    // Anything unwinding through CleanupEndPadInst is in ParentState.
-    FuncInfo.EHPadStateMap[FirstNonPHI] = ParentState;
-    for (const BasicBlock *PredBlock : predecessors(&BB))
-      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
-        calculateExplicitCXXStateNumbers(FuncInfo, *PredBlock, ParentState);
-  } else if (isa<TerminatePadInst>(FirstNonPHI)) {
-    report_fatal_error("Not yet implemented!");
-  } else {
-    llvm_unreachable("unexpected EH Pad!");
+                 << BB->getName() << '\n');
+    for (const BasicBlock *PredBlock : predecessors(BB)) {
+      if ((PredBlock = getEHPadFromPredecessor(PredBlock,
+                                               CleanupPad->getParentPad()))) {
+        calculateCXXStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
+                                 CleanupState);
+      }
+    }
+    for (const User *U : CleanupPad->users()) {
+      const auto *UserI = cast<Instruction>(U);
+      if (UserI->isEHPad())
+        report_fatal_error("Cleanup funclets for the MSVC++ personality cannot "
+                           "contain exceptional actions");
+    }
   }
 }
 
@@ -337,94 +316,88 @@ static int addSEHFinally(WinEHFuncInfo &FuncInfo, int ParentState,
   return FuncInfo.SEHUnwindMap.size() - 1;
 }
 
-static void calculateExplicitSEHStateNumbers(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;
+static void calculateSEHStateNumbers(WinEHFuncInfo &FuncInfo,
+                                     const Instruction *FirstNonPHI,
+                                     int ParentState) {
+  const BasicBlock *BB = FirstNonPHI->getParent();
+  assert(BB->isEHPad() && "no a funclet!");
+
+  if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(FirstNonPHI)) {
+    assert(FuncInfo.EHPadStateMap.count(CatchSwitch) == 0 &&
+           "shouldn't revist catch funclets!");
 
-  if (isa<CatchEndPadInst>(FirstNonPHI)) {
     // Extract the filter function and the __except basic block and create a
     // state for them.
-    SmallVector<const CatchPadInst *, 1> Handlers;
-    findCatchPadsForCatchEndPad(&BB, Handlers);
-    assert(Handlers.size() == 1 &&
+    assert(CatchSwitch->getNumHandlers() == 1 &&
            "SEH doesn't have multiple handlers per __try");
-    const CatchPadInst *CPI = Handlers.front();
-    const BasicBlock *CatchPadBB = CPI->getParent();
+    const auto *CatchPad =
+        cast<CatchPadInst>((*CatchSwitch->handler_begin())->getFirstNonPHI());
+    const BasicBlock *CatchPadBB = CatchPad->getParent();
     const Constant *FilterOrNull =
-        cast<Constant>(CPI->getArgOperand(0)->stripPointerCasts());
+        cast<Constant>(CatchPad->getArgOperand(0)->stripPointerCasts());
     const Function *Filter = dyn_cast<Function>(FilterOrNull);
     assert((Filter || FilterOrNull->isNullValue()) &&
            "unexpected filter value");
     int TryState = addSEHExcept(FuncInfo, ParentState, Filter, CatchPadBB);
 
     // Everything in the __try block uses TryState as its parent state.
-    FuncInfo.EHPadStateMap[CPI] = TryState;
+    FuncInfo.EHPadStateMap[CatchSwitch] = TryState;
     DEBUG(dbgs() << "Assigning state #" << TryState << " to BB "
                  << CatchPadBB->getName() << '\n');
-    for (const BasicBlock *PredBlock : predecessors(CatchPadBB))
-      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
-        calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, TryState);
+    for (const BasicBlock *PredBlock : predecessors(BB))
+      if ((PredBlock = getEHPadFromPredecessor(PredBlock,
+                                               CatchSwitch->getParentPad())))
+        calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
+                                 TryState);
 
     // Everything in the __except block unwinds to ParentState, just like code
     // outside the __try.
-    FuncInfo.EHPadStateMap[FirstNonPHI] = ParentState;
-    DEBUG(dbgs() << "Assigning state #" << ParentState << " to BB "
-                 << BB.getName() << '\n');
-    for (const BasicBlock *PredBlock : predecessors(&BB))
-      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
-        calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, ParentState);
-  } else if (isa<CleanupPadInst>(FirstNonPHI)) {
-    // A cleanup can have multiple exits; don't re-process after the first.
-    if (FuncInfo.EHPadStateMap.count(FirstNonPHI))
+    for (const User *U : CatchPad->users()) {
+      const auto *UserI = cast<Instruction>(U);
+      if (auto *InnerCatchSwitch = dyn_cast<CatchSwitchInst>(UserI))
+        if (InnerCatchSwitch->getUnwindDest() == CatchSwitch->getUnwindDest())
+          calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
+      if (auto *InnerCleanupPad = dyn_cast<CleanupPadInst>(UserI))
+        if (getCleanupRetUnwindDest(InnerCleanupPad) ==
+            CatchSwitch->getUnwindDest())
+          calculateSEHStateNumbers(FuncInfo, UserI, ParentState);
+    }
+  } else {
+    auto *CleanupPad = cast<CleanupPadInst>(FirstNonPHI);
+
+    // It's possible for a cleanup to be visited twice: it might have multiple
+    // cleanupret instructions.
+    if (FuncInfo.EHPadStateMap.count(CleanupPad))
       return;
-    int CleanupState = addSEHFinally(FuncInfo, ParentState, &BB);
-    FuncInfo.EHPadStateMap[FirstNonPHI] = CleanupState;
+
+    int CleanupState = addSEHFinally(FuncInfo, ParentState, BB);
+    FuncInfo.EHPadStateMap[CleanupPad] = CleanupState;
     DEBUG(dbgs() << "Assigning state #" << CleanupState << " to BB "
-                 << BB.getName() << '\n');
-    for (const BasicBlock *PredBlock : predecessors(&BB))
-      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
-        calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, CleanupState);
-  } else if (auto *CEPI = dyn_cast<CleanupEndPadInst>(FirstNonPHI)) {
-    // Propagate ParentState to the cleanuppad in case it doesn't have
-    // any cleanuprets.
-    BasicBlock *CleanupBlock = CEPI->getCleanupPad()->getParent();
-    calculateExplicitSEHStateNumbers(FuncInfo, *CleanupBlock, ParentState);
-    // Anything unwinding through CleanupEndPadInst is in ParentState.
-    FuncInfo.EHPadStateMap[FirstNonPHI] = ParentState;
-    DEBUG(dbgs() << "Assigning state #" << ParentState << " to BB "
-                 << BB.getName() << '\n');
-    for (const BasicBlock *PredBlock : predecessors(&BB))
-      if ((PredBlock = getEHPadFromPredecessor(PredBlock)))
-        calculateExplicitSEHStateNumbers(FuncInfo, *PredBlock, ParentState);
-  } else if (isa<TerminatePadInst>(FirstNonPHI)) {
-    report_fatal_error("Not yet implemented!");
-  } else {
-    llvm_unreachable("unexpected EH Pad!");
+                 << BB->getName() << '\n');
+    for (const BasicBlock *PredBlock : predecessors(BB))
+      if ((PredBlock =
+               getEHPadFromPredecessor(PredBlock, CleanupPad->getParentPad())))
+        calculateSEHStateNumbers(FuncInfo, PredBlock->getFirstNonPHI(),
+                                 CleanupState);
+    for (const User *U : CleanupPad->users()) {
+      const auto *UserI = cast<Instruction>(U);
+      if (UserI->isEHPad())
+        report_fatal_error("Cleanup funclets for the SEH personality cannot "
+                           "contain exceptional actions");
+    }
   }
 }
 
-/// Check if the EH Pad unwinds to caller.  Cleanups are a little bit of a
-/// special case because we have to look at the cleanupret instruction that uses
-/// the cleanuppad.
-static bool doesEHPadUnwindToCaller(const Instruction *EHPad) {
-  auto *CPI = dyn_cast<CleanupPadInst>(EHPad);
-  if (!CPI)
-    return EHPad->mayThrow();
-
-  // This cleanup does not return or unwind, so we say it unwinds to caller.
-  if (CPI->use_empty())
-    return true;
-
-  const Instruction *User = CPI->user_back();
-  if (auto *CRI = dyn_cast<CleanupReturnInst>(User))
-    return CRI->unwindsToCaller();
-  return cast<CleanupEndPadInst>(User)->unwindsToCaller();
+static bool isTopLevelPadForMSVC(const Instruction *EHPad) {
+  if (auto *CatchSwitch = dyn_cast<CatchSwitchInst>(EHPad))
+    return isa<ConstantTokenNone>(CatchSwitch->getParentPad()) &&
+           CatchSwitch->unwindsToCaller();
+  if (auto *CleanupPad = dyn_cast<CleanupPadInst>(EHPad))
+    return isa<ConstantTokenNone>(CleanupPad->getParentPad()) &&
+           getCleanupRetUnwindDest(CleanupPad) == nullptr;
+  if (isa<CatchPadInst>(EHPad))
+    return false;
+  llvm_unreachable("unexpected EHPad!");
 }
 
 void llvm::calculateSEHStateNumbers(const Function *Fn,
@@ -434,10 +407,15 @@ void llvm::calculateSEHStateNumbers(const Function *Fn,
     return;
 
   for (const BasicBlock &BB : *Fn) {
-    if (!BB.isEHPad() || !doesEHPadUnwindToCaller(BB.getFirstNonPHI()))
+    if (!BB.isEHPad())
+      continue;
+    const Instruction *FirstNonPHI = BB.getFirstNonPHI();
+    if (!isTopLevelPadForMSVC(FirstNonPHI))
       continue;
-    calculateExplicitSEHStateNumbers(FuncInfo, BB, -1);
+    ::calculateSEHStateNumbers(FuncInfo, FirstNonPHI, -1);
   }
+
+  calculateStateNumbersForInvokes(Fn, FuncInfo);
 }
 
 void llvm::calculateWinCXXEHStateNumbers(const Function *Fn,
@@ -449,13 +427,13 @@ void llvm::calculateWinCXXEHStateNumbers(const Function *Fn,
   for (const BasicBlock &BB : *Fn) {
     if (!BB.isEHPad())
       continue;
-    if (BB.isLandingPad())
-      report_fatal_error("MSVC C++ EH cannot use landingpads");
     const Instruction *FirstNonPHI = BB.getFirstNonPHI();
-    if (!doesEHPadUnwindToCaller(FirstNonPHI))
+    if (!isTopLevelPadForMSVC(FirstNonPHI))
       continue;
-    calculateExplicitCXXStateNumbers(FuncInfo, BB, -1);
+    calculateCXXStateNumbers(FuncInfo, FirstNonPHI, -1);
   }
+
+  calculateStateNumbersForInvokes(Fn, FuncInfo);
 }
 
 static int addClrEHHandler(WinEHFuncInfo &FuncInfo, int ParentState,
@@ -486,7 +464,7 @@ void llvm::calculateClrEHStateNumbers(const Function *Fn,
     if (BB.isLandingPad())
       report_fatal_error("CoreCLR EH cannot use landingpads");
     const Instruction *FirstNonPHI = BB.getFirstNonPHI();
-    if (!doesEHPadUnwindToCaller(FirstNonPHI))
+    if (!isTopLevelPadForMSVC(FirstNonPHI))
       continue;
     // queue this with sentinel parent state -1 to mean unwind to caller.
     Worklist.emplace_back(FirstNonPHI, -1);
@@ -497,16 +475,11 @@ void llvm::calculateClrEHStateNumbers(const Function *Fn,
     int ParentState;
     std::tie(Pad, ParentState) = Worklist.pop_back_val();
 
+    Value *ParentPad;
     int PredState;
-    if (const CleanupEndPadInst *EndPad = dyn_cast<CleanupEndPadInst>(Pad)) {
-      FuncInfo.EHPadStateMap[EndPad] = ParentState;
-      // Queue the cleanuppad, in case it doesn't have a cleanupret.
-      Worklist.emplace_back(EndPad->getCleanupPad(), ParentState);
-      // Preds of the endpad should get the parent state.
-      PredState = ParentState;
-    } else if (const CleanupPadInst *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
+    if (const CleanupPadInst *Cleanup = dyn_cast<CleanupPadInst>(Pad)) {
       // A cleanup can have multiple exits; don't re-process after the first.
-      if (FuncInfo.EHPadStateMap.count(Pad))
+      if (FuncInfo.EHPadStateMap.count(Cleanup))
         continue;
       // CoreCLR personality uses arity to distinguish faults from finallies.
       const BasicBlock *PadBlock = Cleanup->getParent();
@@ -517,1051 +490,75 @@ void llvm::calculateClrEHStateNumbers(const Function *Fn,
           addClrEHHandler(FuncInfo, ParentState, HandlerType, 0, PadBlock);
       FuncInfo.EHPadStateMap[Cleanup] = NewState;
       // Propagate the new state to all preds of the cleanup
+      ParentPad = Cleanup->getParentPad();
       PredState = NewState;
-    } else if (const CatchEndPadInst *EndPad = dyn_cast<CatchEndPadInst>(Pad)) {
-      FuncInfo.EHPadStateMap[EndPad] = ParentState;
-      // Preds of the endpad should get the parent state.
-      PredState = ParentState;
-    } else if (const CatchPadInst *Catch = dyn_cast<CatchPadInst>(Pad)) {
-      const BasicBlock *PadBlock = Catch->getParent();
-      uint32_t TypeToken = static_cast<uint32_t>(
-          cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
-      int NewState = addClrEHHandler(FuncInfo, ParentState,
-                                     ClrHandlerType::Catch, TypeToken, PadBlock);
-      FuncInfo.EHPadStateMap[Catch] = NewState;
-      // Preds of the catch get its state
+    } else if (const auto *CatchSwitch = dyn_cast<CatchSwitchInst>(Pad)) {
+      SmallVector<const CatchPadInst *, 1> Handlers;
+      for (const BasicBlock *CatchPadBB : CatchSwitch->handlers()) {
+        const auto *Catch = cast<CatchPadInst>(CatchPadBB->getFirstNonPHI());
+        Handlers.push_back(Catch);
+      }
+      FuncInfo.EHPadStateMap[CatchSwitch] = ParentState;
+      int NewState = ParentState;
+      for (auto HandlerI = Handlers.rbegin(), HandlerE = Handlers.rend();
+           HandlerI != HandlerE; ++HandlerI) {
+        const CatchPadInst *Catch = *HandlerI;
+        const BasicBlock *PadBlock = Catch->getParent();
+        uint32_t TypeToken = static_cast<uint32_t>(
+            cast<ConstantInt>(Catch->getArgOperand(0))->getZExtValue());
+        NewState = addClrEHHandler(FuncInfo, NewState, ClrHandlerType::Catch,
+                                   TypeToken, PadBlock);
+        FuncInfo.EHPadStateMap[Catch] = NewState;
+      }
+      for (const auto *CatchPad : Handlers) {
+        for (const User *U : CatchPad->users()) {
+          const auto *UserI = cast<Instruction>(U);
+          if (UserI->isEHPad())
+            Worklist.emplace_back(UserI, ParentState);
+        }
+      }
       PredState = NewState;
+      ParentPad = CatchSwitch->getParentPad();
     } else {
       llvm_unreachable("Unexpected EH pad");
     }
 
     // Queue all predecessors with the given state
     for (const BasicBlock *Pred : predecessors(Pad->getParent())) {
-      if ((Pred = getEHPadFromPredecessor(Pred)))
+      if ((Pred = getEHPadFromPredecessor(Pred, ParentPad)))
         Worklist.emplace_back(Pred->getFirstNonPHI(), PredState);
     }
   }
-}
-
-void WinEHPrepare::replaceTerminatePadWithCleanup(Function &F) {
-  if (Personality != EHPersonality::MSVC_CXX)
-    return;
-  for (BasicBlock &BB : F) {
-    Instruction *First = BB.getFirstNonPHI();
-    auto *TPI = dyn_cast<TerminatePadInst>(First);
-    if (!TPI)
-      continue;
-
-    if (TPI->getNumArgOperands() != 1)
-      report_fatal_error(
-          "Expected a unary terminatepad for MSVC C++ personalities!");
-
-    auto *TerminateFn = dyn_cast<Function>(TPI->getArgOperand(0));
-    if (!TerminateFn)
-      report_fatal_error("Function operand expected in terminatepad for MSVC "
-                         "C++ personalities!");
-
-    // Insert the cleanuppad instruction.
-    auto *CPI = CleanupPadInst::Create(
-        BB.getContext(), {}, Twine("terminatepad.for.", BB.getName()), &BB);
-
-    // Insert the call to the terminate instruction.
-    auto *CallTerminate = CallInst::Create(TerminateFn, {}, &BB);
-    CallTerminate->setDoesNotThrow();
-    CallTerminate->setDoesNotReturn();
-    CallTerminate->setCallingConv(TerminateFn->getCallingConv());
-
-    // Insert a new terminator for the cleanuppad using the same successor as
-    // the terminatepad.
-    CleanupReturnInst::Create(CPI, TPI->getUnwindDest(), &BB);
-
-    // Let's remove the terminatepad now that we've inserted the new
-    // instructions.
-    TPI->eraseFromParent();
-  }
-}
-
-static void
-colorFunclets(Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks,
-              std::map<BasicBlock *, std::set<BasicBlock *>> &BlockColors,
-              std::map<BasicBlock *, std::set<BasicBlock *>> &FuncletBlocks) {
-  SmallVector<std::pair<BasicBlock *, BasicBlock *>, 16> Worklist;
-  BasicBlock *EntryBlock = &F.getEntryBlock();
-
-  // Build up the color map, which maps each block to its set of 'colors'.
-  // For any block B, the "colors" of B are the set of funclets F (possibly
-  // including a root "funclet" representing the main function), such that
-  // F will need to directly contain B or a copy of B (where the term "directly
-  // contain" is used to distinguish from being "transitively contained" in
-  // a nested funclet).
-  // Use a CFG walk driven by a worklist of (block, color) pairs.  The "color"
-  // sets attached during this processing to a block which is the entry of some
-  // funclet F is actually the set of F's parents -- i.e. the union of colors
-  // of all predecessors of F's entry.  For all other blocks, the color sets
-  // are as defined above.  A post-pass fixes up the block color map to reflect
-  // the same sense of "color" for funclet entries as for other blocks.
-
-  DEBUG_WITH_TYPE("winehprepare-coloring", dbgs() << "\nColoring funclets for "
-                                                  << F.getName() << "\n");
-
-  Worklist.push_back({EntryBlock, EntryBlock});
-
-  while (!Worklist.empty()) {
-    BasicBlock *Visiting;
-    BasicBlock *Color;
-    std::tie(Visiting, Color) = Worklist.pop_back_val();
-    DEBUG_WITH_TYPE("winehprepare-coloring",
-                    dbgs() << "Visiting " << Visiting->getName() << ", "
-                           << Color->getName() << "\n");
-    Instruction *VisitingHead = Visiting->getFirstNonPHI();
-    if (VisitingHead->isEHPad() && !isa<CatchEndPadInst>(VisitingHead) &&
-        !isa<CleanupEndPadInst>(VisitingHead)) {
-      // Mark this as a funclet head as a member of itself.
-      FuncletBlocks[Visiting].insert(Visiting);
-      // Queue exits (i.e. successors of rets/endpads) with the parent color.
-      // Skip any exits that are catchendpads, since the parent color must then
-      // represent one of the catches chained to that catchendpad, but the
-      // catchendpad should get the color of the common parent of all its
-      // chained catches (i.e. the grandparent color of the current pad).
-      // We don't need to worry abou catchendpads going unvisited, since the
-      // catches chained to them must have unwind edges to them by which we will
-      // visit them.
-      for (User *U : VisitingHead->users()) {
-        if (auto *Exit = dyn_cast<TerminatorInst>(U)) {
-          for (BasicBlock *Succ : successors(Exit->getParent()))
-            if (!isa<CatchEndPadInst>(*Succ->getFirstNonPHI()))
-              if (BlockColors[Succ].insert(Color).second) {
-                DEBUG_WITH_TYPE("winehprepare-coloring",
-                                dbgs() << "  Assigned color \'"
-                                       << Color->getName() << "\' to block \'"
-                                       << Succ->getName() << "\'.\n");
-                Worklist.push_back({Succ, Color});
-              }
-        }
-      }
-      // Handle CatchPad specially since its successors need different colors.
-      if (CatchPadInst *CatchPad = dyn_cast<CatchPadInst>(VisitingHead)) {
-        // Visit the normal successor with the color of the new EH pad, and
-        // visit the unwind successor with the color of the parent.
-        BasicBlock *NormalSucc = CatchPad->getNormalDest();
-        if (BlockColors[NormalSucc].insert(Visiting).second) {
-          DEBUG_WITH_TYPE("winehprepare-coloring",
-                          dbgs() << "  Assigned color \'" << Visiting->getName()
-                                 << "\' to block \'" << NormalSucc->getName()
-                                 << "\'.\n");
-          Worklist.push_back({NormalSucc, Visiting});
-        }
-        BasicBlock *UnwindSucc = CatchPad->getUnwindDest();
-        if (BlockColors[UnwindSucc].insert(Color).second) {
-          DEBUG_WITH_TYPE("winehprepare-coloring",
-                          dbgs() << "  Assigned color \'" << Color->getName()
-                                 << "\' to block \'" << UnwindSucc->getName()
-                                 << "\'.\n");
-          Worklist.push_back({UnwindSucc, Color});
-        }
-        continue;
-      }
-      // Switch color to the current node, except for terminate pads which
-      // have no bodies and only unwind successors and so need their successors
-      // visited with the color of the parent.
-      if (!isa<TerminatePadInst>(VisitingHead))
-        Color = Visiting;
-    } else {
-      // Note that this is a member of the given color.
-      FuncletBlocks[Color].insert(Visiting);
-    }
-
-    TerminatorInst *Terminator = Visiting->getTerminator();
-    if (isa<CleanupReturnInst>(Terminator) ||
-        isa<CatchReturnInst>(Terminator) ||
-        isa<CleanupEndPadInst>(Terminator)) {
-      // These blocks' successors have already been queued with the parent
-      // color.
-      continue;
-    }
-    for (BasicBlock *Succ : successors(Visiting)) {
-      if (isa<CatchEndPadInst>(Succ->getFirstNonPHI())) {
-        // The catchendpad needs to be visited with the parent's color, not
-        // the current color.  This will happen in the code above that visits
-        // any catchpad unwind successor with the parent color, so we can
-        // safely skip this successor here.
-        continue;
-      }
-      if (BlockColors[Succ].insert(Color).second) {
-        DEBUG_WITH_TYPE("winehprepare-coloring",
-                        dbgs() << "  Assigned color \'" << Color->getName()
-                               << "\' to block \'" << Succ->getName()
-                               << "\'.\n");
-        Worklist.push_back({Succ, Color});
-      }
-    }
-  }
-}
-
-static BasicBlock *getEndPadForCatch(CatchPadInst *Catch) {
-  // The catch may have sibling catches.  Follow the unwind chain until we get
-  // to the catchendpad.
-  BasicBlock *NextUnwindDest = Catch->getUnwindDest();
-  auto *UnwindTerminator = NextUnwindDest->getTerminator();
-  while (auto *NextCatch = dyn_cast<CatchPadInst>(UnwindTerminator)) {
-    NextUnwindDest = NextCatch->getUnwindDest();
-    UnwindTerminator = NextUnwindDest->getTerminator();
-  }
-  // The last catch in the chain must unwind to a catchendpad.
-  assert(isa<CatchEndPadInst>(UnwindTerminator));
-  return NextUnwindDest;
-}
-
-static void updateClonedEHPadUnwindToParent(
-    BasicBlock *UnwindDest, BasicBlock *OrigBlock, BasicBlock *CloneBlock,
-    std::vector<BasicBlock *> &OrigParents, BasicBlock *CloneParent) {
-  auto updateUnwindTerminator = [](BasicBlock *BB) {
-    auto *Terminator = BB->getTerminator();
-    if (isa<CatchEndPadInst>(Terminator) ||
-        isa<CleanupEndPadInst>(Terminator)) {
-      removeUnwindEdge(BB);
-    } else {
-      // If the block we're updating has a cleanupendpad or cleanupret
-      // terminator, we just want to replace that terminator with an
-      // unreachable instruction.
-      assert(isa<CleanupEndPadInst>(Terminator) ||
-             isa<CleanupReturnInst>(Terminator));
-      // Loop over all of the successors, removing the block's entry from any
-      // PHI nodes.
-      for (succ_iterator SI = succ_begin(BB), SE = succ_end(BB); SI != SE; ++SI)
-        (*SI)->removePredecessor(BB);
-      // Remove the terminator and replace it with an unreachable instruction.
-      BB->getTerminator()->eraseFromParent();
-      new UnreachableInst(BB->getContext(), BB);
-    }
-  };
-
-  assert(UnwindDest->isEHPad());
-  // There are many places to which this EH terminator can unwind and each has
-  // slightly different rules for whether or not it fits with the given
-  // location.
-  auto *EHPadInst = UnwindDest->getFirstNonPHI();
-  if (auto *CEP = dyn_cast<CatchEndPadInst>(EHPadInst)) {
-    auto *CloneParentCatch =
-        dyn_cast<CatchPadInst>(CloneParent->getFirstNonPHI());
-    if (!CloneParentCatch ||
-        getEndPadForCatch(CloneParentCatch) != UnwindDest) {
-      DEBUG_WITH_TYPE(
-          "winehprepare-coloring",
-          dbgs() << "      removing unwind destination of clone block \'"
-                 << CloneBlock->getName() << "\'.\n");
-      updateUnwindTerminator(CloneBlock);
-    }
-    // It's possible that the catch end pad is a legal match for both the clone
-    // and the original, so they must be checked separately.  If the original
-    // funclet will still have multiple parents after the current clone parent
-    // is removed, we'll leave its unwind terminator until later.
-    assert(OrigParents.size() >= 2);
-    if (OrigParents.size() != 2)
-      return;
-
-    // If the original funclet will have a single parent after the clone parent
-    // is removed, check that parent's unwind destination.
-    assert(OrigParents.front() == CloneParent ||
-           OrigParents.back() == CloneParent);
-    BasicBlock *OrigParent;
-    if (OrigParents.front() == CloneParent)
-      OrigParent = OrigParents.back();
-    else
-      OrigParent = OrigParents.front();
-
-    auto *OrigParentCatch =
-        dyn_cast<CatchPadInst>(OrigParent->getFirstNonPHI());
-    if (!OrigParentCatch || getEndPadForCatch(OrigParentCatch) != UnwindDest) {
-      DEBUG_WITH_TYPE(
-          "winehprepare-coloring",
-          dbgs() << "      removing unwind destination of original block \'"
-                 << OrigBlock << "\'.\n");
-      updateUnwindTerminator(OrigBlock);
-    }
-  } else if (auto *CleanupEnd = dyn_cast<CleanupEndPadInst>(EHPadInst)) {
-    // If the EH terminator unwinds to a cleanupendpad, that cleanupendpad
-    // must be ending a cleanuppad of either our clone parent or one
-    // one of the parents of the original funclet.
-    auto *CloneParentCP =
-        dyn_cast<CleanupPadInst>(CloneParent->getFirstNonPHI());
-    auto *EndedCP = CleanupEnd->getCleanupPad();
-    if (EndedCP == CloneParentCP) {
-      // If it is ending the cleanuppad of our cloned parent, then we
-      // want to remove the unwind destination of the EH terminator that
-      // we associated with the original funclet.
-      assert(isa<CatchEndPadInst>(OrigBlock->getFirstNonPHI()));
-      DEBUG_WITH_TYPE(
-          "winehprepare-coloring",
-          dbgs() << "      removing unwind destination of original block \'"
-                 << OrigBlock->getName() << "\'.\n");
-      updateUnwindTerminator(OrigBlock);
-    } else {
-      // If it isn't ending the cleanuppad of our clone parent, then we
-      // want to remove the unwind destination of the EH terminator that
-      // associated with our cloned funclet.
-      assert(isa<CatchEndPadInst>(CloneBlock->getFirstNonPHI()));
-      DEBUG_WITH_TYPE(
-          "winehprepare-coloring",
-          dbgs() << "      removing unwind destination of clone block \'"
-                 << CloneBlock->getName() << "\'.\n");
-      updateUnwindTerminator(CloneBlock);
-    }
-  } else {
-    // If the EH terminator unwinds to a catchpad, cleanuppad or
-    // terminatepad that EH pad must be a sibling of the funclet we're
-    // cloning.  We'll clone it later and update one of the catchendpad
-    // instrunctions that unwinds to it at that time.
-    assert(isa<CatchPadInst>(EHPadInst) || isa<CleanupPadInst>(EHPadInst) ||
-           isa<TerminatePadInst>(EHPadInst));
-  }
-}
-
-// If the terminator is a catchpad, we must also clone the catchendpad to which
-// it unwinds and add this to the clone parent's block list.  The catchendpad
-// unwinds to either its caller, a sibling EH pad, a cleanup end pad in its
-// parent funclet or a catch end pad in its grandparent funclet (which must be
-// coupled with the parent funclet).  If it has no unwind destination
-// (i.e. unwind to caller), there is nothing to be done. If the unwind
-// destination is a sibling EH pad, we will update the terminators later (in
-// resolveFuncletAncestryForPath).  If it unwinds to a cleanup end pad or a
-// catch end pad and this end pad corresponds to the clone parent, we will
-// remove the unwind destination in the original catchendpad. If it unwinds to
-// a cleanup end pad or a catch end pad that does not correspond to the clone
-// parent, we will remove the unwind destination in the cloned catchendpad.
-static void updateCatchTerminators(
-    Function &F, CatchPadInst *OrigCatch, CatchPadInst *CloneCatch,
-    std::vector<BasicBlock *> &OrigParents, BasicBlock *CloneParent,
-    ValueToValueMapTy &VMap,
-    std::map<BasicBlock *, std::set<BasicBlock *>> &BlockColors,
-    std::map<BasicBlock *, std::set<BasicBlock *>> &FuncletBlocks) {
-  // If we're cloning a catch pad that unwinds to a catchendpad, we also
-  // need to clone the catchendpad.  The coloring algorithm associates
-  // the catchendpad block with the funclet's parent, so we have some work
-  // to do here to figure out whether the original belongs to the clone
-  // parent or one of the original funclets other parents (it might have
-  // more than one at this point).  In either case, we might also need to
-  // remove the unwind edge if the catchendpad doesn't unwind to a block
-  // in the right grandparent funclet.
-  Instruction *I = CloneCatch->getUnwindDest()->getFirstNonPHI();
-  if (auto *CEP = dyn_cast<CatchEndPadInst>(I)) {
-    assert(BlockColors[CEP->getParent()].size() == 1);
-    BasicBlock *CEPFunclet = *(BlockColors[CEP->getParent()].begin());
-    BasicBlock *CEPCloneParent = nullptr;
-    CatchPadInst *PredCatch = nullptr;
-    if (CEPFunclet == CloneParent) {
-      // The catchendpad is in the clone parent, so we need to clone it
-      // and associate the clone with the original funclet's parent.  If
-      // the original funclet had multiple parents, we'll add it to the
-      // first parent that isn't the clone parent.  The logic in
-      // updateClonedEHPadUnwindToParent() will only remove the unwind edge
-      // if there is only one parent other than the clone parent, so we don't
-      // need to verify the ancestry.  The catchendpad will eventually be
-      // cloned into the correct parent and all invalid unwind edges will be
-      // removed.
-      for (auto *Parent : OrigParents) {
-        if (Parent != CloneParent) {
-          CEPCloneParent = Parent;
-          break;
-        }
-      }
-      PredCatch = OrigCatch;
-    } else {
-      CEPCloneParent = CloneParent;
-      PredCatch = CloneCatch;
-    }
-    assert(CEPCloneParent && PredCatch);
-    DEBUG_WITH_TYPE("winehprepare-coloring",
-                    dbgs() << "  Cloning catchendpad \'"
-                           << CEP->getParent()->getName() << "\' for funclet \'"
-                           << CEPCloneParent->getName() << "\'.\n");
-    BasicBlock *ClonedCEP = CloneBasicBlock(
-        CEP->getParent(), VMap, Twine(".from.", CEPCloneParent->getName()));
-    // Insert the clone immediately after the original to ensure determinism
-    // and to keep the same relative ordering of any funclet's blocks.
-    ClonedCEP->insertInto(&F, CEP->getParent()->getNextNode());
-    PredCatch->setUnwindDest(ClonedCEP);
-    FuncletBlocks[CEPCloneParent].insert(ClonedCEP);
-    BlockColors[ClonedCEP].insert(CEPCloneParent);
-    DEBUG_WITH_TYPE("winehprepare-coloring",
-                    dbgs() << "    Assigning color \'"
-                           << CEPCloneParent->getName() << "\' to block \'"
-                           << ClonedCEP->getName() << "\'.\n");
-    auto *ClonedCEPInst = cast<CatchEndPadInst>(ClonedCEP->getTerminator());
-    if (auto *Dest = ClonedCEPInst->getUnwindDest())
-      updateClonedEHPadUnwindToParent(Dest, OrigCatch->getUnwindDest(),
-                                      CloneCatch->getUnwindDest(), OrigParents,
-                                      CloneParent);
-  }
-}
-
-// While we are cloning a funclet because it has multiple parents, we will call
-// this routine to update the terminators for the original and cloned copies
-// of each basic block.  All blocks in the funclet have been clone by this time.
-// OrigBlock and CloneBlock will be identical except for their block label.
-//
-// If the terminator is a catchpad, we must also clone the catchendpad to which
-// it unwinds and in most cases update either the original catchendpad or the
-// clone.  See the updateCatchTerminators() helper routine for details.
-//
-// If the terminator is a catchret its successor is a block in its parent
-// funclet.  If the instruction returns to a block in the parent for which the
-// cloned funclet was created, the terminator in the original block must be
-// replaced by an unreachable instruction.  Otherwise the terminator in the
-// clone block must be replaced by an unreachable instruction.
-//
-// If the terminator is a cleanupret or cleanupendpad it either unwinds to
-// caller or unwinds to a sibling EH pad, a cleanup end pad in its parent
-// funclet or a catch end pad in its grandparent funclet (which must be
-// coupled with the parent funclet).  If it unwinds to caller there is
-// nothing to be done. If the unwind destination is a sibling EH pad, we will
-// update the terminators later (in resolveFuncletAncestryForPath).  If it
-// unwinds to a cleanup end pad or a catch end pad and this end pad corresponds
-// to the clone parent, we will replace the terminator in the original block
-// with an unreachable instruction. If it unwinds to a cleanup end pad or a
-// catch end pad that does not correspond to the clone parent, we will replace
-// the terminator in the clone block with an unreachable instruction.
-//
-// If the terminator is an invoke instruction, it unwinds either to a child
-// EH pad, a cleanup end pad in the current funclet, or a catch end pad in a
-// parent funclet (which ends either the current catch pad or a sibling
-// catch pad).  If it unwinds to a child EH pad, the child will have multiple
-// parents after this funclet is cloned and this case will be handled later in
-// the resolveFuncletAncestryForPath processing.  If it unwinds to a
-// cleanup end pad in the current funclet, the instruction remapping during
-// the cloning process should have already mapped the unwind destination to
-// the cloned copy of the cleanup end pad.  If it unwinds to a catch end pad
-// there are two possibilities: either the catch end pad is the unwind
-// destination for the catch pad we are currently cloning or it is the unwind
-// destination for a sibling catch pad.  If it it the unwind destination of the
-// catch pad we are cloning, we need to update the cloned invoke instruction
-// to unwind to the cloned catch end pad.  Otherwise, we will handle this
-// later (in resolveFuncletAncestryForPath).
-void WinEHPrepare::updateTerminatorsAfterFuncletClone(
-    Function &F, BasicBlock *OrigFunclet, BasicBlock *CloneFunclet,
-    BasicBlock *OrigBlock, BasicBlock *CloneBlock, BasicBlock *CloneParent,
-    ValueToValueMapTy &VMap, std::map<BasicBlock *, BasicBlock *> &Orig2Clone) {
-  // If the cloned block doesn't have an exceptional terminator, there is
-  // nothing to be done here.
-  TerminatorInst *CloneTerminator = CloneBlock->getTerminator();
-  if (!CloneTerminator->isExceptional())
-    return;
-
-  if (auto *CloneCatch = dyn_cast<CatchPadInst>(CloneTerminator)) {
-    // A cloned catch pad has a lot of wrinkles, so we'll call a helper function
-    // to update this case.
-    auto *OrigCatch = cast<CatchPadInst>(OrigBlock->getTerminator());
-    updateCatchTerminators(F, OrigCatch, CloneCatch,
-                           FuncletParents[OrigFunclet], CloneParent, VMap,
-                           BlockColors, FuncletBlocks);
-  } else if (auto *CRI = dyn_cast<CatchReturnInst>(CloneTerminator)) {
-    if (FuncletBlocks[CloneParent].count(CRI->getSuccessor())) {
-      BasicBlock *OrigParent;
-      // The original funclet may have more than two parents, but that's OK.
-      // We just need to remap the original catchret to any of the parents.
-      // All of the parents should have an entry in the EstrangedBlocks map
-      // if any of them do.
-      if (FuncletParents[OrigFunclet].front() == CloneParent)
-        OrigParent = FuncletParents[OrigFunclet].back();
-      else
-        OrigParent = FuncletParents[OrigFunclet].front();
-      for (succ_iterator SI = succ_begin(OrigBlock), SE = succ_end(OrigBlock);
-           SI != SE; ++SI)
-        (*SI)->removePredecessor(OrigBlock);
-      BasicBlock *LostBlock = EstrangedBlocks[OrigParent][CRI->getSuccessor()];
-      auto *OrigCatchRet = cast<CatchReturnInst>(OrigBlock->getTerminator());
-      if (LostBlock) {
-        OrigCatchRet->setSuccessor(LostBlock);
-      } else {
-        OrigCatchRet->eraseFromParent();
-        new UnreachableInst(OrigBlock->getContext(), OrigBlock);
-      }
-    } else {
-      for (succ_iterator SI = succ_begin(CloneBlock), SE = succ_end(CloneBlock);
-           SI != SE; ++SI)
-        (*SI)->removePredecessor(CloneBlock);
-      BasicBlock *LostBlock = EstrangedBlocks[CloneParent][CRI->getSuccessor()];
-      if (LostBlock) {
-        CRI->setSuccessor(LostBlock);
-      } else {
-        CRI->eraseFromParent();
-        new UnreachableInst(CloneBlock->getContext(), CloneBlock);
-      }
-    }
-  } else if (isa<CleanupReturnInst>(CloneTerminator) ||
-             isa<CleanupEndPadInst>(CloneTerminator)) {
-    BasicBlock *UnwindDest = nullptr;
-
-    // A cleanup pad can unwind through either a cleanupret or a cleanupendpad
-    // but both are handled the same way.
-    if (auto *CRI = dyn_cast<CleanupReturnInst>(CloneTerminator))
-      UnwindDest = CRI->getUnwindDest();
-    else if (auto *CEI = dyn_cast<CleanupEndPadInst>(CloneTerminator))
-      UnwindDest = CEI->getUnwindDest();
-
-    // If the instruction has no local unwind destination, there is nothing
-    // to be done.
-    if (!UnwindDest)
-      return;
-
-    // The unwind destination may be a sibling EH pad, a catchendpad in
-    // a grandparent funclet (ending a catchpad in the parent) or a cleanup
-    // cleanupendpad in the parent.  Call a helper routine to diagnose this
-    // and remove either the clone or original terminator as needed.
-    updateClonedEHPadUnwindToParent(UnwindDest, OrigBlock, CloneBlock,
-                                    FuncletParents[OrigFunclet], CloneParent);
-  } else if (auto *II = dyn_cast<InvokeInst>(CloneTerminator)) {
-    BasicBlock *UnwindDest = II->getUnwindDest();
-    assert(UnwindDest && "Invoke unwinds to a null destination.");
-    assert(UnwindDest->isEHPad() && "Invoke does not unwind to an EH pad.");
-    auto *EHPadInst = UnwindDest->getFirstNonPHI();
-    if (isa<CleanupEndPadInst>(EHPadInst)) {
-      // An invoke that unwinds to a cleanup end pad must be in a cleanup pad.
-      assert(isa<CleanupPadInst>(CloneFunclet->getFirstNonPHI()) &&
-             "Unwinding to cleanup end pad from a non cleanup pad funclet.");
-      // The funclet cloning should have remapped the destination to the cloned
-      // cleanup end pad.
-      assert(FuncletBlocks[CloneFunclet].count(UnwindDest) &&
-             "Unwind destination for invoke was not updated during cloning.");
-    } else if (auto *CEP = dyn_cast<CatchEndPadInst>(EHPadInst)) {
-      auto *OrigCatch = cast<CatchPadInst>(OrigFunclet->getFirstNonPHI());
-      auto *CloneCatch = cast<CatchPadInst>(CloneFunclet->getFirstNonPHI());
-      if (OrigCatch->getUnwindDest() == UnwindDest) {
-        // If the invoke unwinds to a catch end pad that is the unwind
-        // destination for the original catch pad, the cloned invoke should
-        // unwind to the cloned catch end pad.
-        II->setUnwindDest(CloneCatch->getUnwindDest());
-      } else if (CloneCatch->getUnwindDest() == UnwindDest) {
-        // If the invoke unwinds to a catch end pad that is the unwind
-        // destination for the clone catch pad, the original invoke should
-        // unwind to the unwind destination of the original catch pad.
-        // This happens when the catch end pad is matched to the clone
-        // parent when the catchpad instruction is cloned and the original
-        // invoke instruction unwinds to the original catch end pad (which
-        // is now the unwind destination of the cloned catch pad).
-        auto *OrigInvoke = cast<InvokeInst>(OrigBlock->getTerminator());
-        OrigInvoke->setUnwindDest(OrigCatch->getUnwindDest());
-      } else {
-        // If the invoke unwinds to a catch end pad that is not the unwind
-        // destination for the original catch pad, it must be the unwind
-        // destination for a sibling catch end pad.  We'll handle that case
-        // later.
-        assert((getEndPadForCatch(OrigCatch) == UnwindDest ||
-                getEndPadForCatch(CloneCatch) == UnwindDest) &&
-               "Invoke within catch pad unwinds to an invalid catch end pad.");
-      }
-    }
-  }
-}
-
-// Clones all blocks used by the specified funclet to avoid the funclet having
-// multiple parent funclets.  All terminators in the parent that unwind to the
-// original funclet are remapped to unwind to the clone.  Any terminator in the
-// original funclet which returned to this parent is converted to an unreachable
-// instruction. Likewise, any terminator in the cloned funclet which returns to
-// a parent funclet other than the specified parent is converted to an
-// unreachable instruction.
-BasicBlock *WinEHPrepare::cloneFuncletForParent(Function &F,
-                                                BasicBlock *FuncletEntry,
-                                                BasicBlock *Parent) {
-  std::set<BasicBlock *> &BlocksInFunclet = FuncletBlocks[FuncletEntry];
-
-  DEBUG_WITH_TYPE("winehprepare-coloring",
-                  dbgs() << "Cloning funclet \'" << FuncletEntry->getName()
-                         << "\' for parent \'" << Parent->getName() << "\'.\n");
-
-  std::map<BasicBlock *, BasicBlock *> Orig2Clone;
-  ValueToValueMapTy VMap;
-  for (BasicBlock *BB : BlocksInFunclet) {
-    // Create a new basic block and copy instructions into it.
-    BasicBlock *CBB =
-        CloneBasicBlock(BB, VMap, Twine(".from.", Parent->getName()));
-
-    // Insert the clone immediately after the original to ensure determinism
-    // and to keep the same relative ordering of any funclet's blocks.
-    CBB->insertInto(&F, BB->getNextNode());
-
-    // Add basic block mapping.
-    VMap[BB] = CBB;
-
-    // Record delta operations that we need to perform to our color mappings.
-    Orig2Clone[BB] = CBB;
-  } // end for (BasicBlock *BB : BlocksInFunclet)
-
-  BasicBlock *ClonedFunclet = Orig2Clone[FuncletEntry];
-  assert(ClonedFunclet);
-
-  // Set the coloring for the blocks we just cloned.
-  std::set<BasicBlock *> &ClonedBlocks = FuncletBlocks[ClonedFunclet];
-  for (auto &BBMapping : Orig2Clone) {
-    BasicBlock *NewBlock = BBMapping.second;
-    ClonedBlocks.insert(NewBlock);
-    BlockColors[NewBlock].insert(ClonedFunclet);
-
-    DEBUG_WITH_TYPE("winehprepare-coloring",
-                    dbgs() << "  Assigning color \'" << ClonedFunclet->getName()
-                           << "\' to block \'" << NewBlock->getName()
-                           << "\'.\n");
-
-    // Use the VMap to remap the instructions in this cloned block.
-    for (Instruction &I : *NewBlock)
-      RemapInstruction(&I, VMap, RF_IgnoreMissingEntries);
-  }
-
-  // All the cloned blocks have to be colored in the loop above before we can
-  // update the terminators because doing so can require checking the color of
-  // other blocks in the cloned funclet.
-  for (auto &BBMapping : Orig2Clone) {
-    BasicBlock *OldBlock = BBMapping.first;
-    BasicBlock *NewBlock = BBMapping.second;
-
-    // Update the terminator, if necessary, in both the original block and the
-    // cloned so that the original funclet never returns to a block in the
-    // clone parent and the clone funclet never returns to a block in any other
-    // of the original funclet's parents.
-    updateTerminatorsAfterFuncletClone(F, FuncletEntry, ClonedFunclet, OldBlock,
-                                       NewBlock, Parent, VMap, Orig2Clone);
-
-    // Check to see if the cloned block successor has PHI nodes. If so, we need
-    // to add entries to the PHI nodes for the cloned block now.
-    for (BasicBlock *SuccBB : successors(NewBlock)) {
-      for (Instruction &SuccI : *SuccBB) {
-        auto *SuccPN = dyn_cast<PHINode>(&SuccI);
-        if (!SuccPN)
-          break;
-
-        // Ok, we have a PHI node.  Figure out what the incoming value was for
-        // the OldBlock.
-        int OldBlockIdx = SuccPN->getBasicBlockIndex(OldBlock);
-        if (OldBlockIdx == -1)
-          break;
-        Value *IV = SuccPN->getIncomingValue(OldBlockIdx);
-
-        // Remap the value if necessary.
-        if (auto *Inst = dyn_cast<Instruction>(IV)) {
-          ValueToValueMapTy::iterator I = VMap.find(Inst);
-          if (I != VMap.end())
-            IV = I->second;
-        }
-
-        SuccPN->addIncoming(IV, NewBlock);
-      }
-    }
-  }
-
-  // Erase the clone's parent from the original funclet's parent list.
-  std::vector<BasicBlock *> &Parents = FuncletParents[FuncletEntry];
-  Parents.erase(std::remove(Parents.begin(), Parents.end(), Parent),
-                Parents.end());
-
-  // Store the cloned funclet's parent.
-  assert(std::find(FuncletParents[ClonedFunclet].begin(),
-                   FuncletParents[ClonedFunclet].end(),
-                   Parent) == std::end(FuncletParents[ClonedFunclet]));
-  FuncletParents[ClonedFunclet].push_back(Parent);
-
-  // Copy any children of the original funclet to the clone.  We'll either
-  // clone them too or make that path unreachable when we take the next step
-  // in resolveFuncletAncestryForPath().
-  for (auto *Child : FuncletChildren[FuncletEntry]) {
-    assert(std::find(FuncletChildren[ClonedFunclet].begin(),
-                     FuncletChildren[ClonedFunclet].end(),
-                     Child) == std::end(FuncletChildren[ClonedFunclet]));
-    FuncletChildren[ClonedFunclet].push_back(Child);
-    assert(std::find(FuncletParents[Child].begin(), FuncletParents[Child].end(),
-                     ClonedFunclet) == std::end(FuncletParents[Child]));
-    FuncletParents[Child].push_back(ClonedFunclet);
-  }
-
-  // Find any blocks that unwound to the original funclet entry from the
-  // clone parent block and remap them to the clone.
-  for (auto *U : FuncletEntry->users()) {
-    auto *UT = dyn_cast<TerminatorInst>(U);
-    if (!UT)
-      continue;
-    BasicBlock *UBB = UT->getParent();
-    assert(BlockColors[UBB].size() == 1);
-    BasicBlock *UFunclet = *(BlockColors[UBB].begin());
-    // Funclets shouldn't be able to loop back on themselves.
-    assert(UFunclet != FuncletEntry);
-    // If this instruction unwinds to the original funclet from the clone
-    // parent, remap the terminator so that it unwinds to the clone instead.
-    // We will perform a similar transformation for siblings after all
-    // the siblings have been cloned.
-    if (UFunclet == Parent) {
-      // We're about to break the path from this block to the uncloned funclet
-      // entry, so remove it as a predeccessor to clean up the PHIs.
-      FuncletEntry->removePredecessor(UBB);
-      TerminatorInst *Terminator = UBB->getTerminator();
-      RemapInstruction(Terminator, VMap, RF_IgnoreMissingEntries);
-    }
-  }
-
-  // This asserts a condition that is relied upon inside the loop below,
-  // namely that no predecessors of the original funclet entry block
-  // are also predecessors of the cloned funclet entry block.
-  assert(std::all_of(pred_begin(FuncletEntry), pred_end(FuncletEntry),
-                     [&ClonedFunclet](BasicBlock *Pred) {
-                       return std::find(pred_begin(ClonedFunclet),
-                                        pred_end(ClonedFunclet),
-                                        Pred) == pred_end(ClonedFunclet);
-                     }));
-
-  // Remove any invalid PHI node entries in the cloned funclet.cl
-  std::vector<PHINode *> PHIsToErase;
-  for (Instruction &I : *ClonedFunclet) {
-    auto *PN = dyn_cast<PHINode>(&I);
-    if (!PN)
-      break;
-
-    // Predecessors of the original funclet do not reach the cloned funclet,
-    // but the cloning process assumes they will.  Remove them now.
-    for (auto *Pred : predecessors(FuncletEntry))
-      PN->removeIncomingValue(Pred, false);
-  }
-  for (auto *PN : PHIsToErase)
-    PN->eraseFromParent();
-
-  // Replace the original funclet in the parent's children vector with the
-  // cloned funclet.
-  for (auto &It : FuncletChildren[Parent]) {
-    if (It == FuncletEntry) {
-      It = ClonedFunclet;
-      break;
-    }
-  }
-
-  return ClonedFunclet;
-}
-
-// Removes the unwind edge for any exceptional terminators within the specified
-// parent funclet that previously unwound to the specified child funclet.
-void WinEHPrepare::makeFuncletEdgeUnreachable(BasicBlock *Parent,
-                                              BasicBlock *Child) {
-  for (BasicBlock *BB : FuncletBlocks[Parent]) {
-    TerminatorInst *Terminator = BB->getTerminator();
-    if (!Terminator->isExceptional())
-      continue;
-
-    // Look for terninators that unwind to the child funclet.
-    BasicBlock *UnwindDest = nullptr;
-    if (auto *I = dyn_cast<InvokeInst>(Terminator))
-      UnwindDest = I->getUnwindDest();
-    else if (auto *I = dyn_cast<CatchEndPadInst>(Terminator))
-      UnwindDest = I->getUnwindDest();
-    else if (auto *I = dyn_cast<TerminatePadInst>(Terminator))
-      UnwindDest = I->getUnwindDest();
-    // cleanupendpad, catchret and cleanupret don't represent a parent-to-child
-    // funclet transition, so we don't need to consider them here.
-
-    // If the child funclet is the unwind destination, replace the terminator
-    // with an unreachable instruction.
-    if (UnwindDest == Child)
-      removeUnwindEdge(BB);
-  }
-  // The specified parent is no longer a parent of the specified child.
-  std::vector<BasicBlock *> &Children = FuncletChildren[Parent];
-  Children.erase(std::remove(Children.begin(), Children.end(), Child),
-                 Children.end());
-}
-
-// This routine is called after funclets with multiple parents are cloned for
-// a specific parent.  Here we look for children of the specified funclet that
-// unwind to other children of that funclet and update the unwind destinations
-// to ensure that each sibling is connected to the correct clone of the sibling
-// to which it unwinds.
-static void updateSiblingToSiblingUnwind(
-    BasicBlock *CurFunclet,
-    std::map<BasicBlock *, std::set<BasicBlock *>> &BlockColors,
-    std::map<BasicBlock *, std::set<BasicBlock *>> &FuncletBlocks,
-    std::map<BasicBlock *, std::vector<BasicBlock *>> &FuncletParents,
-    std::map<BasicBlock *, std::vector<BasicBlock *>> &FuncletChildren,
-    std::map<BasicBlock *, BasicBlock *> &Funclet2Orig) {
-  // Remap any bad sibling-to-sibling transitions for funclets that
-  // we just cloned.
-  for (BasicBlock *ChildFunclet : FuncletChildren[CurFunclet]) {
-    bool NeedOrigInvokeRemapping = false;
-    for (auto *BB : FuncletBlocks[ChildFunclet]) {
-      TerminatorInst *Terminator = BB->getTerminator();
-      if (!Terminator->isExceptional())
-        continue;
-
-      // See if this terminator has an unwind destination.
-      // Note that catchendpads are handled when the associated catchpad
-      // is cloned.  They don't fit the pattern we're looking for here.
-      BasicBlock *UnwindDest = nullptr;
-      if (auto *II = dyn_cast<InvokeInst>(Terminator)) {
-        UnwindDest = II->getUnwindDest();
-        assert(UnwindDest && "Invoke unwinds to a null destination.");
-        assert(UnwindDest->isEHPad() && "Invoke does not unwind to an EH pad.");
-        auto *EHPadInst = UnwindDest->getFirstNonPHI();
-        if (auto *CEP = dyn_cast<CatchEndPadInst>(EHPadInst)) {
-          // If the invoke unwind destination is the unwind destination for
-          // the current child catch pad funclet, there is nothing to be done.
-          auto *CurCatch = cast<CatchPadInst>(ChildFunclet->getFirstNonPHI());
-          if (CurCatch->getUnwindDest() == UnwindDest)
-            continue;
-
-          // Otherwise, the invoke unwinds to a catch end pad that is the unwind
-          // destination another catch pad in the unwind chain from either the
-          // current catch pad or one of its clones.  If it is already the
-          // catch end pad at the end unwind chain from the current catch pad,
-          // we'll need to check the invoke instructions in the original funclet
-          // later.  Otherwise, we need to remap this invoke now.
-          BasicBlock *CurCatchEnd = getEndPadForCatch(CurCatch);
-          if (CurCatchEnd == UnwindDest)
-            NeedOrigInvokeRemapping = true;
-          else
-            II->setUnwindDest(CurCatchEnd);
-          continue;
-        }
-        // All other unwind scenarios for the invoke are handled elsewhere.
-        continue;
-      } else if (auto *I = dyn_cast<CatchPadInst>(Terminator)) {
-        UnwindDest = I->getUnwindDest();
-        // The catchendpad is not a sibling destination.  This case should
-        // have been handled in cloneFuncletForParent().
-        if (isa<CatchEndPadInst>(Terminator)) {
-          assert(BlockColors[UnwindDest].size() == 1 &&
-                 "Cloned catchpad unwinds to an pad with multiple parents.");
-          assert(FuncletParents[UnwindDest].front() == CurFunclet &&
-                 "Cloned catchpad unwinds to the wrong parent.");
-          continue;
-        }
-      } else {
-        if (auto *I = dyn_cast<CleanupReturnInst>(Terminator))
-          UnwindDest = I->getUnwindDest();
-        else if (auto *I = dyn_cast<CleanupEndPadInst>(Terminator))
-          UnwindDest = I->getUnwindDest();
-
-        // If the cleanup unwinds to caller, there is nothing to be done.
-        if (!UnwindDest)
-          continue;
-      }
-
-      // If the destination is not a cleanup pad, catch pad or terminate pad
-      // we don't need to handle it here.
-      Instruction *EHPad = UnwindDest->getFirstNonPHI();
-      if (!isa<CleanupPadInst>(EHPad) && !isa<CatchPadInst>(EHPad) &&
-          !isa<TerminatePadInst>(EHPad))
-        continue;
-
-      // If it is one of these, then it is either a sibling of the current
-      // child funclet or a clone of one of those siblings.
-      // If it is a sibling, no action is needed.
-      if (FuncletParents[UnwindDest].size() == 1 &&
-          FuncletParents[UnwindDest].front() == CurFunclet)
-        continue;
-
-      // If the unwind destination is a clone of a sibling, we need to figure
-      // out which sibling it is a clone of and use that sibling as the
-      // unwind destination.
-      BasicBlock *DestOrig = Funclet2Orig[UnwindDest];
-      BasicBlock *TargetSibling = nullptr;
-      for (auto &Mapping : Funclet2Orig) {
-        if (Mapping.second != DestOrig)
-          continue;
-        BasicBlock *MappedFunclet = Mapping.first;
-        if (FuncletParents[MappedFunclet].size() == 1 &&
-            FuncletParents[MappedFunclet].front() == CurFunclet) {
-          TargetSibling = MappedFunclet;
-        }
-      }
-      // If we didn't find the sibling we were looking for then the
-      // unwind destination is not a clone of one of child's siblings.
-      // That's unexpected.
-      assert(TargetSibling && "Funclet unwinds to unexpected destination.");
-
-      // Update the terminator instruction to unwind to the correct sibling.
-      if (auto *I = dyn_cast<CatchPadInst>(Terminator))
-        I->setUnwindDest(TargetSibling);
-      else if (auto *I = dyn_cast<CleanupReturnInst>(Terminator))
-        I->setUnwindDest(TargetSibling);
-      else if (auto *I = dyn_cast<CleanupEndPadInst>(Terminator))
-        I->setUnwindDest(TargetSibling);
-    }
-    if (NeedOrigInvokeRemapping) {
-      // To properly remap invoke instructions that unwind to catch end pads
-      // that are not the unwind destination of the catch pad funclet in which
-      // the invoke appears, we must also look at the uncloned invoke in the
-      // original funclet.  If we saw an invoke that was already properly
-      // unwinding to a sibling's catch end pad, we need to check the invokes
-      // in the original funclet.
-      BasicBlock *OrigFunclet = Funclet2Orig[ChildFunclet];
-      for (auto *BB : FuncletBlocks[OrigFunclet]) {
-        auto *II = dyn_cast<InvokeInst>(BB->getTerminator());
-        if (!II)
-          continue;
-
-        BasicBlock *UnwindDest = II->getUnwindDest();
-        assert(UnwindDest && "Invoke unwinds to a null destination.");
-        assert(UnwindDest->isEHPad() && "Invoke does not unwind to an EH pad.");
-        auto *CEP = dyn_cast<CatchEndPadInst>(UnwindDest->getFirstNonPHI());
-        if (!CEP)
-          continue;
-        // If the invoke unwind destination is the unwind destination for
-        // the original catch pad funclet, there is nothing to be done.
-        auto *OrigCatch = cast<CatchPadInst>(OrigFunclet->getFirstNonPHI());
-        if (OrigCatch->getUnwindDest() == UnwindDest)
-          continue;
-
-        // Otherwise, the invoke unwinds to a catch end pad that is the unwind
-        // destination another catch pad in the unwind chain from either the
-        // current catch pad or one of its clones.  If it is not already the
-        // catch end pad at the end unwind chain from the current catch pad,
-        // we need to remap this invoke now.
-        BasicBlock *OrigCatchEnd = getEndPadForCatch(OrigCatch);
-        if (OrigCatchEnd != UnwindDest)
-          II->setUnwindDest(OrigCatchEnd);
-      }
-    }
-  }
-}
 
-void WinEHPrepare::resolveFuncletAncestry(
-    Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
-  // Most of the time this will be unnecessary.  If the conditions arise that
-  // require this work, this flag will be set.
-  if (!FuncletCloningRequired)
-    return;
-
-  // Funclet2Orig is used to map any cloned funclets back to the original
-  // funclet from which they were cloned.  The map is seeded with the
-  // original funclets mapping to themselves.
-  std::map<BasicBlock *, BasicBlock *> Funclet2Orig;
-  for (auto *Funclet : EntryBlocks)
-    Funclet2Orig[Funclet] = Funclet;
-
-  // Start with the entry funclet and walk the funclet parent-child tree.
-  SmallVector<BasicBlock *, 4> FuncletPath;
-  FuncletPath.push_back(&(F.getEntryBlock()));
-  resolveFuncletAncestryForPath(F, FuncletPath, Funclet2Orig);
+  calculateStateNumbersForInvokes(Fn, FuncInfo);
 }
 
-// Walks the funclet control flow, cloning any funclets that have more than one
-// parent funclet and breaking any cyclic unwind chains so that the path becomes
-// unreachable at the point where a funclet would have unwound to a funclet that
-// was already in the chain.
-void WinEHPrepare::resolveFuncletAncestryForPath(
-    Function &F, SmallVectorImpl<BasicBlock *> &FuncletPath,
-    std::map<BasicBlock *, BasicBlock *> &Funclet2Orig) {
-  bool ClonedAnyChildren = false;
-  BasicBlock *CurFunclet = FuncletPath.back();
-  // Copy the children vector because we might changing it.
-  std::vector<BasicBlock *> Children(FuncletChildren[CurFunclet]);
-  for (BasicBlock *ChildFunclet : Children) {
-    // Don't allow the funclet chain to unwind back on itself.
-    // If this funclet is already in the current funclet chain, make the
-    // path to it through the current funclet unreachable.
-    bool IsCyclic = false;
-    BasicBlock *ChildIdentity = Funclet2Orig[ChildFunclet];
-    for (BasicBlock *Ancestor : FuncletPath) {
-      BasicBlock *AncestorIdentity = Funclet2Orig[Ancestor];
-      if (AncestorIdentity == ChildIdentity) {
-        IsCyclic = true;
-        break;
-      }
-    }
-    // If the unwind chain wraps back on itself, break the chain.
-    if (IsCyclic) {
-      makeFuncletEdgeUnreachable(CurFunclet, ChildFunclet);
-      continue;
-    }
-    // If this child funclet has other parents, clone the entire funclet.
-    if (FuncletParents[ChildFunclet].size() > 1) {
-      ChildFunclet = cloneFuncletForParent(F, ChildFunclet, CurFunclet);
-      Funclet2Orig[ChildFunclet] = ChildIdentity;
-      ClonedAnyChildren = true;
-    }
-    FuncletPath.push_back(ChildFunclet);
-    resolveFuncletAncestryForPath(F, FuncletPath, Funclet2Orig);
-    FuncletPath.pop_back();
-  }
-  // If we didn't clone any children, we can return now.
-  if (!ClonedAnyChildren)
-    return;
-
-  updateSiblingToSiblingUnwind(CurFunclet, BlockColors, FuncletBlocks,
-                               FuncletParents, FuncletChildren, Funclet2Orig);
-}
+void WinEHPrepare::colorFunclets(Function &F) {
+  BlockColors = colorEHFunclets(F);
 
-void WinEHPrepare::colorFunclets(Function &F,
-                                 SmallVectorImpl<BasicBlock *> &EntryBlocks) {
-  ::colorFunclets(F, EntryBlocks, BlockColors, FuncletBlocks);
-
-  // The processing above actually accumulated the parent set for this
-  // funclet into the color set for its entry; use the parent set to
-  // populate the children map, and reset the color set to include just
-  // the funclet itself (no instruction can target a funclet entry except on
-  // that transitions to the child funclet).
-  for (BasicBlock *FuncletEntry : EntryBlocks) {
-    std::set<BasicBlock *> &ColorMapItem = BlockColors[FuncletEntry];
-    // It will be rare for funclets to have multiple parents, but if any
-    // do we need to clone the funclet later to address that.  Here we
-    // set a flag indicating that this case has arisen so that we don't
-    // have to do a lot of checking later to handle the more common case.
-    if (ColorMapItem.size() > 1)
-      FuncletCloningRequired = true;
-    for (BasicBlock *Parent : ColorMapItem) {
-      assert(std::find(FuncletChildren[Parent].begin(),
-                       FuncletChildren[Parent].end(),
-                       FuncletEntry) == std::end(FuncletChildren[Parent]));
-      FuncletChildren[Parent].push_back(FuncletEntry);
-      assert(std::find(FuncletParents[FuncletEntry].begin(),
-                       FuncletParents[FuncletEntry].end(),
-                       Parent) == std::end(FuncletParents[FuncletEntry]));
-      FuncletParents[FuncletEntry].push_back(Parent);
-    }
-    ColorMapItem.clear();
-    ColorMapItem.insert(FuncletEntry);
+  // Invert the map from BB to colors to color to BBs.
+  for (BasicBlock &BB : F) {
+    ColorVector &Colors = BlockColors[&BB];
+    for (BasicBlock *Color : Colors)
+      FuncletBlocks[Color].push_back(&BB);
   }
 }
 
 void llvm::calculateCatchReturnSuccessorColors(const Function *Fn,
                                                WinEHFuncInfo &FuncInfo) {
-  SmallVector<BasicBlock *, 4> EntryBlocks;
-  // colorFunclets needs the set of EntryBlocks, get them using
-  // findFuncletEntryPoints.
-  findFuncletEntryPoints(const_cast<Function &>(*Fn), EntryBlocks);
-
-  std::map<BasicBlock *, std::set<BasicBlock *>> BlockColors;
-  std::map<BasicBlock *, std::set<BasicBlock *>> FuncletBlocks;
-  // Figure out which basic blocks belong to which funclets.
-  colorFunclets(const_cast<Function &>(*Fn), EntryBlocks, BlockColors,
-                FuncletBlocks);
-
-  // The static colorFunclets routine assigns multiple colors to funclet entries
-  // because that information is needed to calculate funclets' parent-child
-  // relationship, but we don't need those relationship here and ultimately the
-  // entry blocks should have the color of the funclet they begin.
-  for (BasicBlock *FuncletEntry : EntryBlocks) {
-    BlockColors[FuncletEntry].clear();
-    BlockColors[FuncletEntry].insert(FuncletEntry);
-  }
-
-  // We need to find the catchret successors.  To do this, we must first find
-  // all the catchpad funclets.
-  for (auto &Funclet : FuncletBlocks) {
-    // Figure out what kind of funclet we are looking at; We only care about
-    // catchpads.
-    BasicBlock *FuncletPadBB = Funclet.first;
-    Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
-    auto *CatchPad = dyn_cast<CatchPadInst>(FirstNonPHI);
-    if (!CatchPad)
+  for (const BasicBlock &BB : *Fn) {
+    const auto *CatchRet = dyn_cast<CatchReturnInst>(BB.getTerminator());
+    if (!CatchRet)
       continue;
-
-    // The users of a catchpad are always catchrets.
-    for (User *Exit : CatchPad->users()) {
-      auto *CatchReturn = dyn_cast<CatchReturnInst>(Exit);
-      if (!CatchReturn)
-        continue;
-      BasicBlock *CatchRetSuccessor = CatchReturn->getSuccessor();
-      std::set<BasicBlock *> &SuccessorColors = BlockColors[CatchRetSuccessor];
-      assert(SuccessorColors.size() == 1 && "Expected BB to be monochrome!");
-      BasicBlock *Color = *SuccessorColors.begin();
-      // Record the catchret successor's funclet membership.
-      FuncInfo.CatchRetSuccessorColorMap[CatchReturn] = Color;
-    }
+    // A 'catchret' returns to the outer scope's color.
+    Value *ParentPad = CatchRet->getParentPad();
+    const BasicBlock *Color;
+    if (isa<ConstantTokenNone>(ParentPad))
+      Color = &Fn->getEntryBlock();
+    else
+      Color = cast<Instruction>(ParentPad)->getParent();
+    // Record the catchret successor's funclet membership.
+    FuncInfo.CatchRetSuccessorColorMap[CatchRet] = Color;
   }
 }
 
@@ -1594,100 +591,28 @@ void WinEHPrepare::demotePHIsOnFunclets(Function &F) {
   }
 }
 
-void WinEHPrepare::demoteUsesBetweenFunclets(Function &F) {
-  // Turn all inter-funclet uses of a Value into loads and stores.
-  for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE;) {
-    BasicBlock *BB = &*FI++;
-    std::set<BasicBlock *> &ColorsForBB = BlockColors[BB];
-    for (BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE;) {
-      Instruction *I = &*BI++;
-      // Funclets are permitted to use static allocas.
-      if (auto *AI = dyn_cast<AllocaInst>(I))
-        if (AI->isStaticAlloca())
-          continue;
-
-      demoteNonlocalUses(I, ColorsForBB, F);
-    }
-  }
-}
-
-void WinEHPrepare::demoteArgumentUses(Function &F) {
-  // Also demote function parameters used in funclets.
-  std::set<BasicBlock *> &ColorsForEntry = BlockColors[&F.getEntryBlock()];
-  for (Argument &Arg : F.args())
-    demoteNonlocalUses(&Arg, ColorsForEntry, F);
-}
-
-void WinEHPrepare::cloneCommonBlocks(
-    Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
+void WinEHPrepare::cloneCommonBlocks(Function &F) {
   // We need to clone all blocks which belong to multiple funclets.  Values are
   // remapped throughout the funclet to propogate both the new instructions
   // *and* the new basic blocks themselves.
-  for (BasicBlock *FuncletPadBB : EntryBlocks) {
-    std::set<BasicBlock *> &BlocksInFunclet = FuncletBlocks[FuncletPadBB];
+  for (auto &Funclets : FuncletBlocks) {
+    BasicBlock *FuncletPadBB = Funclets.first;
+    std::vector<BasicBlock *> &BlocksInFunclet = Funclets.second;
+    Value *FuncletToken;
+    if (FuncletPadBB == &F.getEntryBlock())
+      FuncletToken = ConstantTokenNone::get(F.getContext());
+    else
+      FuncletToken = FuncletPadBB->getFirstNonPHI();
 
-    std::map<BasicBlock *, BasicBlock *> Orig2Clone;
+    std::vector<std::pair<BasicBlock *, BasicBlock *>> Orig2Clone;
     ValueToValueMapTy VMap;
-    for (auto BlockIt = BlocksInFunclet.begin(),
-              BlockEnd = BlocksInFunclet.end();
-         BlockIt != BlockEnd;) {
-      // Increment the iterator inside the loop because we might be removing
-      // blocks from the set.
-      BasicBlock *BB = *BlockIt++;
-      std::set<BasicBlock *> &ColorsForBB = BlockColors[BB];
+    for (BasicBlock *BB : BlocksInFunclet) {
+      ColorVector &ColorsForBB = BlockColors[BB];
       // We don't need to do anything if the block is monochromatic.
       size_t NumColorsForBB = ColorsForBB.size();
       if (NumColorsForBB == 1)
         continue;
 
-      // If this block is a catchendpad, it shouldn't be cloned.
-      // We will only see a catchendpad with multiple colors in the case where
-      // some funclet has multiple parents.  In that case, the color will be
-      // resolved during the resolveFuncletAncestry processing.
-      // For now, find the catchpad that unwinds to this block and assign
-      // that catchpad's first parent to be the color for this block.
-      if (auto *CEP = dyn_cast<CatchEndPadInst>(BB->getFirstNonPHI())) {
-        assert(
-            FuncletCloningRequired &&
-            "Found multi-colored catchendpad with no multi-parent funclets.");
-        BasicBlock *CatchParent = nullptr;
-        // There can only be one catchpad predecessor for a catchendpad.
-        for (BasicBlock *PredBB : predecessors(BB)) {
-          if (isa<CatchPadInst>(PredBB->getTerminator())) {
-            CatchParent = PredBB;
-            break;
-          }
-        }
-        // There must be one catchpad predecessor for a catchendpad.
-        assert(CatchParent && "No catchpad found for catchendpad.");
-
-        // If the catchpad has multiple parents, we'll clone the catchendpad
-        // when we clone the catchpad funclet and insert it into the correct
-        // funclet.  For now, we just select the first parent of the catchpad
-        // and give the catchendpad that color.
-        BasicBlock *CorrectColor = FuncletParents[CatchParent].front();
-        assert(FuncletBlocks[CorrectColor].count(BB));
-        assert(BlockColors[BB].count(CorrectColor));
-
-        // Remove this block from the FuncletBlocks set of any funclet that
-        // isn't the funclet whose color we just selected.
-        for (auto It = BlockColors[BB].begin(), End = BlockColors[BB].end();
-             It != End; ) {
-          // The iterator must be incremented here because we are removing
-          // elements from the set we're walking.
-          auto Temp = It++;
-          BasicBlock *ContainingFunclet = *Temp;
-          if (ContainingFunclet != CorrectColor) {
-            FuncletBlocks[ContainingFunclet].erase(BB);
-            BlockColors[BB].erase(Temp);
-          }
-        }
-
-        // This should leave just one color for BB.
-        assert(BlockColors[BB].size() == 1);
-        continue;
-      }
-
       DEBUG_WITH_TYPE("winehprepare-coloring",
                       dbgs() << "  Cloning block \'" << BB->getName()
                               << "\' for funclet \'" << FuncletPadBB->getName()
@@ -1704,7 +629,7 @@ void WinEHPrepare::cloneCommonBlocks(
       VMap[BB] = CBB;
 
       // Record delta operations that we need to perform to our color mappings.
-      Orig2Clone[BB] = CBB;
+      Orig2Clone.emplace_back(BB, CBB);
     }
 
     // If nothing was cloned, we're done cloning in this funclet.
@@ -1717,55 +642,28 @@ void WinEHPrepare::cloneCommonBlocks(
       BasicBlock *OldBlock = BBMapping.first;
       BasicBlock *NewBlock = BBMapping.second;
 
-      BlocksInFunclet.insert(NewBlock);
-      BlockColors[NewBlock].insert(FuncletPadBB);
+      BlocksInFunclet.push_back(NewBlock);
+      ColorVector &NewColors = BlockColors[NewBlock];
+      assert(NewColors.empty() && "A new block should only have one color!");
+      NewColors.push_back(FuncletPadBB);
 
       DEBUG_WITH_TYPE("winehprepare-coloring",
                       dbgs() << "  Assigned color \'" << FuncletPadBB->getName()
                               << "\' to block \'" << NewBlock->getName()
                               << "\'.\n");
 
-      BlocksInFunclet.erase(OldBlock);
-      BlockColors[OldBlock].erase(FuncletPadBB);
+      BlocksInFunclet.erase(
+          std::remove(BlocksInFunclet.begin(), BlocksInFunclet.end(), OldBlock),
+          BlocksInFunclet.end());
+      ColorVector &OldColors = BlockColors[OldBlock];
+      OldColors.erase(
+          std::remove(OldColors.begin(), OldColors.end(), FuncletPadBB),
+          OldColors.end());
 
       DEBUG_WITH_TYPE("winehprepare-coloring",
                       dbgs() << "  Removed color \'" << FuncletPadBB->getName()
                               << "\' from block \'" << OldBlock->getName()
                               << "\'.\n");
-
-      // If we are cloning a funclet that might share a child funclet with
-      // another funclet, look to see if the cloned block is reached from a
-      // catchret instruction.  If so, save this association so we can retrieve
-      // the possibly orphaned clone when we clone the child funclet.
-      if (FuncletCloningRequired) {
-        for (auto *Pred : predecessors(OldBlock)) {
-          auto *Terminator = Pred->getTerminator();
-          if (!isa<CatchReturnInst>(Terminator))
-            continue;
-          // If this block is reached from a catchret instruction in a funclet
-          // that has multiple parents, it will have a color for each of those
-          // parents.  We just removed the color of one of the parents, but
-          // the cloned block will be unreachable until we clone the child
-          // funclet that contains the catchret instruction.  In that case we
-          // need to create a mapping that will let us find the cloned block
-          // later and associate it with the cloned child funclet.
-          bool BlockWillBeEstranged = false;
-          for (auto *Color : BlockColors[Pred]) {
-            if (FuncletParents[Color].size() > 1) {
-              BlockWillBeEstranged = true;
-              break; // Breaks out of the color loop
-            }
-          }
-          if (BlockWillBeEstranged) {
-            EstrangedBlocks[FuncletPadBB][OldBlock] = NewBlock;
-            DEBUG_WITH_TYPE("winehprepare-coloring",
-                            dbgs() << "  Saved mapping of estranged block \'"
-                                  << NewBlock->getName() << "\' for \'"
-                                  << FuncletPadBB->getName() << "\'.\n");
-            break; // Breaks out of the predecessor loop
-          }
-        }
-      }
     }
 
     // Loop over all of the instructions in this funclet, fixing up operand
@@ -1776,6 +674,69 @@ void WinEHPrepare::cloneCommonBlocks(
         RemapInstruction(&I, VMap,
                          RF_IgnoreMissingEntries | RF_NoModuleLevelChanges);
 
+    // Catchrets targeting cloned blocks need to be updated separately from
+    // the loop above because they are not in the current funclet.
+    SmallVector<CatchReturnInst *, 2> FixupCatchrets;
+    for (auto &BBMapping : Orig2Clone) {
+      BasicBlock *OldBlock = BBMapping.first;
+      BasicBlock *NewBlock = BBMapping.second;
+
+      FixupCatchrets.clear();
+      for (BasicBlock *Pred : predecessors(OldBlock))
+        if (auto *CatchRet = dyn_cast<CatchReturnInst>(Pred->getTerminator()))
+          if (CatchRet->getParentPad() == FuncletToken)
+            FixupCatchrets.push_back(CatchRet);
+
+      for (CatchReturnInst *CatchRet : FixupCatchrets)
+        CatchRet->setSuccessor(NewBlock);
+    }
+
+    auto UpdatePHIOnClonedBlock = [&](PHINode *PN, bool IsForOldBlock) {
+      unsigned NumPreds = PN->getNumIncomingValues();
+      for (unsigned PredIdx = 0, PredEnd = NumPreds; PredIdx != PredEnd;
+           ++PredIdx) {
+        BasicBlock *IncomingBlock = PN->getIncomingBlock(PredIdx);
+        bool EdgeTargetsFunclet;
+        if (auto *CRI =
+                dyn_cast<CatchReturnInst>(IncomingBlock->getTerminator())) {
+          EdgeTargetsFunclet = (CRI->getParentPad() == FuncletToken);
+        } else {
+          ColorVector &IncomingColors = BlockColors[IncomingBlock];
+          assert(!IncomingColors.empty() && "Block not colored!");
+          assert((IncomingColors.size() == 1 ||
+                  llvm::all_of(IncomingColors,
+                               [&](BasicBlock *Color) {
+                                 return Color != FuncletPadBB;
+                               })) &&
+                 "Cloning should leave this funclet's blocks monochromatic");
+          EdgeTargetsFunclet = (IncomingColors.front() == FuncletPadBB);
+        }
+        if (IsForOldBlock != EdgeTargetsFunclet)
+          continue;
+        PN->removeIncomingValue(IncomingBlock, /*DeletePHIIfEmpty=*/false);
+        // Revisit the next entry.
+        --PredIdx;
+        --PredEnd;
+      }
+    };
+
+    for (auto &BBMapping : Orig2Clone) {
+      BasicBlock *OldBlock = BBMapping.first;
+      BasicBlock *NewBlock = BBMapping.second;
+      for (Instruction &OldI : *OldBlock) {
+        auto *OldPN = dyn_cast<PHINode>(&OldI);
+        if (!OldPN)
+          break;
+        UpdatePHIOnClonedBlock(OldPN, /*IsForOldBlock=*/true);
+      }
+      for (Instruction &NewI : *NewBlock) {
+        auto *NewPN = dyn_cast<PHINode>(&NewI);
+        if (!NewPN)
+          break;
+        UpdatePHIOnClonedBlock(NewPN, /*IsForOldBlock=*/false);
+      }
+    }
+
     // Check to see if SuccBB has PHI nodes. If so, we need to add entries to
     // the PHI nodes for NewBB now.
     for (auto &BBMapping : Orig2Clone) {
@@ -1823,7 +784,7 @@ void WinEHPrepare::cloneCommonBlocks(
       for (Use &U : OldI->uses()) {
         Instruction *UserI = cast<Instruction>(U.getUser());
         BasicBlock *UserBB = UserI->getParent();
-        std::set<BasicBlock *> &ColorsForUserBB = BlockColors[UserBB];
+        ColorVector &ColorsForUserBB = BlockColors[UserBB];
         assert(!ColorsForUserBB.empty());
         if (ColorsForUserBB.size() > 1 ||
             *ColorsForUserBB.begin() != FuncletPadBB)
@@ -1849,19 +810,56 @@ void WinEHPrepare::cloneCommonBlocks(
   }
 }
 
-void WinEHPrepare::removeImplausibleTerminators(Function &F) {
+void WinEHPrepare::removeImplausibleInstructions(Function &F) {
   // Remove implausible terminators and replace them with UnreachableInst.
   for (auto &Funclet : FuncletBlocks) {
     BasicBlock *FuncletPadBB = Funclet.first;
-    std::set<BasicBlock *> &BlocksInFunclet = Funclet.second;
+    std::vector<BasicBlock *> &BlocksInFunclet = Funclet.second;
     Instruction *FirstNonPHI = FuncletPadBB->getFirstNonPHI();
-    auto *CatchPad = dyn_cast<CatchPadInst>(FirstNonPHI);
-    auto *CleanupPad = dyn_cast<CleanupPadInst>(FirstNonPHI);
+    auto *FuncletPad = dyn_cast<FuncletPadInst>(FirstNonPHI);
+    auto *CatchPad = dyn_cast_or_null<CatchPadInst>(FuncletPad);
+    auto *CleanupPad = dyn_cast_or_null<CleanupPadInst>(FuncletPad);
 
     for (BasicBlock *BB : BlocksInFunclet) {
+      for (Instruction &I : *BB) {
+        CallSite CS(&I);
+        if (!CS)
+          continue;
+
+        Value *FuncletBundleOperand = nullptr;
+        if (auto BU = CS.getOperandBundle(LLVMContext::OB_funclet))
+          FuncletBundleOperand = BU->Inputs.front();
+
+        if (FuncletBundleOperand == FuncletPad)
+          continue;
+
+        // Skip call sites which are nounwind intrinsics.
+        auto *CalledFn =
+            dyn_cast<Function>(CS.getCalledValue()->stripPointerCasts());
+        if (CalledFn && CalledFn->isIntrinsic() && CS.doesNotThrow())
+          continue;
+
+        // This call site was not part of this funclet, remove it.
+        if (CS.isInvoke()) {
+          // Remove the unwind edge if it was an invoke.
+          removeUnwindEdge(BB);
+          // Get a pointer to the new call.
+          BasicBlock::iterator CallI =
+              std::prev(BB->getTerminator()->getIterator());
+          auto *CI = cast<CallInst>(&*CallI);
+          changeToUnreachable(CI, /*UseLLVMTrap=*/false);
+        } else {
+          changeToUnreachable(&I, /*UseLLVMTrap=*/false);
+        }
+
+        // There are no more instructions in the block (except for unreachable),
+        // we are done.
+        break;
+      }
+
       TerminatorInst *TI = BB->getTerminator();
       // CatchPadInst and CleanupPadInst can't transfer control to a ReturnInst.
-      bool IsUnreachableRet = isa<ReturnInst>(TI) && (CatchPad || CleanupPad);
+      bool IsUnreachableRet = isa<ReturnInst>(TI) && FuncletPad;
       // The token consumed by a CatchReturnInst must match the funclet token.
       bool IsUnreachableCatchret = false;
       if (auto *CRI = dyn_cast<CatchReturnInst>(TI))
@@ -1870,34 +868,17 @@ void WinEHPrepare::removeImplausibleTerminators(Function &F) {
       bool IsUnreachableCleanupret = false;
       if (auto *CRI = dyn_cast<CleanupReturnInst>(TI))
         IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
-      // The token consumed by a CleanupEndPadInst must match the funclet token.
-      bool IsUnreachableCleanupendpad = false;
-      if (auto *CEPI = dyn_cast<CleanupEndPadInst>(TI))
-        IsUnreachableCleanupendpad = CEPI->getCleanupPad() != CleanupPad;
       if (IsUnreachableRet || IsUnreachableCatchret ||
-          IsUnreachableCleanupret || IsUnreachableCleanupendpad) {
-        // Loop through all of our successors and make sure they know that one
-        // of their predecessors is going away.
-        for (BasicBlock *SuccBB : TI->successors())
-          SuccBB->removePredecessor(BB);
-
-        if (IsUnreachableCleanupendpad) {
-          // We can't simply replace a cleanupendpad with unreachable, because
-          // its predecessor edges are EH edges and unreachable is not an EH
-          // pad.  Change all predecessors to the "unwind to caller" form.
-          for (pred_iterator PI = pred_begin(BB), PE = pred_end(BB);
-               PI != PE;) {
-            BasicBlock *Pred = *PI++;
-            removeUnwindEdge(Pred);
-          }
+          IsUnreachableCleanupret) {
+        changeToUnreachable(TI, /*UseLLVMTrap=*/false);
+      } else if (isa<InvokeInst>(TI)) {
+        if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
+          // Invokes within a cleanuppad for the MSVC++ personality never
+          // transfer control to their unwind edge: the personality will
+          // terminate the program.
+          removeUnwindEdge(BB);
         }
-
-        new UnreachableInst(BB->getContext(), TI);
-        TI->eraseFromParent();
       }
-      // FIXME: Check for invokes/cleanuprets/cleanupendpads which unwind to
-      // implausible catchendpads (i.e. catchendpad not in immediate parent
-      // funclet).
     }
   }
 }
@@ -1918,7 +899,6 @@ void WinEHPrepare::cleanupPreparedFunclets(Function &F) {
 }
 
 void WinEHPrepare::verifyPreparedFunclets(Function &F) {
-  // Recolor the CFG to verify that all is well.
   for (BasicBlock &BB : F) {
     size_t NumColors = BlockColors[&BB].size();
     assert(NumColors == 1 && "Expected monochromatic BB!");
@@ -1929,45 +909,39 @@ void WinEHPrepare::verifyPreparedFunclets(Function &F) {
     if (!DisableDemotion) {
       bool EHPadHasPHI = BB.isEHPad() && isa<PHINode>(BB.begin());
       assert(!EHPadHasPHI && "EH Pad still has a PHI!");
-      if (EHPadHasPHI)
-        report_fatal_error("EH Pad still has a PHI!");
     }
   }
 }
 
-bool WinEHPrepare::prepareExplicitEH(
-    Function &F, SmallVectorImpl<BasicBlock *> &EntryBlocks) {
-  replaceTerminatePadWithCleanup(F);
+bool WinEHPrepare::prepareExplicitEH(Function &F) {
+  // Remove unreachable blocks.  It is not valuable to assign them a color and
+  // their existence can trick us into thinking values are alive when they are
+  // not.
+  removeUnreachableBlocks(F);
 
   // Determine which blocks are reachable from which funclet entries.
-  colorFunclets(F, EntryBlocks);
+  colorFunclets(F);
 
-  if (!DisableDemotion) {
-    demotePHIsOnFunclets(F);
+  cloneCommonBlocks(F);
 
-    demoteUsesBetweenFunclets(F);
-
-    demoteArgumentUses(F);
-  }
-
-  cloneCommonBlocks(F, EntryBlocks);
-
-  resolveFuncletAncestry(F, EntryBlocks);
+  if (!DisableDemotion)
+    demotePHIsOnFunclets(F);
 
   if (!DisableCleanups) {
-    removeImplausibleTerminators(F);
+    DEBUG(verifyFunction(F));
+    removeImplausibleInstructions(F);
 
+    DEBUG(verifyFunction(F));
     cleanupPreparedFunclets(F);
   }
 
-  verifyPreparedFunclets(F);
+  DEBUG(verifyPreparedFunclets(F));
+  // Recolor the CFG to verify that all is well.
+  DEBUG(colorFunclets(F));
+  DEBUG(verifyPreparedFunclets(F));
 
   BlockColors.clear();
   FuncletBlocks.clear();
-  FuncletChildren.clear();
-  FuncletParents.clear();
-  EstrangedBlocks.clear();
-  FuncletCloningRequired = false;
 
   return true;
 }
@@ -1977,9 +951,11 @@ bool WinEHPrepare::prepareExplicitEH(
 AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
   BasicBlock *PHIBlock = PN->getParent();
   AllocaInst *SpillSlot = nullptr;
+  Instruction *EHPad = PHIBlock->getFirstNonPHI();
 
-  if (isa<CleanupPadInst>(PHIBlock->getFirstNonPHI())) {
-    // Insert a load in place of the PHI and replace all uses.
+  if (!isa<TerminatorInst>(EHPad)) {
+    // If the EHPad isn't a terminator, then we can insert a load in this block
+    // that will dominate all uses.
     SpillSlot = new AllocaInst(PN->getType(), nullptr,
                                Twine(PN->getName(), ".wineh.spillslot"),
                                &F.getEntryBlock().front());
@@ -1989,16 +965,16 @@ AllocaInst *WinEHPrepare::insertPHILoads(PHINode *PN, Function &F) {
     return SpillSlot;
   }
 
+  // Otherwise, we have a PHI on a terminator EHPad, and we give up and insert
+  // loads of the slot before every use.
   DenseMap<BasicBlock *, Value *> Loads;
   for (Value::use_iterator UI = PN->use_begin(), UE = PN->use_end();
        UI != UE;) {
     Use &U = *UI++;
     auto *UsingInst = cast<Instruction>(U.getUser());
-    BasicBlock *UsingBB = UsingInst->getParent();
-    if (UsingBB->isEHPad()) {
+    if (isa<PHINode>(UsingInst) && UsingInst->getParent()->isEHPad()) {
       // Use is on an EH pad phi.  Leave it alone; we'll insert loads and
       // stores for it separately.
-      assert(isa<PHINode>(UsingInst));
       continue;
     }
     replaceUseWithLoad(PN, U, SpillSlot, Loads, F);
@@ -2052,7 +1028,7 @@ void WinEHPrepare::insertPHIStore(
     SmallVectorImpl<std::pair<BasicBlock *, Value *>> &Worklist) {
 
   if (PredBlock->isEHPad() &&
-      !isa<CleanupPadInst>(PredBlock->getFirstNonPHI())) {
+      isa<TerminatorInst>(PredBlock->getFirstNonPHI())) {
     // Pred is unsplittable, so we need to queue it on the worklist.
     Worklist.push_back({PredBlock, PredVal});
     return;
@@ -2062,69 +1038,6 @@ void WinEHPrepare::insertPHIStore(
   new StoreInst(PredVal, SpillSlot, PredBlock->getTerminator());
 }
 
-// TODO: Share loads for same-funclet uses (requires dominators if funclets
-// aren't properly nested).
-void WinEHPrepare::demoteNonlocalUses(Value *V,
-                                      std::set<BasicBlock *> &ColorsForBB,
-                                      Function &F) {
-  // Tokens can only be used non-locally due to control flow involving
-  // unreachable edges.  Don't try to demote the token usage, we'll simply
-  // delete the cloned user later.
-  if (isa<CatchPadInst>(V) || isa<CleanupPadInst>(V))
-    return;
-
-  DenseMap<BasicBlock *, Value *> Loads;
-  AllocaInst *SpillSlot = nullptr;
-  for (Value::use_iterator UI = V->use_begin(), UE = V->use_end(); UI != UE;) {
-    Use &U = *UI++;
-    auto *UsingInst = cast<Instruction>(U.getUser());
-    BasicBlock *UsingBB = UsingInst->getParent();
-
-    // Is the Use inside a block which is colored the same as the Def?
-    // If so, we don't need to escape the Def because we will clone
-    // ourselves our own private copy.
-    std::set<BasicBlock *> &ColorsForUsingBB = BlockColors[UsingBB];
-    if (ColorsForUsingBB == ColorsForBB)
-      continue;
-
-    replaceUseWithLoad(V, U, SpillSlot, Loads, F);
-  }
-  if (SpillSlot) {
-    // Insert stores of the computed value into the stack slot.
-    // We have to be careful if I is an invoke instruction,
-    // because we can't insert the store AFTER the terminator instruction.
-    BasicBlock::iterator InsertPt;
-    if (isa<Argument>(V)) {
-      InsertPt = F.getEntryBlock().getTerminator()->getIterator();
-    } else if (isa<TerminatorInst>(V)) {
-      auto *II = cast<InvokeInst>(V);
-      // We cannot demote invoke instructions to the stack if their normal
-      // edge is critical. Therefore, split the critical edge and create a
-      // basic block into which the store can be inserted.
-      if (!II->getNormalDest()->getSinglePredecessor()) {
-        unsigned SuccNum =
-            GetSuccessorNumber(II->getParent(), II->getNormalDest());
-        assert(isCriticalEdge(II, SuccNum) && "Expected a critical edge!");
-        BasicBlock *NewBlock = SplitCriticalEdge(II, SuccNum);
-        assert(NewBlock && "Unable to split critical edge.");
-        // Update the color mapping for the newly split edge.
-        std::set<BasicBlock *> &ColorsForUsingBB = BlockColors[II->getParent()];
-        BlockColors[NewBlock] = ColorsForUsingBB;
-        for (BasicBlock *FuncletPad : ColorsForUsingBB)
-          FuncletBlocks[FuncletPad].insert(NewBlock);
-      }
-      InsertPt = II->getNormalDest()->getFirstInsertionPt();
-    } else {
-      InsertPt = cast<Instruction>(V)->getIterator();
-      ++InsertPt;
-      // Don't insert before PHI nodes or EH pad instrs.
-      for (; isa<PHINode>(InsertPt) || InsertPt->isEHPad(); ++InsertPt)
-        ;
-    }
-    new StoreInst(V, SpillSlot, &*InsertPt);
-  }
-}
-
 void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
                                       DenseMap<BasicBlock *, Value *> &Loads,
                                       Function &F) {
@@ -2175,10 +1088,10 @@ void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
       Goto->setSuccessor(0, PHIBlock);
       CatchRet->setSuccessor(NewBlock);
       // Update the color mapping for the newly split edge.
-      std::set<BasicBlock *> &ColorsForPHIBlock = BlockColors[PHIBlock];
+      ColorVector &ColorsForPHIBlock = BlockColors[PHIBlock];
       BlockColors[NewBlock] = ColorsForPHIBlock;
       for (BasicBlock *FuncletPad : ColorsForPHIBlock)
-        FuncletBlocks[FuncletPad].insert(NewBlock);
+        FuncletBlocks[FuncletPad].push_back(NewBlock);
       // Treat the new block as incoming for load insertion.
       IncomingBlock = NewBlock;
     }
@@ -2197,11 +1110,12 @@ void WinEHPrepare::replaceUseWithLoad(Value *V, Use &U, AllocaInst *&SpillSlot,
   }
 }
 
-void WinEHFuncInfo::addIPToStateRange(const BasicBlock *PadBB,
+void WinEHFuncInfo::addIPToStateRange(const InvokeInst *II,
                                       MCSymbol *InvokeBegin,
                                       MCSymbol *InvokeEnd) {
-  assert(PadBB->isEHPad() && EHPadStateMap.count(PadBB->getFirstNonPHI()) &&
-         "should get EH pad BB with precomputed state");
-  InvokeToStateMap[InvokeBegin] =
-      std::make_pair(EHPadStateMap[PadBB->getFirstNonPHI()], InvokeEnd);
+  assert(InvokeStateMap.count(II) &&
+         "should get invoke with precomputed state");
+  LabelToStateMap[InvokeBegin] = std::make_pair(InvokeStateMap[II], InvokeEnd);
 }
+
+WinEHFuncInfo::WinEHFuncInfo() {}