1515
1616#include " swift/Basic/Assertions.h"
1717#include " swift/SIL/BasicBlockUtils.h"
18+ #include " swift/SIL/OSSALifetimeCompletion.h"
1819#include " swift/SIL/OwnershipUtils.h"
1920
2021using namespace swift ;
2122using namespace swift ::semanticarc;
2223
23- OwnershipLiveRange::OwnershipLiveRange (SILValue value)
24+ OwnershipLiveRange::OwnershipLiveRange (
25+ SILValue value, ArrayRef<std::pair<Operand *, SILValue>> extraUses)
2426 : introducer(OwnedValueIntroducer::get(value)), destroyingUses(),
2527 ownershipForwardingUses(), unknownConsumingUses() {
2628 assert (introducer);
2729 assert (introducer.value ->getOwnershipKind () == OwnershipKind::Owned);
2830
29- SmallVector<Operand *, 32 > tmpDestroyingUses;
30- SmallVector<Operand *, 32 > tmpForwardingConsumingUses;
31- SmallVector<Operand *, 32 > tmpUnknownConsumingUses;
31+ SmallVector<UsePoint, 32 > tmpDestroyingUses;
32+ SmallVector<UsePoint, 32 > tmpForwardingConsumingUses;
33+ SmallVector<UsePoint, 32 > tmpUnknownConsumingUses;
34+
35+ SmallVector<SILValue, 4 > defs;
36+ defs.push_back (value);
3237
3338 // We know that our silvalue produces an @owned value. Look through all of our
3439 // uses and classify them as either consuming or not.
@@ -111,6 +116,7 @@ OwnershipLiveRange::OwnershipLiveRange(SILValue value)
111116 continue ;
112117 }
113118 llvm::copy (v->getUses (), std::back_inserter (worklist));
119+ defs.push_back (v);
114120 }
115121 continue ;
116122 }
@@ -138,8 +144,32 @@ OwnershipLiveRange::OwnershipLiveRange(SILValue value)
138144 // Otherwise add all users of this BBArg to the worklist to visit
139145 // recursively.
140146 llvm::copy (succArg->getUses (), std::back_inserter (worklist));
147+ defs.push_back (succArg);
148+ }
149+ }
150+ }
151+
152+ for (auto def : defs) {
153+ if (def->use_begin () == def->use_end ()) {
154+ continue ;
155+ }
156+ SmallVector<SILBasicBlock *, 32 > blocks;
157+ SSAPrunedLiveness liveness (def->getFunction (), &blocks);
158+ liveness.initializeDef (def);
159+ liveness.computeSimple ();
160+ for (auto use : extraUses) {
161+ if (use.second != def) {
162+ continue ;
141163 }
164+ liveness.updateForUse (use.first ->getUser (), /* lifetimeEnding=*/ true );
142165 }
166+ OSSALifetimeCompletion::visitAvailabilityBoundary (
167+ def, liveness, [&tmpDestroyingUses](auto *inst, auto end) {
168+ if (end != OSSALifetimeCompletion::LifetimeEnd::Boundary) {
169+ return ;
170+ }
171+ tmpDestroyingUses.push_back (inst);
172+ });
143173 }
144174
145175 // The order in which we append these to consumingUses matters since we assume
@@ -248,7 +278,8 @@ void OwnershipLiveRange::insertEndBorrowsAtDestroys(
248278
249279void OwnershipLiveRange::convertOwnedGeneralForwardingUsesToGuaranteed () && {
250280 while (!ownershipForwardingUses.empty ()) {
251- auto *use = ownershipForwardingUses.back ();
281+ auto point = ownershipForwardingUses.back ();
282+ auto *use = point.getOperand ();
252283 ownershipForwardingUses = ownershipForwardingUses.drop_back ();
253284 ForwardingOperand operand (use);
254285 operand.replaceOwnershipKind (OwnershipKind::Owned,
@@ -260,9 +291,12 @@ void OwnershipLiveRange::convertToGuaranteedAndRAUW(
260291 SILValue newGuaranteedValue, InstModCallbacks callbacks) && {
261292 auto *value = cast<SingleValueInstruction>(introducer.value );
262293 while (!destroyingUses.empty ()) {
263- auto *d = destroyingUses.back ();
294+ auto point = destroyingUses.back ();
295+ auto *destroy = point.getInstruction ();
264296 destroyingUses = destroyingUses.drop_back ();
265- callbacks.deleteInst (d->getUser ());
297+ if (isa<TermInst>(destroy))
298+ continue ;
299+ callbacks.deleteInst (destroy);
266300 }
267301
268302 callbacks.eraseAndRAUWSingleValueInst (value, newGuaranteedValue);
@@ -318,9 +352,12 @@ void OwnershipLiveRange::convertJoinedLiveRangePhiToGuaranteed(
318352
319353 // Then eliminate all of the destroys...
320354 while (!destroyingUses.empty ()) {
321- auto *d = destroyingUses.back ();
355+ auto point = destroyingUses.back ();
356+ auto *destroy = point.getInstruction ();
322357 destroyingUses = destroyingUses.drop_back ();
323- callbacks.deleteInst (d->getUser ());
358+ if (isa<TermInst>(destroy))
359+ continue ;
360+ callbacks.deleteInst (destroy);
324361 }
325362
326363 // and change all of our guaranteed forwarding insts to have guaranteed
@@ -362,13 +399,3 @@ OwnershipLiveRange::hasUnknownConsumingUse(bool assumingAtFixPoint) const {
362399 // to our introducer.
363400 return HasConsumingUse_t::YesButAllPhiArgs;
364401}
365-
366- OwnershipLiveRange::DestroyingInstsRange
367- OwnershipLiveRange::getDestroyingInsts () const {
368- return DestroyingInstsRange (getDestroyingUses (), OperandToUser ());
369- }
370-
371- OwnershipLiveRange::ConsumingInstsRange
372- OwnershipLiveRange::getAllConsumingInsts () const {
373- return ConsumingInstsRange (consumingUses, OperandToUser ());
374- }
0 commit comments