15
15
16
16
#include " swift/Basic/Assertions.h"
17
17
#include " swift/SIL/BasicBlockUtils.h"
18
+ #include " swift/SIL/OSSALifetimeCompletion.h"
18
19
#include " swift/SIL/OwnershipUtils.h"
19
20
20
21
using namespace swift ;
21
22
using namespace swift ::semanticarc;
22
23
23
- OwnershipLiveRange::OwnershipLiveRange (SILValue value)
24
+ OwnershipLiveRange::OwnershipLiveRange (
25
+ SILValue value, ArrayRef<std::pair<Operand *, SILValue>> extraUses)
24
26
: introducer(OwnedValueIntroducer::get(value)), destroyingUses(),
25
27
ownershipForwardingUses(), unknownConsumingUses() {
26
28
assert (introducer);
27
29
assert (introducer.value ->getOwnershipKind () == OwnershipKind::Owned);
28
30
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);
32
37
33
38
// We know that our silvalue produces an @owned value. Look through all of our
34
39
// uses and classify them as either consuming or not.
@@ -111,6 +116,7 @@ OwnershipLiveRange::OwnershipLiveRange(SILValue value)
111
116
continue ;
112
117
}
113
118
llvm::copy (v->getUses (), std::back_inserter (worklist));
119
+ defs.push_back (v);
114
120
}
115
121
continue ;
116
122
}
@@ -138,8 +144,32 @@ OwnershipLiveRange::OwnershipLiveRange(SILValue value)
138
144
// Otherwise add all users of this BBArg to the worklist to visit
139
145
// recursively.
140
146
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 ;
141
163
}
164
+ liveness.updateForUse (use.first ->getUser (), /* lifetimeEnding=*/ true );
142
165
}
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
+ });
143
173
}
144
174
145
175
// The order in which we append these to consumingUses matters since we assume
@@ -248,7 +278,8 @@ void OwnershipLiveRange::insertEndBorrowsAtDestroys(
248
278
249
279
void OwnershipLiveRange::convertOwnedGeneralForwardingUsesToGuaranteed () && {
250
280
while (!ownershipForwardingUses.empty ()) {
251
- auto *use = ownershipForwardingUses.back ();
281
+ auto point = ownershipForwardingUses.back ();
282
+ auto *use = point.getOperand ();
252
283
ownershipForwardingUses = ownershipForwardingUses.drop_back ();
253
284
ForwardingOperand operand (use);
254
285
operand.replaceOwnershipKind (OwnershipKind::Owned,
@@ -260,9 +291,12 @@ void OwnershipLiveRange::convertToGuaranteedAndRAUW(
260
291
SILValue newGuaranteedValue, InstModCallbacks callbacks) && {
261
292
auto *value = cast<SingleValueInstruction>(introducer.value );
262
293
while (!destroyingUses.empty ()) {
263
- auto *d = destroyingUses.back ();
294
+ auto point = destroyingUses.back ();
295
+ auto *destroy = point.getInstruction ();
264
296
destroyingUses = destroyingUses.drop_back ();
265
- callbacks.deleteInst (d->getUser ());
297
+ if (isa<TermInst>(destroy))
298
+ continue ;
299
+ callbacks.deleteInst (destroy);
266
300
}
267
301
268
302
callbacks.eraseAndRAUWSingleValueInst (value, newGuaranteedValue);
@@ -318,9 +352,12 @@ void OwnershipLiveRange::convertJoinedLiveRangePhiToGuaranteed(
318
352
319
353
// Then eliminate all of the destroys...
320
354
while (!destroyingUses.empty ()) {
321
- auto *d = destroyingUses.back ();
355
+ auto point = destroyingUses.back ();
356
+ auto *destroy = point.getInstruction ();
322
357
destroyingUses = destroyingUses.drop_back ();
323
- callbacks.deleteInst (d->getUser ());
358
+ if (isa<TermInst>(destroy))
359
+ continue ;
360
+ callbacks.deleteInst (destroy);
324
361
}
325
362
326
363
// and change all of our guaranteed forwarding insts to have guaranteed
@@ -362,13 +399,3 @@ OwnershipLiveRange::hasUnknownConsumingUse(bool assumingAtFixPoint) const {
362
399
// to our introducer.
363
400
return HasConsumingUse_t::YesButAllPhiArgs;
364
401
}
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