diff --git a/SwiftCompilerSources/Sources/Optimizer/Utilities/FunctionSignatureTransforms.swift b/SwiftCompilerSources/Sources/Optimizer/Utilities/FunctionSignatureTransforms.swift index 08e619d5d8212..310dec2c9f9c9 100644 --- a/SwiftCompilerSources/Sources/Optimizer/Utilities/FunctionSignatureTransforms.swift +++ b/SwiftCompilerSources/Sources/Optimizer/Utilities/FunctionSignatureTransforms.swift @@ -12,6 +12,29 @@ import SIL +private extension ArgumentConventions { + func isLifetimeSourceOrTarget(index argIndex: Int) -> Bool { + // Check if `argIndex` is a lifetime target + if self[parameterDependencies: argIndex] != nil { + return true + } + + // Check if `argIndex` is a lifetime source in resultDependencies + if self[resultDependsOn: argIndex] != nil { + return true + } + + // Check if `argIndex` is a lifetime source in parameterDependencies + for targetIndex in firstParameterIndex..= deadArgIndices.first! { + if callee.argumentConventions.isLifetimeSourceOrTarget(index: argIndex) { + return + } + } + } + let specializedFuncName = context.mangle(withDeadArguments: deadArgIndices, from: callee) let specializedCallee: Function diff --git a/test/SILOptimizer/mandatory_performance_optimizations.sil b/test/SILOptimizer/mandatory_performance_optimizations.sil index e41e5fb859a13..2561bbf28cd4b 100644 --- a/test/SILOptimizer/mandatory_performance_optimizations.sil +++ b/test/SILOptimizer/mandatory_performance_optimizations.sil @@ -1,6 +1,7 @@ -// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -mandatory-performance-optimizations | %FileCheck %s +// RUN: %target-sil-opt -sil-print-types -enable-sil-verify-all %s -mandatory-performance-optimizations -enable-experimental-feature Lifetimes | %FileCheck %s // REQUIRES: swift_in_compiler +// REQUIRES: swift_feature_Lifetimes sil_stage canonical @@ -222,6 +223,78 @@ bb0(%0 : $Int, %1 : $@thick Int.Type, %2 : @owned $Builtin.NativeObject): return %2 : $Builtin.NativeObject } +sil [no_locks] [perf_constraint] [ossa] @dont_remove_metatype_arg_lifetime : $@convention(thin) (Int, UnsafeRawPointer) -> @lifetime(borrow 1) Span { +bb0(%0 : $Int, %1 : $UnsafeRawPointer): + %3 = metatype $@thick Int.Type + %7 = function_ref @metatype_arg_lifetime : $@convention(thin) (Int, @thick Int.Type, UnsafeRawPointer) -> @lifetime(borrow 2) Span + %8 = apply %7(%0, %3, %1) : $@convention(thin) (Int, @thick Int.Type, UnsafeRawPointer) -> @lifetime(borrow 2) Span + return %8 +} + +sil [ossa] @get_span : $@convention(thin) (UnsafeRawPointer) -> @lifetime(borrow 0) Span + +// CHECK-NOT: sil [signature_optimized_thunk] [ossa] @metatype_arg_lifetime : +sil [ossa] @metatype_arg_lifetime : $@convention(thin) (Int, @thick Int.Type, UnsafeRawPointer) -> @lifetime(borrow 2) Span { +bb0(%0 : $Int, %1 : $@thick Int.Type, %2 : $UnsafeRawPointer): + fix_lifetime %1 : $@thick Int.Type + %3 = function_ref @get_span : $@convention(thin) (UnsafeRawPointer) -> @lifetime(borrow 0) Span + %4 = apply %3(%2) : $@convention(thin) (UnsafeRawPointer) -> @lifetime(borrow 0) Span + return %4 +} + +sil [no_locks] [perf_constraint] [ossa] @can_remove_metatype_arg_lifetime : $@convention(thin) (Int, UnsafeRawPointer) -> @lifetime(borrow 1) Span { +bb0(%0 : $Int, %1 : $UnsafeRawPointer): + %3 = metatype $@thick Int.Type + %7 = function_ref @metatype_arg_lifetime_opt : $@convention(thin) (UnsafeRawPointer, Int, @thick Int.Type) -> @lifetime(borrow 0) Span + %8 = apply %7(%1, %0, %3) : $@convention(thin) (UnsafeRawPointer, Int, @thick Int.Type) -> @lifetime(borrow 0) Span + return %8 +} + +// CHECK: sil [signature_optimized_thunk] [ossa] @metatype_arg_lifetime_opt : +sil [ossa] @metatype_arg_lifetime_opt : $@convention(thin) (UnsafeRawPointer, Int, @thick Int.Type) -> @lifetime(borrow 0) Span { +bb0(%2 : $UnsafeRawPointer, %0 : $Int, %1 : $@thick Int.Type): + fix_lifetime %1 : $@thick Int.Type + %3 = function_ref @get_span : $@convention(thin) (UnsafeRawPointer) -> @lifetime(borrow 0) Span + %4 = apply %3(%2) : $@convention(thin) (UnsafeRawPointer) -> @lifetime(borrow 0) Span + return %4 +} + +sil [no_locks] [perf_constraint] [ossa] @dont_remove_metatype_arg_lifetime_inout : $@convention(thin) (Int, @lifetime(copy 2) @inout MutableSpan, @owned MutableSpan) -> () { +bb0(%0 : $Int, %1 : $*MutableSpan, %2 : @owned $MutableSpan): + %3 = metatype $@thick Int.Type + %7 = function_ref @metatype_arg_lifetime_inout : $@convention(thin) (Int, @thick Int.Type, @lifetime(copy 3) @inout MutableSpan, @owned MutableSpan) -> () + %8 = apply %7(%0, %3, %1, %2) : $@convention(thin) (Int, @thick Int.Type, @lifetime(copy 3) @inout MutableSpan, @owned MutableSpan) -> () + %r = tuple () + return %r +} + +// CHECK-NOT: sil [signature_optimized_thunk] [ossa] @metatype_arg_lifetime_inout : +sil [ossa] @metatype_arg_lifetime_inout : $@convention(thin) (Int, @thick Int.Type, @lifetime(copy 3) @inout MutableSpan, @owned MutableSpan) -> () { +bb0(%0 : $Int, %1 : $@thick Int.Type, %2 : $*MutableSpan, %3 : @owned $MutableSpan): + fix_lifetime %1 : $@thick Int.Type + destroy_value %3 + %r = tuple () + return %r +} + +sil [no_locks] [perf_constraint] [ossa] @dont_remove_metatype_arg_lifetime_inout_source : $@convention(thin) (Int, @lifetime(copy 2) @inout MutableSpan, @owned MutableSpan) -> () { +bb0(%0 : $Int, %1 : $*MutableSpan, %2 : @owned $MutableSpan): + %3 = metatype $@thick Int.Type + %7 = function_ref @metatype_arg_lifetime_inout_source : $@convention(thin) (@lifetime(copy 3) @inout MutableSpan, Int, @thick Int.Type, @owned MutableSpan) -> () + %8 = apply %7(%1, %0, %3, %2) : $@convention(thin) (@lifetime(copy 3) @inout MutableSpan, Int, @thick Int.Type, @owned MutableSpan) -> () + %r = tuple () + return %r +} + +// CHECK-NOT: sil [signature_optimized_thunk] [ossa] @metatype_arg_lifetime_inout_source : +sil [ossa] @metatype_arg_lifetime_inout_source : $@convention(thin) (@lifetime(copy 3) @inout MutableSpan, Int, @thick Int.Type, @owned MutableSpan) -> () { +bb0(%2 : $*MutableSpan, %0 : $Int, %1 : $@thick Int.Type, %3 : @owned $MutableSpan): + fix_lifetime %1 : $@thick Int.Type + destroy_value %3 + %r = tuple () + return %r +} + // CHECK-LABEL: sil [no_locks] [perf_constraint] [ossa] @remove_metatype_arg_throws : // CHECK: [[F:%.*]] = function_ref @$s19metatype_arg_throwsTf4ndn_n : $@convention(thin) (Int, @owned Builtin.NativeObject) -> (@owned Builtin.NativeObject, @error any Error) // CHECK: try_apply [[F]](%0, %1) : $@convention(thin) (Int, @owned Builtin.NativeObject) -> (@owned Builtin.NativeObject, @error any Error), normal bb1, error bb2