Skip to content

Commit 3e3a98f

Browse files
Merge pull request #64881 from nate-chandler/copy-propagation/forward-owned-lexical-values
[CanonicalizeOSSALifetime] Transfer lexical value into callee.
2 parents 7e15303 + 63e3ca7 commit 3e3a98f

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,23 @@ void CanonicalizeOSSALifetime::extendLivenessToDeinitBarriers() {
257257
[&](auto *inst) {
258258
if (inst == def)
259259
return true;
260-
return isDeinitBarrier(inst, calleeAnalysis);
260+
if (!isDeinitBarrier(inst, calleeAnalysis))
261+
return false;
262+
// For the most part, instructions that are deinit
263+
// barriers in the abstract are also deinit barriers
264+
// for the purposes of canonicalizing def's lifetime.
265+
//
266+
// There is an important exception: transferring an
267+
// owned lexical lifetime into a callee. If the
268+
// instruction is a full apply which consumes def,
269+
// then it isn't a deinit barrier. Keep looking for
270+
// barriers above it.
271+
auto apply = FullApplySite::isa(inst);
272+
if (!apply)
273+
return true;
274+
return liveness->isInterestingUser(inst) !=
275+
PrunedLiveness::IsInterestingUser::
276+
LifetimeEndingUse;
261277
});
262278
for (auto *barrier : barriers.instructions) {
263279
liveness->updateForUse(barrier, /*lifetimeEnding*/ false);

test/SILOptimizer/copy_propagation.sil

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ sil [ossa] @getOwnedC : $@convention(thin) () -> (@owned C)
2222
sil [ossa] @getOwnedB : $@convention(thin) () -> (@owned B)
2323
sil [ossa] @takeOwnedC : $@convention(thin) (@owned C) -> ()
2424
sil [ossa] @takeOwnedCTwice : $@convention(thin) (@owned C, @owned C) -> ()
25+
sil [ossa] @takeOwnedCAndGuaranteedC : $@convention(thin) (@owned C, @guaranteed C) -> ()
2526
sil [ossa] @takeGuaranteedC : $@convention(thin) (@guaranteed C) -> ()
2627
sil [ossa] @borrowB : $@convention(thin) (@guaranteed B) -> ()
2728
sil [ossa] @takeGuaranteedAnyObject : $@convention(thin) (@guaranteed AnyObject) -> ()
@@ -1016,3 +1017,33 @@ entry(%instance : @owned $C):
10161017
%retval = tuple ()
10171018
return %retval : $()
10181019
}
1020+
1021+
// CHECK-LABEL: sil [ossa] @forward_owned_lexical_value_to_callee : {{.*}} {
1022+
// CHECK-NOT: copy_value
1023+
// CHECK-LABEL: } // end sil function 'forward_owned_lexical_value_to_callee'
1024+
sil [ossa] @forward_owned_lexical_value_to_callee : $@convention(thin) (@owned C) -> () {
1025+
entry(%instance : @owned $C):
1026+
%copy = copy_value %instance : $C
1027+
%consume = function_ref @takeOwnedC : $@convention(thin) (@owned C) -> ()
1028+
apply %consume(%copy) : $@convention(thin) (@owned C) -> ()
1029+
destroy_value %instance : $C
1030+
%retval = tuple ()
1031+
return %retval : $()
1032+
}
1033+
1034+
// CHECK-LABEL: sil [ossa] @cantForwardBecauseBorrowing : {{.*}} {
1035+
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] :
1036+
// CHECK: [[COPY:%[^,]+]] = copy_value [[INSTANCE]]
1037+
// CHECK: [[CONSUME_AND_BORROW:%[^,]+]] = function_ref @takeOwnedCAndGuaranteedC
1038+
// CHECK: apply [[CONSUME_AND_BORROW]]([[COPY]], [[INSTANCE]])
1039+
// CHECK: destroy_value [[INSTANCE]]
1040+
// CHECK-LABEL: } // end sil function 'cantForwardBecauseBorrowing'
1041+
sil [ossa] @cantForwardBecauseBorrowing :$@convention(thin) (@owned C) -> () {
1042+
entry(%instance : @owned $C):
1043+
%copy = copy_value %instance : $C
1044+
%consumeAndBorrow = function_ref @takeOwnedCAndGuaranteedC : $@convention(thin) (@owned C, @guaranteed C) -> ()
1045+
apply %consumeAndBorrow(%copy, %instance) : $@convention(thin) (@owned C, @guaranteed C) -> ()
1046+
destroy_value %instance : $C
1047+
%retval = tuple ()
1048+
return %retval : $()
1049+
}

0 commit comments

Comments
 (0)