@@ -414,6 +414,14 @@ broadenSingleElementStores(StoreInst *storeInst,
414
414
// / copy. The only way to guarantee the lifetime of a variable is to use a
415
415
// / borrow scope--copy/destroy is insufficient by itself.
416
416
// /
417
+ // / FIXME: This removes debug_value instructions aggressively as part of
418
+ // / SILGenCleanup. Instead, debug_values should be canonicalized before copy
419
+ // / elimination so that we never see the pattern:
420
+ // / %b = begin_borrow
421
+ // / %c = copy %b
422
+ // / end_borrow %b
423
+ // / debug_value %c
424
+ // /
417
425
// / FIXME: Technically this should be guarded by a compiler flag like
418
426
// / -enable-copy-propagation until SILGen protects scoped variables by
419
427
// / borrow scopes.
@@ -423,20 +431,21 @@ eliminateSimpleCopies(CopyValueInst *cvi, CanonicalizeInstruction &pass) {
423
431
424
432
// Eliminate copies that only have destroy_value uses.
425
433
SmallVector<DestroyValueInst *, 8 > destroys;
426
- for (auto *use : getNonDebugUses ( cvi)) {
434
+ for (Operand *use : cvi-> getUses ( )) {
427
435
if (auto *dvi = dyn_cast<DestroyValueInst>(use->getUser ())) {
428
436
destroys.push_back (dvi);
429
437
continue ;
430
438
}
439
+ if (!pass.preserveDebugInfo && isa<DebugValueInst>(use->getUser ())) {
440
+ continue ;
441
+ }
431
442
return next;
432
443
}
433
444
434
445
while (!destroys.empty ()) {
435
446
next = killInstruction (destroys.pop_back_val (), next, pass);
436
447
}
437
-
438
- next = killInstAndIncidentalUses (cvi, next, pass);
439
- return next;
448
+ return killInstAndIncidentalUses (cvi, next, pass);
440
449
}
441
450
442
451
// / Unlike dead copy elimination, dead borrows can be safely removed because the
@@ -538,8 +547,11 @@ CanonicalizeInstruction::canonicalize(SILInstruction *inst) {
538
547
// If we have ownership and are not in raw SIL, eliminate unneeded forwarding
539
548
// insts. We don't do this in raw SIL as not to disturb the codegen read by
540
549
// diagnostics.
550
+ //
551
+ // TODO: fix tryEliminateUnneededForwardingInst to handle debug uses.
541
552
auto *fn = inst->getFunction ();
542
- if (fn->hasOwnership () && fn->getModule ().getStage () != SILStage::Raw) {
553
+ if (!preserveDebugInfo && fn->hasOwnership ()
554
+ && fn->getModule ().getStage () != SILStage::Raw) {
543
555
if (OwnershipForwardingMixin::isa (inst))
544
556
if (auto newNext = tryEliminateUnneededForwardingInst (inst, *this ))
545
557
return *newNext;
0 commit comments