mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
210 lines
7.2 KiB
Plaintext
210 lines
7.2 KiB
Plaintext
// RUN: %target-swift-frontend -disable-sil-perf-optzns -O -Xllvm -swiftmergefunc-threshold=0 -emit-ir %s | %FileCheck %s
|
|
|
|
// Check that IRGen lowers non-atomic reference counting instructions to
|
|
// proper runtime calls.
|
|
// Check that LLVM passes combine multiple retains/releases into
|
|
// retain_n/release_n and invoke a proper runtime function. Non-atomic runtime
|
|
// functions should be called only if all combined reference-counting
|
|
// instructions are non-atomic.
|
|
//
|
|
// Take into account that on Linux unknown_retain/unknown_release are not supported
|
|
// and native retain/release runtime functions are used instead.
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import SwiftShims
|
|
|
|
public class C {
|
|
deinit
|
|
init()
|
|
}
|
|
|
|
public protocol P : class {
|
|
}
|
|
|
|
// foo(C) -> C
|
|
sil [noinline] @_TF28nonatomic_reference_counting3fooFCS_1CS0_ : $@convention(thin) (@owned C) -> @owned C {
|
|
bb0(%0 : $C):
|
|
return %0 : $C
|
|
}
|
|
|
|
sil @doSomething : $@convention(thin) () -> ()
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_strong_nonatomic_rr
|
|
// CHECK: call {{.*}}@swift_nonatomic_retain
|
|
// CHECK: call {{.*}}@swift_nonatomic_release
|
|
// CHECK: ret
|
|
sil @test_strong_nonatomic_rr: $@convention(thin) () -> @owned C {
|
|
bb0:
|
|
%1 = alloc_ref $C
|
|
strong_retain [nonatomic] %1 : $C
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
strong_release [nonatomic] %1 : $C
|
|
return %1 : $C
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_unknown_nonatomic_rr
|
|
// CHECK: call {{.*}}@{{(swift_nonatomic_unknownObjectRetain|swift_nonatomic_retain)}}
|
|
// CHECK: call {{.*}}@{{(swift_nonatomic_unknownObjectRelease|swift_nonatomic_release)}}
|
|
// CHECK: ret
|
|
sil @test_unknown_nonatomic_rr: $@convention(thin) <T where T : P> (@owned T) -> () {
|
|
bb0(%0 : $T):
|
|
strong_retain [nonatomic] %0 : $T
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
strong_release [nonatomic] %0 : $T
|
|
%9 = tuple ()
|
|
return %9 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_strong_nonatomic_rr_n
|
|
// CHECK: call {{.*}}@swift_nonatomic_retain_n
|
|
// CHECK: call {{.*}}@swift_nonatomic_release_n
|
|
// CHECK: ret
|
|
sil @test_strong_nonatomic_rr_n: $@convention(thin) () -> @owned C {
|
|
bb0:
|
|
%1 = alloc_ref $C
|
|
strong_retain [nonatomic] %1 : $C
|
|
strong_retain [nonatomic] %1 : $C
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
strong_release [nonatomic] %1 : $C
|
|
strong_release [nonatomic] %1 : $C
|
|
return %1 : $C
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_strong_mixed_rr_n
|
|
// CHECK: call {{.*}}@swift_retain_n
|
|
// CHECK: call {{.*}}@swift_release_n
|
|
// CHECK: ret
|
|
sil @test_strong_mixed_rr_n: $@convention(thin) () -> @owned C {
|
|
bb0:
|
|
%1 = alloc_ref $C
|
|
strong_retain [nonatomic] %1 : $C
|
|
strong_retain %1 : $C
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
strong_release %1 : $C
|
|
strong_release [nonatomic] %1 : $C
|
|
return %1 : $C
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_unknown_nonatomic_rr_n
|
|
// CHECK: call {{.*}}@{{(swift_nonatomic_unknownObjectRetain_n|swift_nonatomic_retain_n)}}
|
|
// CHECK: call {{.*}}@{{(swift_nonatomic_unknownObjectRelease_n|swift_nonatomic_release_n)}}
|
|
// CHECK: ret
|
|
sil @test_unknown_nonatomic_rr_n: $@convention(thin) <T where T : P> (@owned T) -> () {
|
|
bb0(%0 : $T):
|
|
strong_retain [nonatomic] %0 : $T
|
|
strong_retain [nonatomic] %0 : $T
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
strong_release [nonatomic] %0 : $T
|
|
strong_release [nonatomic] %0 : $T
|
|
%9 = tuple ()
|
|
return %9 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_unknown_mixed_rr_n
|
|
// CHECK: call {{.*}}@{{(swift_unknownObjectRetain_n|swift_retain_n)}}
|
|
// CHECK: call {{.*}}@{{(swift_unknownObjectRelease_n|swift_release_n)}}
|
|
// CHECK: ret
|
|
sil @test_unknown_mixed_rr_n: $@convention(thin) <T where T : P> (@owned T) -> () {
|
|
bb0(%0 : $T):
|
|
strong_retain [nonatomic] %0 : $T
|
|
strong_retain %0 : $T
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
strong_release %0 : $T
|
|
strong_release [nonatomic] %0 : $T
|
|
%9 = tuple ()
|
|
return %9 : $()
|
|
}
|
|
|
|
sil @test_unowned_nonatomic_rr: $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_ref $C
|
|
%1 = ref_to_unowned %0 : $C to $@sil_unowned C
|
|
unowned_retain [nonatomic] %1 : $@sil_unowned C
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
unowned_release [nonatomic] %1 : $@sil_unowned C
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_bridged_nonatomic_rr
|
|
// CHECK: call {{.*}}@swift_nonatomic_bridgeObjectRetain
|
|
// CHECK: call {{.*}}@swift_nonatomic_bridgeObjectRelease
|
|
// CHECK: ret
|
|
sil @test_bridged_nonatomic_rr: $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_ref $C
|
|
%1 = integer_literal $Builtin.Word, 0
|
|
%2 = ref_to_bridge_object %0 : $C, %1 : $Builtin.Word
|
|
strong_retain [nonatomic] %2 : $Builtin.BridgeObject
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
strong_release [nonatomic] %2 : $Builtin.BridgeObject
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_bridged_nonatomic_rr_n
|
|
// CHECK: call {{.*}}@swift_nonatomic_bridgeObjectRetain_n
|
|
// CHECK: call {{.*}}@swift_nonatomic_bridgeObjectRelease_n
|
|
// CHECK: ret
|
|
sil @test_bridged_nonatomic_rr_n: $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_ref $C
|
|
%1 = integer_literal $Builtin.Word, 0
|
|
%2 = ref_to_bridge_object %0 : $C, %1 : $Builtin.Word
|
|
strong_retain [nonatomic] %2 : $Builtin.BridgeObject
|
|
strong_retain [nonatomic] %2 : $Builtin.BridgeObject
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
//%f = function_ref @_TF28nonatomic_reference_counting3fooFCS_1CS0_ : $@convention(thin) (@owned C) -> @owned C
|
|
//%r = apply %f (%0) : $@convention(thin) (@owned C) -> @owned C
|
|
strong_release [nonatomic] %2 : $Builtin.BridgeObject
|
|
strong_release [nonatomic] %2 : $Builtin.BridgeObject
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define {{.*}}@test_bridged_mixed_rr_n
|
|
// CHECK: call {{.*}}@swift_bridgeObjectRetain_n
|
|
// CHECK: call {{.*}}@swift_bridgeObjectRelease_n
|
|
// CHECK: ret
|
|
sil @test_bridged_mixed_rr_n: $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_ref $C
|
|
%1 = integer_literal $Builtin.Word, 0
|
|
%2 = ref_to_bridge_object %0 : $C, %1 : $Builtin.Word
|
|
strong_retain [nonatomic] %2 : $Builtin.BridgeObject
|
|
strong_retain %2 : $Builtin.BridgeObject
|
|
%f = function_ref @doSomething : $@convention(thin) () -> ()
|
|
%r = apply %f () : $@convention(thin) () -> ()
|
|
//%f = function_ref @_TF28nonatomic_reference_counting3fooFCS_1CS0_ : $@convention(thin) (@owned C) -> @owned C
|
|
//%r = apply %f (%0) : $@convention(thin) (@owned C) -> @owned C
|
|
strong_release %2 : $Builtin.BridgeObject
|
|
strong_release [nonatomic] %2 : $Builtin.BridgeObject
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// C.__deallocating_deinit
|
|
sil @_TFC28nonatomic_reference_counting1CD : $@convention(method) (@owned C) -> () {
|
|
bb0(%0 : $C):
|
|
dealloc_ref %0 : $C
|
|
%4 = tuple ()
|
|
return %4 : $()
|
|
}
|
|
|
|
sil_vtable C {
|
|
#C.deinit!deallocator: @_TFC28nonatomic_reference_counting1CD // C.__deallocating_deinit
|
|
}
|
|
|