+ // Don't emit any special code for the cleanuppad instruction. It just marks
+ // the start of a funclet.
+ FuncInfo.MBB->setIsEHFuncletEntry();
+}
+
+/// When an invoke or a cleanupret unwinds to the next EH pad, there are
+/// many places it could ultimately go. In the IR, we have a single unwind
+/// destination, but in the machine CFG, we enumerate all the possible blocks.
+/// This function skips over imaginary basic blocks that hold catchpad,
+/// terminatepad, or catchendpad instructions, and finds all the "real" machine
+/// basic block destinations.
+static void
+findUnwindDestinations(FunctionLoweringInfo &FuncInfo,
+ const BasicBlock *EHPadBB,
+ SmallVectorImpl<MachineBasicBlock *> &UnwindDests) {
+ bool IsMSVCCXX = classifyEHPersonality(FuncInfo.Fn->getPersonalityFn()) ==
+ EHPersonality::MSVC_CXX;
+ while (EHPadBB) {
+ const Instruction *Pad = EHPadBB->getFirstNonPHI();
+ if (isa<LandingPadInst>(Pad)) {
+ // Stop on landingpads. They are not funclets.
+ UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]);
+ break;
+ } else if (isa<CleanupPadInst>(Pad) || isa<LandingPadInst>(Pad)) {
+ // Stop on cleanup pads. Cleanups are always funclet entries for all known
+ // personalities.
+ UnwindDests.push_back(FuncInfo.MBBMap[EHPadBB]);
+ UnwindDests.back()->setIsEHFuncletEntry();
+ break;
+ } else if (const auto *CPI = dyn_cast<CatchPadInst>(Pad)) {
+ // Add the catchpad handler to the possible destinations.
+ UnwindDests.push_back(FuncInfo.MBBMap[CPI->getNormalDest()]);
+ // In MSVC C++, catchblocks are funclets and need prologues.
+ if (IsMSVCCXX)
+ UnwindDests.back()->setIsEHFuncletEntry();
+ EHPadBB = CPI->getUnwindDest();
+ } else if (const auto *CEPI = dyn_cast<CatchEndPadInst>(Pad)) {
+ EHPadBB = CEPI->getUnwindDest();
+ } else if (const auto *CEPI = dyn_cast<CleanupEndPadInst>(Pad)) {
+ EHPadBB = CEPI->getUnwindDest();
+ }
+ }