@@ -274,6 +274,37 @@ bool CanonicalizeOSSALifetime::computeCanonicalLiveness() {
274
274
return true ;
275
275
}
276
276
277
+ // / Extend liveness to the availability boundary of currentDef. Even if a copy
278
+ // / is consumed on a path to the dead-end, if the def stays live through to the
279
+ // / dead-end, its lifetime must not be shrunk back from it (eventually we'll
280
+ // / support shrinking it back to deinit barriers).
281
+ // /
282
+ // / Example:
283
+ // / %def is lexical
284
+ // / %copy = copy_value %def
285
+ // / consume %copy
286
+ // / apply %foo() // deinit barrier
287
+ // / // Must extend lifetime of %def up to this point per language rules.
288
+ // / unreachable
289
+ void CanonicalizeOSSALifetime::extendLexicalLivenessToDeadEnds () {
290
+ // TODO: OSSALifetimeCompletion: Once lifetimes are always complete, delete
291
+ // this method.
292
+ SmallVector<SILBasicBlock *, 32 > directDiscoverdBlocks;
293
+ SSAPrunedLiveness directLiveness (function, &directDiscoverdBlocks);
294
+ directLiveness.initializeDef (getCurrentDef ());
295
+ directLiveness.computeSimple ();
296
+ OSSALifetimeCompletion::visitAvailabilityBoundary (
297
+ getCurrentDef (), directLiveness, [&](auto *unreachable, auto end) {
298
+ if (end == OSSALifetimeCompletion::LifetimeEnd::Boundary) {
299
+ recordUnreachableLifetimeEnd (unreachable);
300
+ }
301
+ unreachable->visitPriorInstructions ([&](auto *inst) {
302
+ liveness->extendToNonUse (inst);
303
+ return true ;
304
+ });
305
+ });
306
+ }
307
+
277
308
// / Extend liveness to the copy-extended availability boundary of currentDef.
278
309
// / Prevents destroys from being inserted between borrows of (copies of) the
279
310
// / def and dead-ends.
@@ -1368,6 +1399,9 @@ bool CanonicalizeOSSALifetime::computeLiveness() {
1368
1399
clear ();
1369
1400
return false ;
1370
1401
}
1402
+ if (respectsDeinitBarriers ()) {
1403
+ extendLexicalLivenessToDeadEnds ();
1404
+ }
1371
1405
extendLivenessToDeadEnds ();
1372
1406
if (respectsDeinitBarriers ()) {
1373
1407
extendLivenessToDeinitBarriers ();
0 commit comments