Skip to content

Commit 46a3b41

Browse files
authored
Merge pull request #68203 from atrick/5.9-fix-dse-capture-effects
[5.9] Fix SIL function side effects to handle unapplied escaping closures
2 parents c24866b + a41592d commit 46a3b41

File tree

3 files changed

+54
-3
lines changed

3 files changed

+54
-3
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/ComputeSideEffects.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,24 @@ private struct CollectedEffects {
142142
handleApply(pa)
143143
checkedIfDeinitBarrier = true
144144
}
145+
// In addition to the effects of the apply, also consider the
146+
// effects of the capture, which reads the captured value in
147+
// order to move it into the context. This only applies to
148+
// addressible values, because capturing does not dereference
149+
// any class objects.
150+
//
151+
// Ignore captures for on-stack partial applies. They only
152+
// bitwise-move or capture by address, so the call to
153+
// handleApply above is sufficient. And, if they are not applied
154+
// in this function, then they are never applied.
155+
if !pa.isOnStack {
156+
// callee is never an address.
157+
for argument in pa.arguments {
158+
if argument.type.isAddress {
159+
addEffects(.read, to: argument)
160+
}
161+
}
162+
}
145163

146164
case let fl as FixLifetimeInst:
147165
// A fix_lifetime instruction acts like a read on the operand to prevent

test/SILOptimizer/dead_store_elim.sil

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-sil-opt %s -dead-store-elim -max-partial-store-count=2 -enable-sil-verify-all | %FileCheck %s
2+
// RUN: %target-sil-opt %s -compute-side-effects -dead-store-elim -max-partial-store-count=2 -enable-sil-verify-all | %FileCheck %s --check-prefix=CHECK-SEA-DSE
23

34
// REQUIRES: swift_in_compiler
45

@@ -1542,3 +1543,32 @@ bb0:
15421543
dealloc_stack_ref %1 : $foo
15431544
return %3 : $Int
15441545
}
1546+
1547+
class Klass {}
1548+
1549+
sil @klassClosure : $@convention(thin) (@in_guaranteed Klass) -> ()
1550+
1551+
sil @test_pa_without_apply : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> () {
1552+
bb0(%0 : $*Klass):
1553+
%3 = function_ref @klassClosure : $@convention(thin) (@in_guaranteed Klass) -> ()
1554+
%4 = partial_apply [callee_guaranteed] %3(%0) : $@convention(thin) (@in_guaranteed Klass) -> ()
1555+
return %4 : $@callee_guaranteed () -> ()
1556+
}
1557+
1558+
// CHECK-SEA-DSE: sil @dont_dead_store_capture :
1559+
// CHECK-SEA-DSE: store
1560+
// CHECK-SEA-DSE: } // end sil function 'dont_dead_store_capture'
1561+
sil @dont_dead_store_capture : $@convention(thin) (@in_guaranteed (Klass, Klass)) -> () {
1562+
bb0(%0 : $*(Klass, Klass)):
1563+
%ele = tuple_element_addr %0 : $*(Klass, Klass), 1
1564+
%1 = load %ele : $*Klass
1565+
%3 = alloc_stack $Klass
1566+
store %1 to %3 : $*Klass
1567+
strong_retain %1 : $Klass
1568+
%4 = function_ref @test_pa_without_apply : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> ()
1569+
%5 = apply %4(%3) : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> ()
1570+
%6 = apply %5() : $@callee_guaranteed () -> ()
1571+
dealloc_stack %3 : $*Klass
1572+
%7 = tuple ()
1573+
return %7 : $()
1574+
}

test/SILOptimizer/side_effects.sil

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ bb0(%0 : $X, %1 : $*Int32):
138138

139139
// CHECK-LABEL: sil @partial_apply_load_store_to_args
140140
// CHECK-NEXT: [%0: read v**]
141-
// CHECK-NEXT: [%1: write v**]
141+
// CHECK-NEXT: [%1: read v**, write v**]
142142
// CHECK-NEXT: [%2: write c0.v**, destroy c*.v**]
143143
// CHECK-NEXT: [global: read,write,copy,destroy,allocate,deinit_barrier]
144144
// CHECK-NEXT: {{^[^[]}}
@@ -157,7 +157,7 @@ bb0(%0 : $*Int32, %1 : $*Int32, %2 : $X):
157157

158158
// CHECK-LABEL: sil @guaranteed_partial_apply_load_store_to_args
159159
// CHECK-NEXT: [%0: read v**]
160-
// CHECK-NEXT: [%1: write v**]
160+
// CHECK-NEXT: [%1: read v**, write v**]
161161
// CHECK-NEXT: [%2: write c0.v**]
162162
// CHECK-NEXT: [global: ]
163163
// CHECK-NEXT: {{^[^[]}}
@@ -827,6 +827,7 @@ bb0(%0 : $X):
827827
}
828828

829829
// CHECK-LABEL: sil @not_called_partial_apply
830+
// CHECK-NEXT: [%0: read v**]
830831
// CHECK-NEXT: [global: ]
831832
// CHECK-NEXT: {{^[^[]}}
832833
sil @not_called_partial_apply : $@convention(thin) (@in Int32) -> @owned @callee_owned (Bool) -> Int32 {
@@ -837,6 +838,8 @@ bb0(%0 : $*Int32):
837838
}
838839

839840
// CHECK-LABEL: sil @partial_apply_chain
841+
// CHECK-NEXT: [%0: read v**]
842+
// CHECK-NEXT: [%1: read v**]
840843
// CHECK-NEXT: [global: ]
841844
// CHECK-NEXT: {{^[^[]}}
842845
sil @partial_apply_chain : $@convention(thin) (@in Int32, @in Int32) -> @owned @callee_owned (Bool) -> Int32 {
@@ -849,7 +852,7 @@ bb0(%0 : $*Int32, %1 : $*Int32):
849852

850853
// CHECK-LABEL: sil @two_nonstack_partial_applies
851854
// CHECK-NEXT: [%0: read v**]
852-
// CHECK-NEXT: [%1: write v**]
855+
// CHECK-NEXT: [%1: read v**, write v**]
853856
// CHECK-NEXT: [%2: write c0.v**]
854857
// CHECK-NEXT: [global: ]
855858
// CHECK-NEXT: {{^[^[]}}

0 commit comments

Comments
 (0)