Skip to content

Commit 2cebca5

Browse files
committed
[OSSACanOwned] Dead-end extend base lifetime.
Regardless of consumes of copies, if the original lexical value is not consumed on a dead-end path, it must remain live to that dead-end. rdar://145226757
1 parent 0fabb6c commit 2cebca5

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed

include/swift/SILOptimizer/Utils/CanonicalizeOSSALifetime.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ class CanonicalizeOSSALifetime final {
499499
PrunedLivenessBoundary &boundary);
500500

501501
void extendLivenessToDeadEnds();
502+
void extendLexicalLivenessToDeadEnds();
502503
void extendLivenessToDeinitBarriers();
503504

504505
void extendUnconsumedLiveness(PrunedLivenessBoundary const &boundary);

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,29 @@ bool CanonicalizeOSSALifetime::computeCanonicalLiveness() {
274274
return true;
275275
}
276276

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+
void CanonicalizeOSSALifetime::extendLexicalLivenessToDeadEnds() {
282+
// TODO: OSSALifetimeCompletion: Once lifetimes are always complete, delete
283+
// this method.
284+
SmallVector<SILBasicBlock *, 32> lexicalDiscoverdBlocks;
285+
SSAPrunedLiveness lexicalLiveness(function, &lexicalDiscoverdBlocks);
286+
lexicalLiveness.initializeDef(getCurrentDef());
287+
lexicalLiveness.computeSimple();
288+
OSSALifetimeCompletion::visitAvailabilityBoundary(
289+
getCurrentDef(), lexicalLiveness, [&](auto *unreachable, auto end) {
290+
if (end == OSSALifetimeCompletion::LifetimeEnd::Boundary) {
291+
recordUnreachableLifetimeEnd(unreachable);
292+
}
293+
unreachable->visitPriorInstructions([&](auto *inst) {
294+
liveness->extendToNonUse(inst);
295+
return true;
296+
});
297+
});
298+
}
299+
277300
/// Extend liveness to the copy-extended availability boundary of currentDef.
278301
/// Prevents destroys from being inserted between borrows of (copies of) the
279302
/// def and dead-ends.
@@ -1359,6 +1382,9 @@ bool CanonicalizeOSSALifetime::computeLiveness() {
13591382
clear();
13601383
return false;
13611384
}
1385+
if (respectsDeinitBarriers()) {
1386+
extendLexicalLivenessToDeadEnds();
1387+
}
13621388
extendLivenessToDeadEnds();
13631389
if (respectsDeinitBarriers()) {
13641390
extendLivenessToDeinitBarriers();

test/SILOptimizer/canonicalize_ossa_lifetime_unit.sil

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
import Swift
44

55
class C {}
6+
7+
enum Never {}
8+
sil @run : $@convention(thin) () -> Never
69
sil @getOwned : $@convention(thin) () -> @owned C
710
sil @barrier : $@convention(thin) () -> ()
811
sil [ossa] @getC : $@convention(thin) () -> @owned C
@@ -945,3 +948,18 @@ entry(%a: @owned $C):
945948
%retval = tuple ()
946949
return %retval
947950
}
951+
952+
// CHECK-LABEL: begin running test {{.*}} on extend_lifetime_to_deadend_despite_copy_consume
953+
// CHECK-LABEL: sil [ossa] @extend_lifetime_to_deadend_despite_copy_consume : {{.*}} {
954+
// CHECK: copy_value
955+
// CHECK-LABEL: } // end sil function 'extend_lifetime_to_deadend_despite_copy_consume'
956+
// CHECK-LABEL: end running test {{.*}} on extend_lifetime_to_deadend_despite_copy_consume
957+
sil [ossa] @extend_lifetime_to_deadend_despite_copy_consume : $@convention(thin) (@owned C) -> () {
958+
entry(%c : @owned $C):
959+
specify_test "canonicalize_ossa_lifetime true false true @argument"
960+
%cc = copy_value %c
961+
%takeC = function_ref @takeC : $@convention(thin) (@owned C) -> ()
962+
apply %takeC(%cc) : $@convention(thin) (@owned C) -> ()
963+
%run = function_ref @run : $@convention(thin) () -> Never
964+
unreachable
965+
}

0 commit comments

Comments
 (0)