Skip to content

Commit 1e6f93e

Browse files
committed
Disable function signature optimization on functions with lifetime dependencies
If a function has lifetime dependencies, disable FSO's dead param optimization. Dead params maybe dependency sources and we should not delete them. It is also problematic to dead code params that are not dependency sources, since lifetime dependent sources are stored as indices and deleting dead parameters will require recomputation of these indices.
1 parent 9f9d265 commit 1e6f93e

File tree

3 files changed

+52
-3
lines changed

3 files changed

+52
-3
lines changed

lib/SILOptimizer/FunctionSignatureTransforms/DeadArgumentTransform.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ bool FunctionSignatureTransform::DeadArgumentAnalyzeParameters() {
2828

2929
// Did we decide we should optimize any parameter?
3030
SILFunction *F = TransformDescriptor.OriginalFunction;
31+
32+
// If a function has lifetime dependencies, disable FSO's dead param
33+
// optimization. Dead params maybe dependency sources and we should not
34+
// delete them. It is also problematic to dead code params that are not
35+
// dependency sources, since lifetime dependent sources are stored as indices
36+
// and deleting dead parameters will require recomputation of these indices.
37+
if (F->getLoweredFunctionType()->hasLifetimeDependencies()) {
38+
return false;
39+
}
40+
3141
bool SignatureOptimize = false;
3242
auto Args = F->begin()->getSILFunctionArguments();
3343
auto OrigShouldModifySelfArgument =

test/SILOptimizer/functionsigopts.sil

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1-
// RUN: %target-sil-opt -sil-print-types -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts %s | %FileCheck %s
2-
// RUN: %target-sil-opt -sil-print-types -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts %s | %FileCheck -check-prefix=CHECK-NEGATIVE %s
1+
// RUN: %target-sil-opt -sil-print-types -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts -enable-experimental-feature Lifetimes %s | %FileCheck %s
2+
// RUN: %target-sil-opt -sil-print-types -sil-inline-generics -enable-sil-verify-all -inline -function-signature-opts -enable-experimental-feature Lifetimes %s | %FileCheck -check-prefix=CHECK-NEGATIVE %s
3+
4+
// REQUIRES: swift_in_compiler
5+
// REQUIRES: swift_feature_Lifetimes
36

47
import Builtin
58
import Swift
@@ -1832,6 +1835,28 @@ bb0(%0 : $ValueGenericType<N>):
18321835
return %2 : $Int
18331836
}
18341837

1838+
struct NE<T> : ~Escapable where T : ~Escapable {
1839+
@_lifetime(copy t)
1840+
init(_ t: borrowing T)
1841+
}
1842+
1843+
// CHECK-NOT: sil [serialized] [signature_optimized_thunk] [always_inline] @neinit :
1844+
sil [noinline] @neinit : $@convention(method) <T where T : ~Escapable> (@in_guaranteed T, @thin NE<T>.Type) -> @lifetime(copy 0) @owned NE<T> {
1845+
bb0(%0 : @noImplicitCopy $*T, %1 : $@thin NE<T>.Type):
1846+
debug_value [moveable_value_debuginfo] %0, let, name "t", argno 1, expr op_deref
1847+
%3 = struct $NE<T> ()
1848+
return %3
1849+
}
1850+
1851+
sil hidden @neinit_caller : $@convention(thin) <T where T : ~Escapable> (@in_guaranteed T) -> @lifetime(copy 0) @owned NE<T> {
1852+
bb0(%0 : @noImplicitCopy $*T):
1853+
debug_value [moveable_value_debuginfo] %0, let, name "t", argno 1, expr op_deref
1854+
%2 = metatype $@thin NE<T>.Type
1855+
%3 = function_ref @neinit : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed τ_0_0, @thin NE<τ_0_0>.Type) -> @lifetime(copy 0) @owned NE<τ_0_0>
1856+
%4 = apply %3<T>(%0, %2) : $@convention(method) <τ_0_0 where τ_0_0 : ~Escapable> (@in_guaranteed τ_0_0, @thin NE<τ_0_0>.Type) -> @lifetime(copy 0) @owned NE<τ_0_0>
1857+
return %4
1858+
}
1859+
18351860
// CHECK-LABEL: sil shared @$s36exploded_release_to_guaranteed_paramTf4gX_n
18361861
// CHECK: bb0([[INPUT_ARG0:%[0-9]+]] : $Int):
18371862
// CHECK-NOT: strong_release

test/SILOptimizer/functionsigopts_crash.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
// RUN: %target-swift-frontend -module-name main -O -emit-sil -primary-file %s | %FileCheck %s
1+
// RUN: %target-swift-frontend -module-name main -O -emit-sil -primary-file %s -enable-experimental-feature Lifetimes | %FileCheck %s
2+
3+
// REQUIRES: swift_in_compiler
4+
// REQUIRES: swift_feature_Lifetimes
25

36
protocol P {
47
func foo()
@@ -53,3 +56,14 @@ extension Array: IP {
5356
}
5457
}
5558
}
59+
60+
struct NE<T : ~Escapable> : ~Escapable {
61+
@_lifetime(copy t)
62+
init(_ t: borrowing T) {}
63+
}
64+
65+
@_lifetime(copy t)
66+
func getNE<T : ~Escapable>(_ t: borrowing T) -> NE<T> {
67+
return NE(t)
68+
}
69+

0 commit comments

Comments
 (0)