@@ -618,7 +618,8 @@ class CopyForwarding {
618
618
bool forwardDeadTempCopy (CopyAddrInst *destCopy);
619
619
bool forwardPropagateCopy ();
620
620
bool backwardPropagateCopy ();
621
- bool hoistDestroy (SILInstruction *DestroyPoint, SILLocation DestroyLoc);
621
+ bool hoistDestroy (SILInstruction *DestroyPoint, SILLocation DestroyLoc,
622
+ SmallVectorImpl<DebugValueAddrInst *> &debugInstsToDelete);
622
623
623
624
bool isSourceDeadAtCopy ();
624
625
@@ -1224,8 +1225,11 @@ bool CopyForwarding::backwardPropagateCopy() {
1224
1225
// /
1225
1226
// / Return true if a destroy was inserted, forwarded from a copy, or the
1226
1227
// / block was marked dead-in.
1227
- bool CopyForwarding::hoistDestroy (SILInstruction *DestroyPoint,
1228
- SILLocation DestroyLoc) {
1228
+ // / \p debugInstsToDelete will contain the debug_value_addr users of copy src
1229
+ // / that need to be deleted if the hoist is successful
1230
+ bool CopyForwarding::hoistDestroy (
1231
+ SILInstruction *DestroyPoint, SILLocation DestroyLoc,
1232
+ SmallVectorImpl<DebugValueAddrInst *> &debugInstsToDelete) {
1229
1233
if (!EnableDestroyHoisting)
1230
1234
return false ;
1231
1235
@@ -1266,6 +1270,14 @@ bool CopyForwarding::hoistDestroy(SILInstruction *DestroyPoint,
1266
1270
<< *Inst);
1267
1271
return tryToInsertHoistedDestroyAfter (Inst);
1268
1272
}
1273
+ if (auto *debugAddr = dyn_cast<DebugValueAddrInst>(Inst)) {
1274
+ // Collect debug_value_addr uses of copy src. If the hoist is
1275
+ // successful, these instructions will have consumed operand and need to
1276
+ // be erased.
1277
+ if (SrcDebugValueInsts.contains (debugAddr)) {
1278
+ debugInstsToDelete.push_back (debugAddr);
1279
+ }
1280
+ }
1269
1281
if (!ShouldHoist && isa<ApplyInst>(Inst))
1270
1282
ShouldHoist = true ;
1271
1283
continue ;
@@ -1316,10 +1328,11 @@ void CopyForwarding::forwardCopiesOf(SILValue Def, SILFunction *F) {
1316
1328
bool HoistedDestroyFound = false ;
1317
1329
SILLocation HoistedDestroyLoc = F->getLocation ();
1318
1330
const SILDebugScope *HoistedDebugScope = nullptr ;
1331
+ SmallVector<DebugValueAddrInst *, 2 > debugInstsToDelete;
1319
1332
1320
1333
for (auto *Destroy : DestroyPoints) {
1321
1334
// If hoistDestroy returns false, it was not worth hoisting.
1322
- if (hoistDestroy (Destroy, Destroy->getLoc ())) {
1335
+ if (hoistDestroy (Destroy, Destroy->getLoc (), debugInstsToDelete )) {
1323
1336
// Propagate DestroyLoc for any destroy hoisted above a block.
1324
1337
if (DeadInBlocks.count (Destroy->getParent ())) {
1325
1338
HoistedDestroyLoc = Destroy->getLoc ();
@@ -1331,7 +1344,12 @@ void CopyForwarding::forwardCopiesOf(SILValue Def, SILFunction *F) {
1331
1344
// original Destroy.
1332
1345
Destroy->eraseFromParent ();
1333
1346
assert (HasChanged || !DeadInBlocks.empty () && " HasChanged should be set" );
1347
+ // Since the hoist was successful, delete all dead debug_value_addr
1348
+ for (auto *deadDebugUser : debugInstsToDelete) {
1349
+ deadDebugUser->eraseFromParent ();
1350
+ }
1334
1351
}
1352
+ debugInstsToDelete.clear ();
1335
1353
}
1336
1354
// Any blocks containing a DestroyPoints where hoistDestroy did not find a use
1337
1355
// are now marked in DeadInBlocks.
@@ -1358,9 +1376,14 @@ void CopyForwarding::forwardCopiesOf(SILValue Def, SILFunction *F) {
1358
1376
if (DeadInSuccs.size () == Succs.size () &&
1359
1377
!SrcUserInsts.count (BB->getTerminator ())) {
1360
1378
// All successors are dead, so continue hoisting.
1361
- bool WasHoisted = hoistDestroy (BB->getTerminator (), HoistedDestroyLoc);
1379
+ bool WasHoisted = hoistDestroy (BB->getTerminator (), HoistedDestroyLoc,
1380
+ debugInstsToDelete);
1362
1381
(void )WasHoisted;
1363
1382
assert (WasHoisted && " should always hoist above a terminator" );
1383
+ for (auto *deadDebugUser : debugInstsToDelete) {
1384
+ deadDebugUser->eraseFromParent ();
1385
+ }
1386
+ debugInstsToDelete.clear ();
1364
1387
continue ;
1365
1388
}
1366
1389
// Emit a destroy on each CFG edge leading to a dead-in block. This requires
0 commit comments