@@ -414,6 +414,14 @@ broadenSingleElementStores(StoreInst *storeInst,
414414// / copy. The only way to guarantee the lifetime of a variable is to use a
415415// / borrow scope--copy/destroy is insufficient by itself.
416416// /
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+ // /
417425// / FIXME: Technically this should be guarded by a compiler flag like
418426// / -enable-copy-propagation until SILGen protects scoped variables by
419427// / borrow scopes.
@@ -423,20 +431,21 @@ eliminateSimpleCopies(CopyValueInst *cvi, CanonicalizeInstruction &pass) {
423431
424432 // Eliminate copies that only have destroy_value uses.
425433 SmallVector<DestroyValueInst *, 8 > destroys;
426- for (auto *use : getNonDebugUses ( cvi)) {
434+ for (Operand *use : cvi-> getUses ( )) {
427435 if (auto *dvi = dyn_cast<DestroyValueInst>(use->getUser ())) {
428436 destroys.push_back (dvi);
429437 continue ;
430438 }
439+ if (!pass.preserveDebugInfo && isa<DebugValueInst>(use->getUser ())) {
440+ continue ;
441+ }
431442 return next;
432443 }
433444
434445 while (!destroys.empty ()) {
435446 next = killInstruction (destroys.pop_back_val (), next, pass);
436447 }
437-
438- next = killInstAndIncidentalUses (cvi, next, pass);
439- return next;
448+ return killInstAndIncidentalUses (cvi, next, pass);
440449}
441450
442451// / Unlike dead copy elimination, dead borrows can be safely removed because the
@@ -538,8 +547,11 @@ CanonicalizeInstruction::canonicalize(SILInstruction *inst) {
538547 // If we have ownership and are not in raw SIL, eliminate unneeded forwarding
539548 // insts. We don't do this in raw SIL as not to disturb the codegen read by
540549 // diagnostics.
550+ //
551+ // TODO: fix tryEliminateUnneededForwardingInst to handle debug uses.
541552 auto *fn = inst->getFunction ();
542- if (fn->hasOwnership () && fn->getModule ().getStage () != SILStage::Raw) {
553+ if (!preserveDebugInfo && fn->hasOwnership ()
554+ && fn->getModule ().getStage () != SILStage::Raw) {
543555 if (OwnershipForwardingMixin::isa (inst))
544556 if (auto newNext = tryEliminateUnneededForwardingInst (inst, *this ))
545557 return *newNext;
0 commit comments