Skip to content

Commit f0d76fa

Browse files
Merge pull request #65458 from nate-chandler/guaranteed-copy-propagation/forwarding-inner-uses-during-outer-rewriting
[CanonicalizeBorrowScope] Allow inner forwarding value unmapped to outer value during outer rewriting.
2 parents 2e36235 + 78d0660 commit f0d76fa

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

lib/SILOptimizer/Utils/CanonicalizeBorrowScope.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,14 @@ SILValue CanonicalizeBorrowScope::findDefInBorrowScope(SILValue value) {
200200
return value;
201201
}
202202

203-
/// Visit all extended uses within the borrow scope, looking through copies.
204-
/// Call visitUse for uses which could potentially be outside the borrow scope.
205-
/// Call visitForwardingUse for hoistable forwarding operations which could
206-
/// potentially be inside the borrow scope.
203+
/// Visit all extended uses within the borrow scope, looking through copies and
204+
/// moves. Call visitUse for uses which could potentially be outside the borrow
205+
/// scope. Call visitForwardingUse for hoistable forwarding operations which
206+
/// could potentially be inside the borrow scope.
207207
///
208208
/// The visitor may or may not be able to determine which uses are outside the
209209
/// scope, but it can filter uses that are definitely within the scope. For
210-
/// example, guaranteed uses and uses in live-out blocks must be both be within
210+
/// example, guaranteed uses and uses in live-out blocks must both be within
211211
/// the scope.
212212
///
213213
/// This def-use traversal is similar to findExtendedTransitiveGuaranteedUses(),
@@ -638,7 +638,9 @@ class RewriteOuterBorrowUses {
638638
assert(succeed && "should be filtered by FindBorrowScopeUses");
639639

640640
auto iter = innerToOuterMap.find(innerValue);
641-
assert(iter != innerToOuterMap.end());
641+
if (iter == innerToOuterMap.end()) {
642+
return SILValue();
643+
}
642644
SILValue outerValue = iter->second;
643645
cleanupOuterValue(outerValue);
644646
return outerValue;

test/SILOptimizer/canonicalize_borrow_scope_unit.sil

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@ import Builtin
44

55
typealias AnyObject = Builtin.AnyObject
66

7+
class C {}
8+
class D : C {}
9+
10+
sil @getD : $() -> (@owned D)
11+
sil @takeC : $(@owned C) -> ()
12+
713
struct Unmanaged<Instance> where Instance : AnyObject {
814
unowned(unsafe) var _value: @sil_unmanaged Instance
915
}
@@ -57,3 +63,37 @@ bb0(%instance : @guaranteed $Instance):
5763
%retval = struct $Unmanaged<Instance> (%unmanaged : $@sil_unmanaged Instance)
5864
return %retval : $Unmanaged<Instance>
5965
}
66+
67+
// CHECK-LABEL: begin running test {{.*}} on dont_rewrite_inner_forwarding_user: canonicalize-borrow-scope
68+
// CHECK-LABEL: sil [ossa] @dont_rewrite_inner_forwarding_user : {{.*}} {
69+
// CHECK: [[GET_C:%[^,]+]] = function_ref @getD
70+
// CHECK: [[TAKE_C:%[^,]+]] = function_ref @takeC
71+
// CHECK: [[C:%[^,]+]] = apply [[GET_C]]()
72+
// CHECK: [[OUTER_COPY:%[^,]+]] = copy_value [[C]]
73+
// CHECK: [[OUTER_UPCAST:%[^,]+]] = upcast [[OUTER_COPY]]
74+
// CHECK: [[B:%[^,]+]] = begin_borrow [[C]]
75+
// CHECK: [[DEAD_INNER_COPY:%[^,]+]] = copy_value [[B]]
76+
// CHECK: destroy_value [[DEAD_INNER_COPY]]
77+
// CHECK: [[U:%[^,]+]] = upcast [[B]]
78+
// CHECK: [[C1:%[^,]+]] = copy_value [[U]]
79+
// CHECK: apply [[TAKE_C]]([[C1]])
80+
// CHECK: end_borrow [[B]]
81+
// CHECK: destroy_value [[C]]
82+
// CHECK: return [[OUTER_UPCAST]]
83+
// CHECK-LABEL: } // end sil function 'dont_rewrite_inner_forwarding_user'
84+
// CHECK-LABEL: end running test {{.*}} on dont_rewrite_inner_forwarding_user: canonicalize-borrow-scope
85+
sil [ossa] @dont_rewrite_inner_forwarding_user : $@convention(thin) () -> (@owned C) {
86+
%getD = function_ref @getD : $@convention(thin) () -> (@owned D)
87+
%takeC = function_ref @takeC : $@convention(thin) (@owned C) -> ()
88+
%d = apply %getD() : $@convention(thin) () -> (@owned D)
89+
test_specification "canonicalize-borrow-scope @instruction"
90+
%b = begin_borrow %d : $D
91+
%c2 = copy_value %b : $D
92+
%u2 = upcast %c2 : $D to $C
93+
%c1 = copy_value %b : $D
94+
%u1 = upcast %c1 : $D to $C
95+
apply %takeC(%u1) : $@convention(thin) (@owned C) -> ()
96+
end_borrow %b : $D
97+
destroy_value %d : $D
98+
return %u2 : $C
99+
}

0 commit comments

Comments
 (0)