@@ -1200,8 +1200,19 @@ bool CopyForwarding::hoistDestroy(SILInstruction *DestroyPoint,
1200
1200
1201
1201
// If DestroyPoint is a block terminator, we must hoist.
1202
1202
bool MustHoist = (DestroyPoint == BB->getTerminator ());
1203
+ // If we haven't seen anything significant, avoid useless hoisting.
1204
+ bool ShouldHoist = MustHoist;
1205
+
1206
+ auto tryToInsertHoistedDestroyAfter = [&](SILInstruction *afterInst) {
1207
+ if (!ShouldHoist)
1208
+ return false ;
1209
+ LLVM_DEBUG (llvm::dbgs () << " Hoisting to Use:" << *afterInst);
1210
+ SILBuilderWithScope (std::next (afterInst->getIterator ()), afterInst)
1211
+ .createDestroyAddr (DestroyLoc, CurrentDef);
1212
+ HasChanged = true ;
1213
+ return true ;
1214
+ };
1203
1215
1204
- bool IsWorthHoisting = MustHoist;
1205
1216
auto SI = DestroyPoint->getIterator (), SE = BB->begin ();
1206
1217
while (SI != SE) {
1207
1218
--SI;
@@ -1219,10 +1230,10 @@ bool CopyForwarding::hoistDestroy(SILInstruction *DestroyPoint,
1219
1230
// destroy_addr CurrentDef
1220
1231
LLVM_DEBUG (llvm::dbgs () << " Cannot hoist above stored value use:"
1221
1232
<< *Inst);
1222
- return false ;
1233
+ return tryToInsertHoistedDestroyAfter (Inst) ;
1223
1234
}
1224
- if (!IsWorthHoisting && isa<ApplyInst>(Inst))
1225
- IsWorthHoisting = true ;
1235
+ if (!ShouldHoist && isa<ApplyInst>(Inst))
1236
+ ShouldHoist = true ;
1226
1237
continue ;
1227
1238
}
1228
1239
if (auto *CopyInst = dyn_cast<CopyAddrInst>(Inst)) {
@@ -1233,19 +1244,15 @@ bool CopyForwarding::hoistDestroy(SILInstruction *DestroyPoint,
1233
1244
return true ;
1234
1245
}
1235
1246
}
1236
- // We reached a user of CurrentDef. If we haven't seen anything significant,
1237
- // avoid useless hoisting.
1238
- if (!IsWorthHoisting)
1239
- return false ;
1240
-
1241
- LLVM_DEBUG (llvm::dbgs () << " Hoisting to Use:" << *Inst);
1242
- SILBuilderWithScope (std::next (SI), Inst)
1243
- .createDestroyAddr (DestroyLoc, CurrentDef);
1244
- HasChanged = true ;
1245
- return true ;
1247
+ return tryToInsertHoistedDestroyAfter (Inst);
1246
1248
}
1247
- if (!DoGlobalHoisting)
1249
+ if (!DoGlobalHoisting) {
1250
+ // If DoGlobalHoisting is set, then we should never mark a DeadInBlock, so
1251
+ // MustHoist should be false.
1252
+ assert (!MustHoist &&
1253
+ " Cannot hoist above a terminator with global hoisting disabled." );
1248
1254
return false ;
1255
+ }
1249
1256
DeadInBlocks.insert (BB);
1250
1257
return true ;
1251
1258
}
0 commit comments