Skip to content

Commit 3ba8a93

Browse files
committed
[ShrinkBorrowScope] Don't hoist over any applies.
Previously, hoisting was done over applies that were users of the borrowed value. Here, that is no longer done. That hoisting was done on the theory that multiple distinct lexical scopes were equivalent to a single enclosing lexical scope. Dead borrow elimination, however, means that they are not in fact the same, however: If a callee takes an object as an argument, and in that callee that argument is dead, FSO and inliniing (even with approaches to maintain lexical borrow scopes when the value that is borrowed comes from an owned argument) can result in a dead borrow scope in the caller which could then be eliminated which would then enable the destroy_value to be hoisted over the inlined body, including over barriers.
1 parent 9166233 commit 3ba8a93

File tree

4 files changed

+48
-59
lines changed

4 files changed

+48
-59
lines changed

lib/SILOptimizer/Utils/ShrinkBorrowScope.cpp

Lines changed: 1 addition & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,6 @@ class ShrinkBorrowScope {
5151
/// which is itself a deinit barrier.
5252
SmallPtrSet<SILBasicBlock *, 8> barredBlocks;
5353

54-
llvm::SmallDenseMap<ApplySite, size_t> transitiveUsesPerApplySite;
55-
5654
// The list of blocks to look for new points at which to insert end_borrows
5755
// in. A block must not be processed if all of its successors have not yet
5856
// been. For that reason, it is necessary to allow the same block to be
@@ -136,12 +134,6 @@ class ShrinkBorrowScope {
136134
}
137135
}
138136

139-
size_t usesInApply(ApplySite apply) {
140-
if (auto count = transitiveUsesPerApplySite.lookup(apply))
141-
return count;
142-
return 0;
143-
}
144-
145137
bool canHoistOverInstruction(SILInstruction *instruction) {
146138
return tryHoistOverInstruction(instruction, /*rewrite=*/false);
147139
}
@@ -151,36 +143,7 @@ class ShrinkBorrowScope {
151143
return false;
152144
}
153145
if (users.contains(instruction)) {
154-
if (auto apply = ApplySite::isa(instruction)) {
155-
SmallVector<int, 2> rewritableArgumentIndices;
156-
auto count = apply.getNumArguments();
157-
for (unsigned index = 0; index < count; ++index) {
158-
auto argument = apply.getArgument(index);
159-
if (canReplaceValueWithBorrowedValue(argument)) {
160-
rewritableArgumentIndices.push_back(index);
161-
}
162-
}
163-
if (rewritableArgumentIndices.size() != usesInApply(apply)) {
164-
return false;
165-
}
166-
if (rewrite) {
167-
// We can rewrite all the arguments which are transitive uses of the
168-
// borrow.
169-
for (auto index : rewritableArgumentIndices) {
170-
auto argument = apply.getArgument(index);
171-
auto borrowee = introducer->getOperand();
172-
if (auto *cvi = dyn_cast<CopyValueInst>(argument)) {
173-
cvi->setOperand(borrowee);
174-
modifiedCopyValueInsts.push_back(cvi);
175-
madeChange = true;
176-
} else {
177-
apply.setArgument(index, borrowee);
178-
madeChange = true;
179-
}
180-
}
181-
}
182-
return true;
183-
} else if (auto *bbi = dyn_cast<BeginBorrowInst>(instruction)) {
146+
if (auto *bbi = dyn_cast<BeginBorrowInst>(instruction)) {
184147
if (bbi->isLexical() &&
185148
canReplaceValueWithBorrowedValue(bbi->getOperand())) {
186149
if (rewrite) {
@@ -237,9 +200,6 @@ bool ShrinkBorrowScope::populateUsers() {
237200
for (auto *use : uses) {
238201
auto *user = use->getUser();
239202
users.insert(user);
240-
if (auto apply = ApplySite::isa(user)) {
241-
++transitiveUsesPerApplySite[apply];
242-
}
243203
}
244204
return true;
245205
}

test/SILOptimizer/copy_propagation_borrow.sil

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -394,9 +394,11 @@ bb3:
394394
// CHECK: [[ALLOC:%.*]] = alloc_ref $C
395395
// CHECK-NEXT: [[B1:%.*]] = begin_borrow [[ALLOC]]
396396
// CHECK-NOT: copy
397+
// CHECK: [[B2:%.*]] = begin_borrow [[ALLOC]]
397398
// CHECK-NOT: copy
398399
// CHECK: end_borrow [[B1]] : $C
399-
// CHECK: apply %0([[ALLOC]]) : $@convention(thin) (@guaranteed C) -> ()
400+
// CHECK: apply %0([[B2]]) : $@convention(thin) (@guaranteed C) -> ()
401+
// CHECK: end_borrow [[B2]] : $C
400402
// CHECK-NEXT: return [[ALLOC]] : $C
401403
// CHECK-LABEL: } // end sil function 'testInterleavedBorrow'
402404
sil [ossa] @testInterleavedBorrow : $@convention(thin) () -> @owned C {
@@ -426,11 +428,14 @@ bb0:
426428
// CHECK: [[B1:%.*]] = begin_borrow [[ALLOC]]
427429
// CHECK: apply %{{.*}}([[B1]]) : $@convention(thin) (@guaranteed C) -> ()
428430
// CHECK-NEXT: end_borrow [[B1]] : $C
431+
// CHECK-NEXT: [[B2:%.*]] = begin_borrow [[ALLOC]]
429432
// CHECK-NEXT: cond_br undef, bb1, bb2
430433
// CHECK: bb1:
431-
// CHECK: apply %{{.*}}([[ALLOC]]) : $@convention(thin) (@guaranteed C) -> ()
434+
// CHECK: apply %{{.*}}([[B2]]) : $@convention(thin) (@guaranteed C) -> ()
435+
// CHECK-NEXT: end_borrow [[B2]] : $C
432436
// CHECK-NEXT: br bb3
433437
// CHECK: bb2:
438+
// CHECK-NEXT: end_borrow [[B2]] : $C
434439
// CHECK-NEXT: br bb3
435440
// CHECK: bb3:
436441
// CHECK-NEXT: return [[ALLOC]] : $C

test/SILOptimizer/shrink_borrow_scope.sil

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,10 @@ sil [ossa] @synchronization_point : $@convention(thin) () -> ()
4444
// Hoist over br.
4545
// CHECK-LABEL: sil [ossa] @hoist_over_branch_1 : {{.*}} {
4646
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
47+
// CHECK: [[LIFETIME:%[^,]]] = begin_borrow [[INSTANCE]]
4748
// CHECK: [[CALLEE_GUARANTEED:%[^,]+]] = function_ref @callee_guaranteed
48-
// CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[INSTANCE]])
49+
// CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[LIFETIME]])
50+
// CHECK: end_borrow [[LIFETIME]]
4951
// CHECK: br [[EXIT:bb[0-9]+]]
5052
// CHECK: [[EXIT]]:
5153
// CHECK: return [[INSTANCE]]
@@ -64,8 +66,10 @@ bl1:
6466
// Hoist over cond_br.
6567
// CHECK-LABEL: sil [ossa] @hoist_over_branch_2 : {{.*}} {
6668
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
69+
// CHECK: [[LIFETIME:%[^,]]] = begin_borrow [[INSTANCE]]
6770
// CHECK: [[CALLEE_GUARANTEED:%[^,]+]] = function_ref @callee_guaranteed
68-
// CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[INSTANCE]])
71+
// CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[LIFETIME]])
72+
// CHECK: end_borrow [[LIFETIME]]
6973
// CHECK: cond_br undef, [[BL1:bb[0-9]+]], [[BL2:bb[0-9]+]]
7074
// CHECK: [[BL1]]:
7175
// CHECK: br [[EXIT:bb[0-9]+]]
@@ -93,8 +97,10 @@ exit:
9397
// Hoist over two brs.
9498
// CHECK-LABEL: sil [ossa] @hoist_over_branch_3 : {{.*}} {
9599
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
100+
// CHECK: [[LIFETIME:%[^,]]] = begin_borrow [[INSTANCE]]
96101
// CHECK: [[CALLEE_GUARANTEED:%[^,]+]] = function_ref @callee_guaranteed
97-
// CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[INSTANCE]])
102+
// CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[LIFETIME]])
103+
// CHECK: end_borrow [[LIFETIME]]
98104
// CHECK: cond_br undef, [[BL1:bb[0-9]+]], [[BL2:bb[0-9]+]]
99105
// CHECK: [[BL1]]:
100106
// CHECK: br [[EXIT:bb[0-9]+]]
@@ -121,12 +127,15 @@ exit:
121127
// Don't hoist over 1 / 2 brs.
122128
// CHECK-LABEL: sil [ossa] @hoist_over_branch_4 : {{.*}} {
123129
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
130+
// CHECK: [[LIFETIME:%[^,]]] = begin_borrow [[INSTANCE]]
124131
// CHECK: cond_br undef, [[BL1:bb[0-9]+]], [[BL2:bb[0-9]+]]
125132
// CHECK: [[BL1]]:
126133
// CHECK: [[CALLEE_GUARANTEED:%[^,]+]] = function_ref @callee_guaranteed
127-
// CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[INSTANCE]])
134+
// CHECK: {{%[^,]+}} = apply [[CALLEE_GUARANTEED]]([[LIFETIME]])
135+
// CHECK: end_borrow [[LIFETIME]]
128136
// CHECK: br [[EXIT:bb[0-9]+]]
129137
// CHECK: [[BL2]]:
138+
// CHECK: end_borrow [[LIFETIME]]
130139
// CHECK: br [[EXIT]]
131140
// CHECK: [[EXIT]]:
132141
// CHECK: return [[INSTANCE]]
@@ -149,8 +158,10 @@ exit:
149158
// Hoist over switch_enum destinations.
150159
// CHECK-LABEL: sil [ossa] @hoist_over_branch_5 : {{.*}} {
151160
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C, [[CASE:%[^,]+]] : $OneOfThree):
161+
// CHECK: [[LIFETIME:%[^,]]] = begin_borrow [[INSTANCE]]
152162
// CHECK: [[CALLEE_GUARANTEED:%[^,]+]] = function_ref @callee_guaranteed
153-
// CHECK: {{%[0-9]+}} = apply [[CALLEE_GUARANTEED]]([[INSTANCE]])
163+
// CHECK: {{%[0-9]+}} = apply [[CALLEE_GUARANTEED]]([[LIFETIME]])
164+
// CHECK: end_borrow [[LIFETIME]]
154165
// CHECK: switch_enum [[CASE]] : $OneOfThree, case #OneOfThree.one!enumelt: [[ONE_DEST:bb[0-9]+]], case #OneOfThree.two!enumelt: [[TWO_DEST:bb[0-9]+]], case #OneOfThree.three!enumelt: [[THREE_DEST:bb[0-9]+]]
155166
// CHECK: [[ONE_DEST]]:
156167
// CHECK: br [[EXIT:bb[0-9]+]]
@@ -590,11 +601,15 @@ entry(%instance : @guaranteed $C):
590601
return %result : $()
591602
}
592603

593-
// Hoist over an apply that uses a copy of the borrow.
594-
// CHECK-LABEL: sil [ossa] @hoist_over_apply_at_copy : {{.*}} {
595-
// CHECK-NOT: copy_value
596-
// CHECK-LABEL: } // end sil function 'hoist_over_apply_at_copy'
597-
sil [ossa] @hoist_over_apply_at_copy : $@convention(thin) (@owned C) -> () {
604+
// Don't hoist over an apply that uses a copy of the borrow.
605+
// CHECK-LABEL: sil [ossa] @dont_hoist_over_apply_at_copy : {{.*}} {
606+
// CHECK: begin_borrow
607+
// CHECK: copy_value
608+
// CHECK: apply
609+
// CHECK: end_borrow
610+
// CHECK: destroy_value
611+
// CHECK-LABEL: } // end sil function 'dont_hoist_over_apply_at_copy'
612+
sil [ossa] @dont_hoist_over_apply_at_copy : $@convention(thin) (@owned C) -> () {
598613
entry(%instance : @owned $C):
599614
%synchronization_point = function_ref @synchronization_point : $@convention(thin) () -> ()
600615
%callee_owned = function_ref @callee_owned : $@convention(thin) (@owned C) -> ()
@@ -612,12 +627,12 @@ entry(%instance : @owned $C):
612627
return %result : $()
613628
}
614629

615-
// Hoist over an apply that uses the borrow.
630+
// Don't hoist over an apply that uses the borrow.
616631
// CHECK-LABEL: sil [ossa] @hoist_over_apply_at_borrow : {{.*}} {
617632
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
618633
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[INSTANCE]]
634+
// CHECK: apply {{%[^,]+}}([[LIFETIME]])
619635
// CHECK: end_borrow [[LIFETIME]]
620-
// CHECK: apply {{%[^,]+}}([[INSTANCE]])
621636
// CHECK-LABEL: } // end sil function 'hoist_over_apply_at_borrow'
622637
sil [ossa] @hoist_over_apply_at_borrow : $@convention(thin) (@owned C) -> () {
623638
entry(%instance : @owned $C):
@@ -695,11 +710,18 @@ entry(%instance : @owned $C):
695710
return %result : $()
696711
}
697712

698-
// CHECK-LABEL: sil [ossa] @hoist_over_try_apply_at_borrow : {{.*}} {
713+
// CHECK-LABEL: sil [ossa] @dont_hoist_over_try_apply_at_borrow : {{.*}} {
699714
// CHECK: {{bb[0-9]+}}([[INSTANCE:%[^,]+]] : @owned $C):
700-
// CHECK-NEXT: try_apply undef([[INSTANCE]]) : $@convention(thin) (@guaranteed C) -> @error Error, normal bb1, error bb2
701-
// CHECK-LABEL: } // end sil function 'hoist_over_try_apply_at_borrow'
702-
sil [ossa] @hoist_over_try_apply_at_borrow : $@convention(thin) (@owned C) -> @error Error {
715+
// CHECK: [[LIFETIME:%[^,]+]] = begin_borrow [[INSTANCE]]
716+
// CHECK: try_apply undef([[LIFETIME]]) : {{.*}}, normal [[GOOD:bb[0-9]+]], error [[BAD:bb[0-9]+]]
717+
// CHECK: [[GOOD]]
718+
// CHECK: end_borrow [[LIFETIME]]
719+
// CHECK: destroy_value [[INSTANCE]]
720+
// CHECK: [[BAD]]
721+
// CHECK: end_borrow [[LIFETIME]]
722+
// CHECK: destroy_value [[INSTANCE]]
723+
// CHECK-LABEL: } // end sil function 'dont_hoist_over_try_apply_at_borrow'
724+
sil [ossa] @dont_hoist_over_try_apply_at_borrow : $@convention(thin) (@owned C) -> @error Error {
703725
bb0(%instance : @owned $C):
704726
%lifetime = begin_borrow %instance : $C
705727
try_apply undef(%lifetime) : $@convention(thin) (@guaranteed C) -> @error Error, normal good, error bad

test/SILOptimizer/shrink_borrow_scope.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
// RUN: %target-swift-frontend -c -O -enable-copy-propagation=true -enable-lexical-lifetimes=true -sil-verify-all -Xllvm -sil-print-final-ossa-module %s | %FileCheck %s
22

3+
// REQUIRES: rdar87255563
4+
35
// =============================================================================
46
// = DECLARATIONS {{
57
// =============================================================================

0 commit comments

Comments
 (0)