Skip to content

Commit 7e8410e

Browse files
committed
COWArrayOpt: handle load_borrow
1 parent d71f36b commit 7e8410e

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

lib/SILOptimizer/LoopTransforms/ArrayOpt.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,10 @@ class StructUseCollector {
8181

8282
UserList AggregateAddressUsers;
8383
UserList StructAddressUsers;
84-
SmallVector<LoadInst*, 16> StructLoads;
84+
SmallVector<SingleValueInstruction *, 16> StructLoads;
8585
UserList StructValueUsers;
8686
UserOperList ElementAddressUsers;
87-
SmallVector<std::pair<LoadInst*, Operand*>, 16> ElementLoads;
87+
SmallVector<std::pair<SingleValueInstruction *, Operand*>, 16> ElementLoads;
8888
UserOperList ElementValueUsers;
8989
VisitedSet Visited;
9090

@@ -126,7 +126,7 @@ class StructUseCollector {
126126
return false;
127127
for (SILInstruction *user : StructAddressUsers) {
128128
// ignore load users
129-
if (isa<LoadInst>(user))
129+
if (isa<LoadInst>(user) || isa<LoadBorrowInst>(user))
130130
continue;
131131
if (user != use1 && user != use2)
132132
return false;
@@ -162,8 +162,8 @@ class StructUseCollector {
162162
if (StructVal) {
163163
// Found a use of an element.
164164
assert(AccessPathSuffix.empty() && "should have accessed struct");
165-
if (auto *LoadI = dyn_cast<LoadInst>(UseInst)) {
166-
ElementLoads.push_back(std::make_pair(LoadI, StructVal));
165+
if (isa<LoadInst>(UseInst) || isa<LoadBorrowInst>(UseInst)) {
166+
ElementLoads.push_back(std::make_pair(cast<SingleValueInstruction>(UseInst), StructVal));
167167
continue;
168168
}
169169

@@ -185,9 +185,9 @@ class StructUseCollector {
185185

186186
if (AccessPathSuffix.empty()) {
187187
// Found a use of the struct at the given access path.
188-
if (auto *LoadI = dyn_cast<LoadInst>(UseInst)) {
189-
StructLoads.push_back(LoadI);
190-
StructAddressUsers.push_back(LoadI);
188+
if (isa<LoadInst>(UseInst) || isa<LoadBorrowInst>(UseInst)) {
189+
StructLoads.push_back(cast<SingleValueInstruction>(UseInst));
190+
StructAddressUsers.push_back(UseInst);
191191
continue;
192192
}
193193

lib/SILOptimizer/LoopTransforms/COWArrayOpt.cpp

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ bool areArraysEqual(RCIdentityFunctionInfo *RCIA, SILValue A, SILValue B,
5555
return true;
5656
// We have stripped off struct_extracts. Remove the load to look at the
5757
// address we are loading from.
58-
if (auto *ALoad = dyn_cast<LoadInst>(A))
59-
A = ALoad->getOperand();
60-
if (auto *BLoad = dyn_cast<LoadInst>(B))
61-
B = BLoad->getOperand();
58+
if (isa<LoadInst>(A) || isa<LoadBorrowInst>(A))
59+
A = cast<SingleValueInstruction>(A)->getOperand(0);
60+
if (isa<LoadInst>(B) || isa<LoadBorrowInst>(B))
61+
B = cast<SingleValueInstruction>(B)->getOperand(0);
6262
// Strip off struct_extract_refs until we hit array address.
6363
if (ArrayAddress) {
6464
StructElementAddrInst *SEAI = nullptr;
@@ -463,6 +463,10 @@ bool COWArrayOpt::checkSafeArrayAddressUses(UserList &AddressUsers) {
463463
return false;
464464
}
465465

466+
if (isa<LoadBorrowInst>(UseInst)) {
467+
continue;
468+
}
469+
466470
if (isa<DeallocStackInst>(UseInst)) {
467471
// Handle destruction of a local array.
468472
continue;
@@ -569,6 +573,9 @@ bool COWArrayOpt::checkSafeArrayValueUses(UserList &ArrayValueUsers) {
569573
if (isa<MarkDependenceInst>(UseInst))
570574
continue;
571575

576+
if (isa<EndBorrowInst>(UseInst))
577+
continue;
578+
572579
if (UseInst->isDebugInstruction())
573580
continue;
574581

test/SILOptimizer/cowarray_opt_ossa.sil

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,42 @@ bb2:
164164
return %r : $()
165165
}
166166

167+
// CHECK-LABEL: sil [ossa] @hoist_ignoring_paired_retain_release_and_hoist2_load_borrow :
168+
// CHECK: bb0([[ARRAY:%[0-9]+]]
169+
// CHECK: [[MM:%[0-9]+]] = function_ref @array_make_mutable
170+
// CHECK: apply [[MM]]([[ARRAY]]
171+
// CHECK: [[EM:%[0-9]+]] = function_ref @array_end_mutation
172+
// CHECK: apply [[EM]]([[ARRAY]]
173+
// CHECK: bb1:
174+
// CHECK: load_borrow
175+
// CHECK: end_borrow
176+
// CHECK: apply [[MM]]([[ARRAY]]
177+
// CHECK: apply [[EM]]([[ARRAY]]
178+
// CHECK: cond_br {{.*}}, bb2
179+
// CHECK: } // end sil function 'hoist_ignoring_paired_retain_release_and_hoist2_load_borrow'
180+
sil [ossa] @hoist_ignoring_paired_retain_release_and_hoist2_load_borrow : $@convention(thin) (@inout MyArray<MyStruct>, @inout Builtin.Int1) -> () {
181+
bb0(%0 : $*MyArray<MyStruct>, %1 : $*Builtin.Int1):
182+
%2 = load [copy] %0 : $*MyArray<MyStruct>
183+
br bb1
184+
185+
bb1:
186+
%b = load_borrow %0
187+
%3 = load [trivial] %1 : $*Builtin.Int1
188+
end_borrow %b
189+
%5 = function_ref @array_make_mutable : $@convention(method) (@inout MyArray<MyStruct>) -> ()
190+
%6 = apply %5(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
191+
%7 = function_ref @array_end_mutation : $@convention(method) (@inout MyArray<MyStruct>) -> ()
192+
%8 = apply %7(%0) : $@convention(method) (@inout MyArray<MyStruct>) -> ()
193+
cond_br %3, bb1a, bb2
194+
195+
bb1a:
196+
br bb1
197+
198+
bb2:
199+
destroy_value %2 : $MyArray<MyStruct>
200+
%r = tuple()
201+
return %r : $()
202+
}
167203
// CHECK-LABEL: sil [ossa] @hoist_blocked_by_unpaired_retain_release_1 :
168204
// CHECK: bb0(
169205
// CHECK-NOT: apply

0 commit comments

Comments
 (0)