Skip to content

Commit 73d6a48

Browse files
authored
[WinEH] Track changes in WinEHPrepare pass (#134121)
Before this change, the pass would always claim to have changed IR if there is a scope-based personality function. We add some plumbing to track if there was an actual change. This should be NFC, except that we might now preserve more analysis passes.
1 parent aaa9c19 commit 73d6a48

File tree

1 file changed

+43
-19
lines changed

1 file changed

+43
-19
lines changed

llvm/lib/CodeGen/WinEHPrepare.cpp

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)