Skip to content

[5.9] Fix SIL function side effects to handle unapplied escaping closures #68203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,24 @@ private struct CollectedEffects {
handleApply(pa)
checkedIfDeinitBarrier = true
}
// In addition to the effects of the apply, also consider the
// effects of the capture, which reads the captured value in
// order to move it into the context. This only applies to
// addressible values, because capturing does not dereference
// any class objects.
//
// Ignore captures for on-stack partial applies. They only
// bitwise-move or capture by address, so the call to
// handleApply above is sufficient. And, if they are not applied
// in this function, then they are never applied.
if !pa.isOnStack {
// callee is never an address.
for argument in pa.arguments {
if argument.type.isAddress {
addEffects(.read, to: argument)
}
}
}

case let fl as FixLifetimeInst:
// A fix_lifetime instruction acts like a read on the operand to prevent
Expand Down
30 changes: 30 additions & 0 deletions test/SILOptimizer/dead_store_elim.sil
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %target-sil-opt %s -dead-store-elim -max-partial-store-count=2 -enable-sil-verify-all | %FileCheck %s
// 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

// REQUIRES: swift_in_compiler

Expand Down Expand Up @@ -1542,3 +1543,32 @@ bb0:
dealloc_stack_ref %1 : $foo
return %3 : $Int
}

class Klass {}

sil @klassClosure : $@convention(thin) (@in_guaranteed Klass) -> ()

sil @test_pa_without_apply : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> () {
bb0(%0 : $*Klass):
%3 = function_ref @klassClosure : $@convention(thin) (@in_guaranteed Klass) -> ()
%4 = partial_apply [callee_guaranteed] %3(%0) : $@convention(thin) (@in_guaranteed Klass) -> ()
return %4 : $@callee_guaranteed () -> ()
}

// CHECK-SEA-DSE: sil @dont_dead_store_capture :
// CHECK-SEA-DSE: store
// CHECK-SEA-DSE: } // end sil function 'dont_dead_store_capture'
sil @dont_dead_store_capture : $@convention(thin) (@in_guaranteed (Klass, Klass)) -> () {
bb0(%0 : $*(Klass, Klass)):
%ele = tuple_element_addr %0 : $*(Klass, Klass), 1
%1 = load %ele : $*Klass
%3 = alloc_stack $Klass
store %1 to %3 : $*Klass
strong_retain %1 : $Klass
%4 = function_ref @test_pa_without_apply : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> ()
%5 = apply %4(%3) : $@convention(thin) (@in Klass) -> @callee_guaranteed () -> ()
%6 = apply %5() : $@callee_guaranteed () -> ()
dealloc_stack %3 : $*Klass
%7 = tuple ()
return %7 : $()
}
9 changes: 6 additions & 3 deletions test/SILOptimizer/side_effects.sil
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ bb0(%0 : $X, %1 : $*Int32):

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

// CHECK-LABEL: sil @guaranteed_partial_apply_load_store_to_args
// CHECK-NEXT: [%0: read v**]
// CHECK-NEXT: [%1: write v**]
// CHECK-NEXT: [%1: read v**, write v**]
// CHECK-NEXT: [%2: write c0.v**]
// CHECK-NEXT: [global: ]
// CHECK-NEXT: {{^[^[]}}
Expand Down Expand Up @@ -827,6 +827,7 @@ bb0(%0 : $X):
}

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

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

// CHECK-LABEL: sil @two_nonstack_partial_applies
// CHECK-NEXT: [%0: read v**]
// CHECK-NEXT: [%1: write v**]
// CHECK-NEXT: [%1: read v**, write v**]
// CHECK-NEXT: [%2: write c0.v**]
// CHECK-NEXT: [global: ]
// CHECK-NEXT: {{^[^[]}}
Expand Down