@@ -78,10 +78,10 @@ class WinEHPrepareImpl {
7878 bool prepareExplicitEH (Function &F);
7979 void colorFunclets (Function &F);
8080
81- void demotePHIsOnFunclets (Function &F, bool DemoteCatchSwitchPHIOnly);
82- void cloneCommonBlocks (Function &F);
83- void removeImplausibleInstructions (Function &F);
84- void cleanupPreparedFunclets (Function &F);
81+ bool demotePHIsOnFunclets (Function &F, bool DemoteCatchSwitchPHIOnly);
82+ bool cloneCommonBlocks (Function &F);
83+ bool removeImplausibleInstructions (Function &F);
84+ bool cleanupPreparedFunclets (Function &F);
8585 void verifyPreparedFunclets (Function &F);
8686
8787 bool DemoteCatchSwitchPHIOnly;
@@ -861,8 +861,10 @@ void WinEHPrepareImpl::colorFunclets(Function &F) {
861861 }
862862}
863863
864- void WinEHPrepareImpl::demotePHIsOnFunclets (Function &F,
864+ bool WinEHPrepareImpl::demotePHIsOnFunclets (Function &F,
865865 bool DemoteCatchSwitchPHIOnly) {
866+ bool Changed = false ;
867+
866868 // Strip PHI nodes off of EH pads.
867869 SmallVector<PHINode *, 16 > PHINodes;
868870 for (BasicBlock &BB : make_early_inc_range (F)) {
@@ -892,6 +894,8 @@ void WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
892894 break ;
893895 }
894896
897+ Changed = true ;
898+
895899 AllocaInst *SpillSlot = insertPHILoads (PN, F);
896900 if (SpillSlot)
897901 insertPHIStores (PN, SpillSlot);
@@ -905,9 +909,13 @@ void WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
905909 PN->replaceAllUsesWith (PoisonValue::get (PN->getType ()));
906910 PN->eraseFromParent ();
907911 }
912+
913+ return Changed;
908914}
909915
910- void WinEHPrepareImpl::cloneCommonBlocks (Function &F) {
916+ bool WinEHPrepareImpl::cloneCommonBlocks (Function &F) {
917+ bool Changed = false ;
918+
911919 // We need to clone all blocks which belong to multiple funclets. Values are
912920 // remapped throughout the funclet to propagate both the new instructions
913921 // *and* the new basic blocks themselves.
@@ -952,6 +960,8 @@ void WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
952960 if (Orig2Clone.empty ())
953961 continue ;
954962
963+ Changed = true ;
964+
955965 // Update our color mappings to reflect that one block has lost a color and
956966 // another has gained a color.
957967 for (auto &BBMapping : Orig2Clone) {
@@ -1107,9 +1117,13 @@ void WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
11071117 SSAUpdate.RewriteUseAfterInsertions (*UsesToRename.pop_back_val ());
11081118 }
11091119 }
1120+
1121+ return Changed;
11101122}
11111123
1112- void WinEHPrepareImpl::removeImplausibleInstructions (Function &F) {
1124+ bool WinEHPrepareImpl::removeImplausibleInstructions (Function &F) {
1125+ bool Changed = false ;
1126+
11131127 // Remove implausible terminators and replace them with UnreachableInst.
11141128 for (auto &Funclet : FuncletBlocks) {
11151129 BasicBlock *FuncletPadBB = Funclet.first ;
@@ -1139,6 +1153,8 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
11391153 (CalledFn && CalledFn->isIntrinsic () && CB->doesNotThrow ()))
11401154 continue ;
11411155
1156+ Changed = true ;
1157+
11421158 // This call site was not part of this funclet, remove it.
11431159 if (isa<InvokeInst>(CB)) {
11441160 // Remove the unwind edge if it was an invoke.
@@ -1170,9 +1186,11 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
11701186 IsUnreachableCleanupret = CRI->getCleanupPad () != CleanupPad;
11711187 if (IsUnreachableRet || IsUnreachableCatchret ||
11721188 IsUnreachableCleanupret) {
1189+ Changed = true ;
11731190 changeToUnreachable (TI);
11741191 } else if (isa<InvokeInst>(TI)) {
11751192 if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
1193+ Changed = true ;
11761194 // Invokes within a cleanuppad for the MSVC++ personality never
11771195 // transfer control to their unwind edge: the personality will
11781196 // terminate the program.
@@ -1181,20 +1199,26 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
11811199 }
11821200 }
11831201 }
1202+
1203+ return Changed;
11841204}
11851205
1186- void WinEHPrepareImpl::cleanupPreparedFunclets (Function &F) {
1206+ bool WinEHPrepareImpl::cleanupPreparedFunclets (Function &F) {
1207+ bool Changed = false ;
1208+
11871209 // Clean-up some of the mess we made by removing useles PHI nodes, trivial
11881210 // branches, etc.
11891211 for (BasicBlock &BB : llvm::make_early_inc_range (F)) {
1190- SimplifyInstructionsInBlock (&BB);
1191- ConstantFoldTerminator (&BB, /* DeleteDeadConditions=*/ true );
1192- MergeBlockIntoPredecessor (&BB);
1212+ Changed |= SimplifyInstructionsInBlock (&BB);
1213+ Changed |= ConstantFoldTerminator (&BB, /* DeleteDeadConditions=*/ true );
1214+ Changed |= MergeBlockIntoPredecessor (&BB);
11931215 }
11941216
11951217 // We might have some unreachable blocks after cleaning up some impossible
11961218 // control flow.
1197- removeUnreachableBlocks (F);
1219+ Changed |= removeUnreachableBlocks (F);
1220+
1221+ return Changed;
11981222}
11991223
12001224#ifndef NDEBUG
@@ -1216,31 +1240,31 @@ bool WinEHPrepareImpl::prepareExplicitEH(Function &F) {
12161240 // Remove unreachable blocks. It is not valuable to assign them a color and
12171241 // their existence can trick us into thinking values are alive when they are
12181242 // not.
1219- removeUnreachableBlocks (F);
1243+ bool Changed = removeUnreachableBlocks (F);
12201244
12211245 // Determine which blocks are reachable from which funclet entries.
12221246 colorFunclets (F);
12231247
1224- cloneCommonBlocks (F);
1248+ Changed |= cloneCommonBlocks (F);
12251249
12261250 if (!DisableDemotion)
1227- demotePHIsOnFunclets (F, DemoteCatchSwitchPHIOnly ||
1228- DemoteCatchSwitchPHIOnlyOpt);
1251+ Changed |= demotePHIsOnFunclets (F, DemoteCatchSwitchPHIOnly ||
1252+ DemoteCatchSwitchPHIOnlyOpt);
12291253
12301254 if (!DisableCleanups) {
12311255 assert (!verifyFunction (F, &dbgs ()));
1232- removeImplausibleInstructions (F);
1256+ Changed |= removeImplausibleInstructions (F);
12331257
12341258 assert (!verifyFunction (F, &dbgs ()));
1235- cleanupPreparedFunclets (F);
1259+ Changed |= cleanupPreparedFunclets (F);
12361260 }
12371261
12381262 LLVM_DEBUG (verifyPreparedFunclets (F));
12391263 // Recolor the CFG to verify that all is well.
12401264 LLVM_DEBUG (colorFunclets (F));
12411265 LLVM_DEBUG (verifyPreparedFunclets (F));
12421266
1243- return true ;
1267+ return Changed ;
12441268}
12451269
12461270// TODO: Share loads when one use dominates another, or when a catchpad exit
0 commit comments