Skip to content

Commit 81242bb

Browse files
committed
[OSSACanOwned] Don't walk into reborrow copies.
Because discovery of defs walks into reborrows and borrowed-from instructions, copies may be seen whose underlying value is a guaranteed value (namely, a reborrow or a borrowed-from instruction). Such copies may be used beyond the lifetime end of such guaranteed values, so it's not allowed to sink copies to their consuming uses. Such canonicalization is the responsibility of the OSSACanonicalizeGuaranteed utility. rdar://139842132
1 parent d881f92 commit 81242bb

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

lib/SILOptimizer/Utils/CanonicalizeOSSALifetime.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,16 @@ bool CanonicalizeOSSALifetime::computeCanonicalLiveness() {
165165
auto *user = use->getUser();
166166
// Recurse through copies.
167167
if (auto *copy = dyn_cast<CopyValueInst>(user)) {
168-
addDefToWorklist(Def::copy(copy));
168+
// Don't recurse through copies of borrowed-froms or reborrows.
169+
switch (def) {
170+
case Def::Kind::Root:
171+
case Def::Kind::Copy:
172+
addDefToWorklist(Def::copy(copy));
173+
break;
174+
case Def::Kind::Reborrow:
175+
case Def::Kind::BorrowedFrom:
176+
break;
177+
}
169178
continue;
170179
}
171180
if (auto *bfi = dyn_cast<BorrowedFromInst>(user)) {

test/SILOptimizer/canonicalize_ossa_lifetime_unit.sil

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -789,3 +789,71 @@ entry(%c : @owned $C):
789789
specify_test "canonicalize_ossa_lifetime true false true %c"
790790
unreachable
791791
}
792+
793+
// CHECK-LABEL: begin running test {{.*}} on consume_copy_of_borrowed_from
794+
// CHECK-LABEL: sil [ossa] @consume_copy_of_borrowed_from : {{.*}} {
795+
// The copy can't be eliminated because it's a copy of a borrowed-from. Such
796+
// copies are not rewritten.
797+
// CHECK: copy_value
798+
// CHECK-LABEL: } // end sil function 'consume_copy_of_borrowed_from'
799+
// CHECK-LABEL: end running test {{.*}} on consume_copy_of_borrowed_from
800+
sil [ossa] @consume_copy_of_borrowed_from : $@convention(thin) (@owned C) -> () {
801+
bb0(%instance : @owned $C):
802+
%borrow = begin_borrow %instance : $C
803+
br bb1(%instance : $C, %borrow : $C)
804+
805+
bb1(%instance2 : @owned $C, %reborrowed : @reborrow $C):
806+
specify_test "canonicalize_ossa_lifetime true false true %instance2"
807+
%reborrow = borrowed %reborrowed : $C from (%instance2 : $C)
808+
cond_br undef, bb2, bb3
809+
810+
bb2:
811+
end_borrow %reborrow : $C
812+
destroy_value %instance2 : $C
813+
%retval = tuple ()
814+
return %retval : $()
815+
816+
bb3:
817+
%copy = copy_value %reborrow : $C
818+
%takeC = function_ref @takeC : $@convention(thin) (@owned C) -> ()
819+
apply %takeC(%copy) : $@convention(thin) (@owned C) -> ()
820+
unreachable
821+
}
822+
823+
// CHECK-LABEL: begin running test {{.*}} on consume_copy_of_borrowed_from_2
824+
// CHECK-LABEL: sil [ossa] @consume_copy_of_borrowed_from_2 : {{.*}} {
825+
// The copy can't be eliminated because it's a copy of a borrowed-from. Such
826+
// copies are not rewritten.
827+
// CHECK: copy_value
828+
// CHECK-LABEL: } // end sil function 'consume_copy_of_borrowed_from_2'
829+
// CHECK-LABEL: end running test {{.*}} on consume_copy_of_borrowed_from_2
830+
sil [ossa] @consume_copy_of_borrowed_from_2 : $@convention(thin) (@owned C) -> () {
831+
bb0(%instance : @owned $C):
832+
%borrow = begin_borrow %instance : $C
833+
br bb1(%instance : $C, %borrow : $C)
834+
835+
bb1(%instance2 : @owned $C, %reborrowed : @reborrow $C):
836+
specify_test "canonicalize_ossa_lifetime true false true %instance2"
837+
%reborrow = borrowed %reborrowed : $C from (%instance2 : $C)
838+
cond_br undef, bb2, bb3
839+
840+
bb2:
841+
end_borrow %reborrow : $C
842+
destroy_value %instance2 : $C
843+
br exit
844+
845+
bb3:
846+
%copy = copy_value %reborrow : $C
847+
end_borrow %reborrow : $C
848+
destroy_value %instance2 : $C
849+
br bb4
850+
851+
bb4:
852+
%takeC = function_ref @takeC : $@convention(thin) (@owned C) -> ()
853+
apply %takeC(%copy) : $@convention(thin) (@owned C) -> ()
854+
br exit
855+
856+
exit:
857+
%retval = tuple ()
858+
return %retval : $()
859+
}

0 commit comments

Comments
 (0)