@@ -206,6 +206,7 @@ class DCE {
206206
207207 void markValueLive (SILValue V);
208208 void markInstructionLive (SILInstruction *Inst);
209+ void markOwnedDeadValueLive (SILValue v);
209210 void markTerminatorArgsLive (SILBasicBlock *Pred, SILBasicBlock *Succ,
210211 size_t ArgIndex);
211212 void markControllingTerminatorsLive (SILBasicBlock *Block);
@@ -268,6 +269,20 @@ void DCE::markInstructionLive(SILInstruction *Inst) {
268269 Worklist.push_back (Inst);
269270}
270271
272+ void DCE::markOwnedDeadValueLive (SILValue v) {
273+ if (v->getOwnershipKind () == OwnershipKind::Owned) {
274+ // When an owned value has no lifetime ending uses it means that it is in a
275+ // dead-end region. We must not remove and inserting compensating destroys
276+ // for it because that would potentially destroy the value too early.
277+ // TODO: we can remove this once we have complete OSSA lifetimes
278+ for (Operand *use : v->getUses ()) {
279+ if (use->isLifetimeEnding ())
280+ return ;
281+ }
282+ markValueLive (v);
283+ }
284+ }
285+
271286// / Gets the producing instruction of a cond_fail condition. Currently these
272287// / are overflow builtins but may be extended to other instructions in the
273288// / future.
@@ -334,6 +349,9 @@ void DCE::markLive() {
334349 // to be live in the sense that they are not trivially something we
335350 // can delete by examining only that instruction.
336351 for (auto &BB : *F) {
352+ for (SILArgument *arg : BB.getArguments ()) {
353+ markOwnedDeadValueLive (arg);
354+ }
337355 for (auto &I : BB) {
338356 switch (I.getKind ()) {
339357 case SILInstructionKind::CondFailInst: {
@@ -414,6 +432,9 @@ void DCE::markLive() {
414432 default :
415433 if (seemsUseful (&I))
416434 markInstructionLive (&I);
435+ for (SILValue result : I.getResults ()) {
436+ markOwnedDeadValueLive (result);
437+ }
417438 }
418439 }
419440 }
0 commit comments