@@ -78,10 +78,10 @@ class WinEHPrepareImpl {
78
78
bool prepareExplicitEH (Function &F);
79
79
void colorFunclets (Function &F);
80
80
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);
85
85
void verifyPreparedFunclets (Function &F);
86
86
87
87
bool DemoteCatchSwitchPHIOnly;
@@ -861,8 +861,10 @@ void WinEHPrepareImpl::colorFunclets(Function &F) {
861
861
}
862
862
}
863
863
864
- void WinEHPrepareImpl::demotePHIsOnFunclets (Function &F,
864
+ bool WinEHPrepareImpl::demotePHIsOnFunclets (Function &F,
865
865
bool DemoteCatchSwitchPHIOnly) {
866
+ bool Changed = false ;
867
+
866
868
// Strip PHI nodes off of EH pads.
867
869
SmallVector<PHINode *, 16 > PHINodes;
868
870
for (BasicBlock &BB : make_early_inc_range (F)) {
@@ -892,6 +894,8 @@ void WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
892
894
break ;
893
895
}
894
896
897
+ Changed = true ;
898
+
895
899
AllocaInst *SpillSlot = insertPHILoads (PN, F);
896
900
if (SpillSlot)
897
901
insertPHIStores (PN, SpillSlot);
@@ -905,9 +909,13 @@ void WinEHPrepareImpl::demotePHIsOnFunclets(Function &F,
905
909
PN->replaceAllUsesWith (PoisonValue::get (PN->getType ()));
906
910
PN->eraseFromParent ();
907
911
}
912
+
913
+ return Changed;
908
914
}
909
915
910
- void WinEHPrepareImpl::cloneCommonBlocks (Function &F) {
916
+ bool WinEHPrepareImpl::cloneCommonBlocks (Function &F) {
917
+ bool Changed = false ;
918
+
911
919
// We need to clone all blocks which belong to multiple funclets. Values are
912
920
// remapped throughout the funclet to propagate both the new instructions
913
921
// *and* the new basic blocks themselves.
@@ -952,6 +960,8 @@ void WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
952
960
if (Orig2Clone.empty ())
953
961
continue ;
954
962
963
+ Changed = true ;
964
+
955
965
// Update our color mappings to reflect that one block has lost a color and
956
966
// another has gained a color.
957
967
for (auto &BBMapping : Orig2Clone) {
@@ -1107,9 +1117,13 @@ void WinEHPrepareImpl::cloneCommonBlocks(Function &F) {
1107
1117
SSAUpdate.RewriteUseAfterInsertions (*UsesToRename.pop_back_val ());
1108
1118
}
1109
1119
}
1120
+
1121
+ return Changed;
1110
1122
}
1111
1123
1112
- void WinEHPrepareImpl::removeImplausibleInstructions (Function &F) {
1124
+ bool WinEHPrepareImpl::removeImplausibleInstructions (Function &F) {
1125
+ bool Changed = false ;
1126
+
1113
1127
// Remove implausible terminators and replace them with UnreachableInst.
1114
1128
for (auto &Funclet : FuncletBlocks) {
1115
1129
BasicBlock *FuncletPadBB = Funclet.first ;
@@ -1139,6 +1153,8 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
1139
1153
(CalledFn && CalledFn->isIntrinsic () && CB->doesNotThrow ()))
1140
1154
continue ;
1141
1155
1156
+ Changed = true ;
1157
+
1142
1158
// This call site was not part of this funclet, remove it.
1143
1159
if (isa<InvokeInst>(CB)) {
1144
1160
// Remove the unwind edge if it was an invoke.
@@ -1170,9 +1186,11 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
1170
1186
IsUnreachableCleanupret = CRI->getCleanupPad () != CleanupPad;
1171
1187
if (IsUnreachableRet || IsUnreachableCatchret ||
1172
1188
IsUnreachableCleanupret) {
1189
+ Changed = true ;
1173
1190
changeToUnreachable (TI);
1174
1191
} else if (isa<InvokeInst>(TI)) {
1175
1192
if (Personality == EHPersonality::MSVC_CXX && CleanupPad) {
1193
+ Changed = true ;
1176
1194
// Invokes within a cleanuppad for the MSVC++ personality never
1177
1195
// transfer control to their unwind edge: the personality will
1178
1196
// terminate the program.
@@ -1181,20 +1199,26 @@ void WinEHPrepareImpl::removeImplausibleInstructions(Function &F) {
1181
1199
}
1182
1200
}
1183
1201
}
1202
+
1203
+ return Changed;
1184
1204
}
1185
1205
1186
- void WinEHPrepareImpl::cleanupPreparedFunclets (Function &F) {
1206
+ bool WinEHPrepareImpl::cleanupPreparedFunclets (Function &F) {
1207
+ bool Changed = false ;
1208
+
1187
1209
// Clean-up some of the mess we made by removing useles PHI nodes, trivial
1188
1210
// branches, etc.
1189
1211
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);
1193
1215
}
1194
1216
1195
1217
// We might have some unreachable blocks after cleaning up some impossible
1196
1218
// control flow.
1197
- removeUnreachableBlocks (F);
1219
+ Changed |= removeUnreachableBlocks (F);
1220
+
1221
+ return Changed;
1198
1222
}
1199
1223
1200
1224
#ifndef NDEBUG
@@ -1216,31 +1240,31 @@ bool WinEHPrepareImpl::prepareExplicitEH(Function &F) {
1216
1240
// Remove unreachable blocks. It is not valuable to assign them a color and
1217
1241
// their existence can trick us into thinking values are alive when they are
1218
1242
// not.
1219
- removeUnreachableBlocks (F);
1243
+ bool Changed = removeUnreachableBlocks (F);
1220
1244
1221
1245
// Determine which blocks are reachable from which funclet entries.
1222
1246
colorFunclets (F);
1223
1247
1224
- cloneCommonBlocks (F);
1248
+ Changed |= cloneCommonBlocks (F);
1225
1249
1226
1250
if (!DisableDemotion)
1227
- demotePHIsOnFunclets (F, DemoteCatchSwitchPHIOnly ||
1228
- DemoteCatchSwitchPHIOnlyOpt);
1251
+ Changed |= demotePHIsOnFunclets (F, DemoteCatchSwitchPHIOnly ||
1252
+ DemoteCatchSwitchPHIOnlyOpt);
1229
1253
1230
1254
if (!DisableCleanups) {
1231
1255
assert (!verifyFunction (F, &dbgs ()));
1232
- removeImplausibleInstructions (F);
1256
+ Changed |= removeImplausibleInstructions (F);
1233
1257
1234
1258
assert (!verifyFunction (F, &dbgs ()));
1235
- cleanupPreparedFunclets (F);
1259
+ Changed |= cleanupPreparedFunclets (F);
1236
1260
}
1237
1261
1238
1262
LLVM_DEBUG (verifyPreparedFunclets (F));
1239
1263
// Recolor the CFG to verify that all is well.
1240
1264
LLVM_DEBUG (colorFunclets (F));
1241
1265
LLVM_DEBUG (verifyPreparedFunclets (F));
1242
1266
1243
- return true ;
1267
+ return Changed ;
1244
1268
}
1245
1269
1246
1270
// TODO: Share loads when one use dominates another, or when a catchpad exit
0 commit comments