Skip to content

Commit 88c4141

Browse files
authored
Merge pull request #67955 from atrick/fix-dse-capture-effects
Fix SIL function side effects to handle unapplied escaping captures.
2 parents 4581eb7 + 4ce6fcf commit 88c4141

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-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+
// the callee and its arguments are all captured...
157+
for operand in pa.operands {
158+
if operand.value.type.isAddress {
159+
addEffects(.read, to: operand.value)
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: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-sil-opt %s -dead-store-elimination -enable-sil-verify-all | %FileCheck %s
2+
// RUN: %target-sil-opt %s -compute-side-effects -dead-store-elimination -enable-sil-verify-all | %FileCheck %s --check-prefix=CHECK-SEA-DSE
23

34
// REQUIRES: swift_in_compiler
45

@@ -1631,3 +1632,31 @@ bb0(%0 : $UInt64, %1 : $Builtin.Word):
16311632
return %76 : $Builtin.Int8
16321633
}
16331634

1635+
class Klass {}
1636+
1637+
sil @klassClosure : $@convention(thin) (@in_guaranteed Klass) -> ()
1638+
1639+
sil @test_pa_without_apply : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> () {
1640+
bb0(%0 : $*Klass):
1641+
%3 = function_ref @klassClosure : $@convention(thin) (@in_guaranteed Klass) -> ()
1642+
%4 = partial_apply [callee_guaranteed] %3(%0) : $@convention(thin) (@in_guaranteed Klass) -> ()
1643+
return %4 : $@callee_guaranteed () -> ()
1644+
}
1645+
1646+
// CHECK-SEA-DSE: sil @dont_dead_store_capture :
1647+
// CHECK-SEA-DSE: store
1648+
// CHECK-SEA-DSE: } // end sil function 'dont_dead_store_capture'
1649+
sil @dont_dead_store_capture : $@convention(thin) (@in_guaranteed (Klass, Klass)) -> () {
1650+
bb0(%0 : $*(Klass, Klass)):
1651+
%ele = tuple_element_addr %0 : $*(Klass, Klass), 1
1652+
%1 = load %ele : $*Klass
1653+
%3 = alloc_stack $Klass
1654+
store %1 to %3 : $*Klass
1655+
strong_retain %1 : $Klass
1656+
%4 = function_ref @test_pa_without_apply : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> ()
1657+
%5 = apply %4(%3) : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> ()
1658+
%6 = apply %5() : $@callee_guaranteed () -> ()
1659+
dealloc_stack %3 : $*Klass
1660+
%7 = tuple ()
1661+
return %7 : $()
1662+
}

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)