@@ -80,6 +80,9 @@ static SILInstruction *endOSSALifetime(SILValue value,
80
80
if (auto scopedAddress = ScopedAddressValue (value)) {
81
81
return scopedAddress.createScopeEnd (builder.getInsertionPoint (), loc);
82
82
}
83
+ if (value->getOwnershipKind () == OwnershipKind::None) {
84
+ return builder.createExtendLifetime (loc, value);
85
+ }
83
86
return builder.createEndBorrow (loc, lookThroughBorrowedFromUser (value));
84
87
}
85
88
@@ -297,9 +300,16 @@ void AvailabilityBoundaryVisitor::computeRegion(
297
300
regionWorklist.push (block);
298
301
};
299
302
300
- for (auto *endBlock : boundary.endBlocks ) {
301
- if (!consumingBlocks.contains (endBlock)) {
302
- collect (endBlock);
303
+ // Trivial values that correspond to local variables (as opposed to
304
+ // ScopedAddresses) are available only up to their last extend_lifetime on
305
+ // non-dead-end paths. They cannot be consumed, but are only "available" up to
306
+ // the end of their scope.
307
+ if (value->getOwnershipKind () != OwnershipKind::None
308
+ || ScopedAddressValue (value)) {
309
+ for (auto *endBlock : boundary.endBlocks ) {
310
+ if (!consumingBlocks.contains (endBlock)) {
311
+ collect (endBlock);
312
+ }
303
313
}
304
314
}
305
315
for (SILBasicBlock *edge : boundary.boundaryEdges ) {
@@ -497,12 +507,21 @@ bool OSSALifetimeCompletion::analyzeAndUpdateLifetime(SILValue value,
497
507
if (auto scopedAddress = ScopedAddressValue (value)) {
498
508
return analyzeAndUpdateLifetime (scopedAddress, boundary);
499
509
}
500
-
501
510
// Called for inner borrows, inner adjacent reborrows, inner reborrows, and
502
511
// scoped addresses.
503
512
auto handleInnerScope = [this , boundary](SILValue innerBorrowedValue) {
504
513
completeOSSALifetime (innerBorrowedValue, boundary);
505
514
};
515
+ if (value->getOwnershipKind () == OwnershipKind::None) {
516
+ // Trivial variable lifetimes are only relevant up to the extend_lifetime
517
+ // instructions emitted by SILGen. Their other uses have no meaning with
518
+ // respect to lifetime. The only purpose of "completing" their lifetime is
519
+ // to insert extend_lifetime on dead-end blocks.
520
+ LinearLiveness liveness (value);
521
+ liveness.compute ();
522
+ return endLifetimeAtBoundary (value, liveness.getLiveness (), boundary,
523
+ deadEndBlocks);
524
+ }
506
525
InteriorLiveness liveness (value);
507
526
liveness.compute (domInfo, handleInnerScope);
508
527
// TODO: Rebuild outer adjacent phis on demand (SILGen does not currently
0 commit comments