mirror of
https://github.com/apple/swift.git
synced 2026-03-04 18:24:35 +01:00
Even if an indirect argument is unused, pretend that the function reads from it. If the unused argument is passed to another generic function and that function is specialized, the argument may be re-abstracted and the specializer inserts a load from the indirect argument. Therefore we must be prepared that unused indirect argument might get loaded from at some time. Fixes a compiler crash rdar://168623362
1774 lines
87 KiB
Plaintext
1774 lines
87 KiB
Plaintext
// RUN: %target-sil-opt -sil-print-types -parse-serialized-sil -enable-sil-verify-all -sil-partial-specialization -generic-specializer %s | %FileCheck %s
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
|
|
class Klass {}
|
|
class GenericKlass<T> {}
|
|
|
|
sil [ossa] [transparent] @ossaTransparentCallee : $@convention(thin) <T> (@in T) -> () {
|
|
bb0(%0 : $*T):
|
|
destroy_addr %0 : $*T
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// We specialize this case today and just respect the already set ownership in
|
|
// each function. This makes sense since ossa can be specialized.
|
|
//
|
|
// CHECK-LABEL: sil @caller : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
// CHECK: [[FUNC:%.*]] = function_ref @$s21ossaTransparentCalleeBo_Tg5 : $@convention(thin) (@owned Builtin.NativeObject) -> ()
|
|
// CHECK: apply [[FUNC]](
|
|
// CHECK: } // end sil function 'caller'
|
|
sil @caller : $@convention(thin) (@owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $Builtin.NativeObject):
|
|
%1 = function_ref @ossaTransparentCallee : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
|
|
%2 = alloc_stack $Builtin.NativeObject
|
|
store %0 to %2 : $*Builtin.NativeObject
|
|
apply %1<Builtin.NativeObject>(%2) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
|
|
dealloc_stack %2 : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil shared [noinline] [ossa] @$s33XXX_foo_guaranteed_generic_returnBo_Tg5 :
|
|
// CHECK: [[S1:%.*]] = alloc_stack $Builtin.NativeObject
|
|
// CHECK: [[S2:%.*]] = alloc_stack $Builtin.NativeObject
|
|
// CHECK: [[SBI:%.*]] = store_borrow %0 to [[S2]] : $*Builtin.NativeObject
|
|
// CHECK: end_borrow [[SBI]] : $*Builtin.NativeObject
|
|
// CHECK: dealloc_stack [[S2]] : $*Builtin.NativeObject
|
|
// CHECK-LABEL: } // end sil function '$s33XXX_foo_guaranteed_generic_returnBo_Tg5'
|
|
|
|
// CHECK-LABEL: sil [ossa] @exp1 : $@convention(thin) () -> () {
|
|
// CHECK-NOT: apply
|
|
// Call of specialized initializer: <Int32>
|
|
// CHECK: [[CTOR:%[0-9]+]] = function_ref @$s8XXX_inits5Int32V_Tt1g5
|
|
// CHECK: apply [[CTOR]]
|
|
// CHECK: [[ACCEPTS_INT:%[0-9]+]] = function_ref @acceptsInt
|
|
// Call of specialized XXX_foo: <Int32>
|
|
// CHECK: [[FOO:%[0-9]+]] = function_ref @$s7XXX_foos5Int32V_Tg5
|
|
// CHECK: apply [[FOO]]
|
|
// CHECK: apply [[ACCEPTS_INT]]
|
|
// CHECK: return
|
|
// CHECK: } // end sil function 'exp1'
|
|
|
|
// CHECK: sil [ossa] @exp2 : $@convention(thin) () -> () {
|
|
// CHECK: } // end sil function 'exp2'
|
|
|
|
struct XXX<T> {
|
|
init(t: T)
|
|
mutating func foo(t: T) -> Int32
|
|
var m_t: T
|
|
}
|
|
|
|
// specialize.XXX.init <A>(specialize.XXX<A>.Type)(t : A) -> specialize.XXX<A>
|
|
sil [ossa] [noinline] @XXX_init : $@convention(thin) <T> (@in T, @thin XXX<T>.Type) -> @out XXX<T> {
|
|
bb0(%0 : $*XXX<T>, %1 : $*T, %2 : $@thin XXX<T>.Type):
|
|
%3 = alloc_stack $XXX<T>, var, name "sf" // users: %7, %11, %13
|
|
debug_value %1 : $*T, let, name "t", expr op_deref // id: %4
|
|
%5 = alloc_stack $T // users: %6, %8, %9
|
|
copy_addr %1 to [init] %5 : $*T // id: %6
|
|
%7 = struct_element_addr %3 : $*XXX<T>, #XXX.m_t // user: %8
|
|
copy_addr [take] %5 to [init] %7 : $*T // id: %8
|
|
dealloc_stack %5 : $*T // id: %9
|
|
destroy_addr %1 : $*T // id: %10
|
|
copy_addr [take] %3 to [init] %0 : $*XXX<T> // id: %11
|
|
%12 = tuple () // user: %14
|
|
dealloc_stack %3 : $*XXX<T> // id: %13
|
|
return %12 : $() // id: %14
|
|
}
|
|
|
|
// specialize.XXX.foo <A>(@inout specialize.XXX<A>)(t : A) -> Swift.Int32
|
|
sil [ossa] [noinline] @XXX_foo : $@convention(method) <T> (@in T, @inout XXX<T>) -> Int32 {
|
|
bb0(%0 : $*T, %1 : $*XXX<T>):
|
|
debug_value %0 : $*T, let, name "t", expr op_deref // id: %2
|
|
%3 = alloc_stack $T // users: %4, %6, %7
|
|
copy_addr %0 to [init] %3 : $*T // id: %4
|
|
%5 = struct_element_addr %1 : $*XXX<T>, #XXX.m_t // user: %6
|
|
copy_addr [take] %3 to %5 : $*T // id: %6
|
|
dealloc_stack %3 : $*T // id: %7
|
|
%8 = integer_literal $Builtin.Int32, 4 // user: %9
|
|
%9 = struct $Int32 (%8 : $Builtin.Int32) // user: %11
|
|
destroy_addr %0 : $*T // id: %10
|
|
return %9 : $Int32 // id: %11
|
|
}
|
|
|
|
sil [ossa] [noinline] @XXX_init_guaranteed : $@convention(thin) <T> (@in_guaranteed T, @thin XXX<T>.Type) -> @out XXX<T> {
|
|
bb0(%0 : $*XXX<T>, %1 : $*T, %2 : $@thin XXX<T>.Type):
|
|
%3 = alloc_stack $XXX<T>, var, name "sf" // users: %7, %11, %13
|
|
debug_value %1 : $*T, let, name "t", expr op_deref // id: %4
|
|
%5 = alloc_stack $T // users: %6, %8, %9
|
|
copy_addr %1 to [init] %5 : $*T // id: %6
|
|
%7 = struct_element_addr %3 : $*XXX<T>, #XXX.m_t // user: %8
|
|
copy_addr [take] %5 to [init] %7 : $*T // id: %8
|
|
dealloc_stack %5 : $*T // id: %9
|
|
copy_addr [take] %3 to [init] %0 : $*XXX<T> // id: %11
|
|
%12 = tuple () // user: %14
|
|
dealloc_stack %3 : $*XXX<T> // id: %13
|
|
return %12 : $() // id: %14
|
|
}
|
|
|
|
// specialize.XXX.foo <A>(@inout specialize.XXX<A>)(t : A) -> Swift.Int32
|
|
sil [ossa] [noinline] @XXX_foo_guaranteed : $@convention(method) <T> (@in_guaranteed T, @inout XXX<T>) -> Int32 {
|
|
bb0(%0 : $*T, %1 : $*XXX<T>):
|
|
debug_value %0 : $*T, let, name "t", expr op_deref // id: %2
|
|
%3 = alloc_stack $T // users: %4, %6, %7
|
|
copy_addr %0 to [init] %3 : $*T // id: %4
|
|
%5 = struct_element_addr %1 : $*XXX<T>, #XXX.m_t // user: %6
|
|
copy_addr [take] %3 to %5 : $*T // id: %6
|
|
dealloc_stack %3 : $*T // id: %7
|
|
%8 = integer_literal $Builtin.Int32, 4 // user: %9
|
|
%9 = struct $Int32 (%8 : $Builtin.Int32) // user: %11
|
|
return %9 : $Int32 // id: %11
|
|
}
|
|
|
|
sil [ossa] [noinline] @XXX_foo_guaranteed_generic_return : $@convention(method) <T> (@in_guaranteed T, @in XXX<T>) -> @out T {
|
|
bb0(%0 : $*T, %1 : $*T, %2 : $*XXX<T>):
|
|
%3 = address_to_pointer %1 : $*T to $Builtin.RawPointer
|
|
%4 = alloc_stack $T
|
|
%5 = struct_element_addr %2 : $*XXX<T>, #XXX.m_t
|
|
copy_addr [take] %5 to [init] %0 : $*T
|
|
dealloc_stack %4 : $*T
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
// Swift.Int32._convertFromBuiltinIntegerLiteral (Swift.Int32.Type)(Builtin.IntLiteral) -> Swift.Int32
|
|
sil public_external [ossa] [transparent] @$sSi33_convertFromBuiltinIntegerLiteralySiBI_cSimF : $@convention(thin) (Builtin.IntLiteral, @thin Int32.Type) -> Int32 {
|
|
bb0(%0 : $Builtin.IntLiteral, %1 : $@thin Int32.Type):
|
|
%3 = builtin "s_to_s_checked_trunc_IntLiteral_Int32"(%0 : $Builtin.IntLiteral) : $(Builtin.Int32, Builtin.Int1)
|
|
%4 = tuple_extract %3 : $(Builtin.Int32, Builtin.Int1), 0 // user: %5
|
|
%5 = struct $Int32 (%4 : $Builtin.Int32) // user: %6
|
|
return %5 : $Int32 // id: %6
|
|
}
|
|
|
|
// specialize.acceptsInt (Swift.Int32) -> ()
|
|
sil [noinline] [ossa] @acceptsInt : $@convention(thin) (Int32) -> () {
|
|
bb0(%0 : $Int32):
|
|
debug_value %0 : $Int32, let, name "x" // id: %1
|
|
%2 = tuple () // user: %3
|
|
return %2 : $() // id: %3
|
|
}
|
|
|
|
// specialize.exp1 () -> ()
|
|
sil [ossa] @exp1 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_stack $XXX<Int32>, var, name "II" // users: %7, %15, %19
|
|
// function_ref specialize.XXX.init <A>(specialize.XXX<A>.Type)(t : A) -> specialize.XXX<A>
|
|
%1 = function_ref @XXX_init : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> // user: %7
|
|
%2 = metatype $@thin XXX<Int32>.Type // user: %7
|
|
%3 = alloc_stack $Int32 // users: %6, %7, %8
|
|
%4 = integer_literal $Builtin.Int32, 5 // user: %5
|
|
%5 = struct $Int32 (%4 : $Builtin.Int32) // user: %6
|
|
store %5 to [trivial] %3 : $*Int32 // id: %6
|
|
%7 = apply %1<Int32>(%0, %3, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0>
|
|
dealloc_stack %3 : $*Int32 // id: %8
|
|
// function_ref specialize.acceptsInt (Swift.Int32) -> ()
|
|
%9 = function_ref @acceptsInt : $@convention(thin) (Int32) -> () // user: %16
|
|
// function_ref specialize.XXX.foo <A>(@inout specialize.XXX<A>)(t : A) -> Swift.Int32
|
|
%10 = function_ref @XXX_foo : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15
|
|
%11 = alloc_stack $Int32 // users: %14, %15, %17
|
|
%12 = integer_literal $Builtin.Int32, 4 // user: %13
|
|
%13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14
|
|
store %13 to [trivial] %11 : $*Int32 // id: %14
|
|
%15 = apply %10<Int32>(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16
|
|
%16 = apply %9(%15) : $@convention(thin) (Int32) -> ()
|
|
dealloc_stack %11 : $*Int32 // id: %17
|
|
%18 = tuple () // user: %20
|
|
dealloc_stack %0 : $*XXX<Int32> // id: %19
|
|
return %18 : $() // id: %20
|
|
}
|
|
|
|
// specialize.exp2 () -> ()
|
|
sil [ossa] @exp2 : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = alloc_stack $XXX<UInt8>, var, name "I8" // users: %7, %15, %19
|
|
// function_ref specialize.XXX.init <A>(specialize.XXX<A>.Type)(t : A) -> specialize.XXX<A>
|
|
%1 = function_ref @XXX_init : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> // user: %7
|
|
%2 = metatype $@thin XXX<UInt8>.Type // user: %7
|
|
%3 = alloc_stack $UInt8 // users: %6, %7, %8
|
|
%4 = integer_literal $Builtin.Int8, 5 // user: %5
|
|
%5 = struct $UInt8 (%4 : $Builtin.Int8) // user: %6
|
|
store %5 to [trivial] %3 : $*UInt8 // id: %6
|
|
%7 = apply %1<UInt8>(%0, %3, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0>
|
|
dealloc_stack %3 : $*UInt8 // id: %8
|
|
// function_ref specialize.acceptsInt (Swift.Int32) -> ()
|
|
%9 = function_ref @acceptsInt : $@convention(thin) (Int32) -> () // user: %16
|
|
// function_ref specialize.XXX.foo <A>(@inout specialize.XXX<A>)(t : A) -> Swift.Int32
|
|
%10 = function_ref @XXX_foo : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15
|
|
%11 = alloc_stack $UInt8 // users: %14, %15, %17
|
|
%12 = integer_literal $Builtin.Int8, 4 // user: %13
|
|
%13 = struct $UInt8 (%12 : $Builtin.Int8) // user: %14
|
|
store %13 to [trivial] %11 : $*UInt8 // id: %14
|
|
%15 = apply %10<UInt8>(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16
|
|
%16 = apply %9(%15) : $@convention(thin) (Int32) -> ()
|
|
dealloc_stack %11 : $*UInt8 // id: %17
|
|
%18 = tuple () // user: %20
|
|
dealloc_stack %0 : $*XXX<UInt8> // id: %19
|
|
return %18 : $() // id: %20
|
|
}
|
|
|
|
sil [ossa] @exp2_nativeObject : $@convention(thin) (@guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%arg : @guaranteed $Builtin.NativeObject):
|
|
%0 = alloc_stack $XXX<Builtin.NativeObject>
|
|
// function_ref specialize.XXX.init <A>(specialize.XXX<A>.Type)(t : A) -> specialize.XXX<A>
|
|
%1 = function_ref @XXX_init : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0> // user: %7
|
|
%2 = metatype $@thin XXX<Builtin.NativeObject>.Type // user: %7
|
|
%3 = alloc_stack $Builtin.NativeObject // users: %6, %7, %8
|
|
%arg1 = copy_value %arg : $Builtin.NativeObject
|
|
store %arg1 to [init] %3 : $*Builtin.NativeObject // id: %6
|
|
%7 = apply %1<Builtin.NativeObject>(%0, %3, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0>
|
|
dealloc_stack %3 : $*Builtin.NativeObject // id: %8
|
|
|
|
%1g = function_ref @XXX_init_guaranteed : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0>
|
|
%3g = alloc_stack $Builtin.NativeObject // users: %6, %7, %8
|
|
%3g_out = alloc_stack $XXX<Builtin.NativeObject> // users: %6, %7, %8
|
|
%arg1g = copy_value %arg : $Builtin.NativeObject
|
|
store %arg1g to [init] %3g : $*Builtin.NativeObject // id: %6
|
|
%7g = apply %1<Builtin.NativeObject>(%3g_out, %3g, %2) : $@convention(thin) <τ_0_0> (@in τ_0_0, @thin XXX<τ_0_0>.Type) -> @out XXX<τ_0_0>
|
|
destroy_addr %3g_out : $*XXX<Builtin.NativeObject>
|
|
dealloc_stack %3g_out : $*XXX<Builtin.NativeObject>
|
|
dealloc_stack %3g : $*Builtin.NativeObject // id: %8
|
|
|
|
// function_ref specialize.acceptsInt (Swift.Int32) -> ()
|
|
%9 = function_ref @acceptsInt : $@convention(thin) (Int32) -> () // user: %16
|
|
// function_ref specialize.XXX.foo <A>(@inout specialize.XXX<A>)(t : A) -> Swift.Int32
|
|
%10 = function_ref @XXX_foo : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15
|
|
%11 = alloc_stack $Builtin.NativeObject // users: %14, %15, %17
|
|
%arg2 = copy_value %arg : $Builtin.NativeObject
|
|
store %arg2 to [init] %11 : $*Builtin.NativeObject
|
|
%15 = apply %10<Builtin.NativeObject>(%11, %0) : $@convention(method) <τ_0_0> (@in τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16
|
|
%16 = apply %9(%15) : $@convention(thin) (Int32) -> ()
|
|
dealloc_stack %11 : $*Builtin.NativeObject // id: %17
|
|
|
|
%10g = function_ref @XXX_foo_guaranteed : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %15
|
|
%11g = alloc_stack $Builtin.NativeObject // users: %14, %15, %17
|
|
%arg2g = copy_value %arg : $Builtin.NativeObject
|
|
store %arg2g to [init] %11g : $*Builtin.NativeObject
|
|
%15g = apply %10g<Builtin.NativeObject>(%11g, %0) : $@convention(method) <τ_0_0> (@in_guaranteed τ_0_0, @inout XXX<τ_0_0>) -> Int32 // user: %16
|
|
apply %9(%15g) : $@convention(thin) (Int32) -> ()
|
|
destroy_addr %11g : $*Builtin.NativeObject
|
|
dealloc_stack %11g : $*Builtin.NativeObject // id: %17
|
|
|
|
%17 = function_ref @XXX_foo_guaranteed_generic_return : $@convention(method) <T> (@in_guaranteed T, @in XXX<T>) -> @out T
|
|
%18 = alloc_stack $Builtin.NativeObject
|
|
%19 = alloc_stack $Builtin.NativeObject
|
|
%arg3 = copy_value %arg : $Builtin.NativeObject
|
|
store %arg3 to [init] %18 : $*Builtin.NativeObject
|
|
apply %17<Builtin.NativeObject>(%19, %18, %0) : $@convention(method) <T> (@in_guaranteed T, @in XXX<T>) -> @out T
|
|
destroy_addr %18 : $*Builtin.NativeObject
|
|
destroy_addr %19 : $*Builtin.NativeObject
|
|
dealloc_stack %19 : $*Builtin.NativeObject
|
|
dealloc_stack %18 : $*Builtin.NativeObject
|
|
|
|
dealloc_stack %0 : $*XXX<Builtin.NativeObject>
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
// specialize.useClosure <A>(fun : () -> A) -> A
|
|
sil [ossa] @useClosure : $@convention(thin) <T> (@owned @callee_owned () -> @out T) -> @out T {
|
|
bb0(%0 : $*T, %1 : @owned $@callee_owned () -> @out T):
|
|
debug_value %1 : $@callee_owned () -> @out T, let, name "fun" // id: %2
|
|
%2 = copy_value %1 : $@callee_owned () -> @out T // id: %3
|
|
%4 = apply %2(%0) : $@callee_owned () -> @out T
|
|
destroy_value %1 : $@callee_owned () -> @out T // id: %5
|
|
%6 = tuple () // user: %7
|
|
return %6 : $() // id: %7
|
|
}
|
|
|
|
// specialize.getGenericClosure <A>(t : A) -> () -> A
|
|
sil [ossa] @getGenericClosure : $@convention(thin) <T> (@in T) -> @owned @callee_owned () -> @out T {
|
|
bb0(%0 : $*T):
|
|
debug_value %0 : $*T, let, name "t", expr op_deref // id: %1
|
|
// function_ref specialize.(getGenericClosure <A>(t : A) -> () -> A).(tmp #1) (())A
|
|
%2 = function_ref @getGenericClosure_closure : $@convention(thin) <τ_0_0> (@owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> @out τ_0_0 // user: %5
|
|
%3 = alloc_box $<τ_0_0> { var τ_0_0 } <T>
|
|
%3b = begin_borrow %3 : $<τ_0_0> { var τ_0_0 } <T>
|
|
%3a = project_box %3b : $<τ_0_0> { var τ_0_0 } <T>, 0
|
|
copy_addr %0 to [init] %3a : $*T // id: %4
|
|
end_borrow %3b : $<τ_0_0> { var τ_0_0 } <T>
|
|
%5 = partial_apply %2<T>(%3) : $@convention(thin) <τ_0_0> (@owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> @out τ_0_0 // user: %7
|
|
destroy_addr %0 : $*T // id: %6
|
|
return %5 : $@callee_owned () -> @out T // id: %7
|
|
}
|
|
|
|
// specialize.(getGenericClosure <A>(t : A) -> () -> A).(tmp #1) (())
|
|
sil shared [ossa] @getGenericClosure_closure : $@convention(thin) <T> (@owned <τ_0_0> { var τ_0_0 } <T>) -> @out T {
|
|
bb0(%0 : $*T, %1 : @owned $<τ_0_0> { var τ_0_0 } <T>):
|
|
%1a = begin_borrow %1 : $<τ_0_0> { var τ_0_0 } <T>
|
|
%2 = project_box %1a : $<τ_0_0> { var τ_0_0 } <T>, 0
|
|
copy_addr %2 to [init] %0 : $*T // id: %3
|
|
end_borrow %1a : $<τ_0_0> { var τ_0_0 } <T>
|
|
destroy_value %1 : $<τ_0_0> { var τ_0_0 } <T> // id: %4
|
|
%5 = tuple () // user: %6
|
|
return %5 : $() // id: %6
|
|
}
|
|
|
|
// specialize.specializePartialApplies () -> Swift.UInt8
|
|
sil [ossa] @specializePartialApplies : $@convention(thin) () -> UInt8 {
|
|
bb0:
|
|
%0 = alloc_stack $UInt8, var, name "i" // users: %3, %18
|
|
%1 = integer_literal $Builtin.Int8, 5 // user: %2
|
|
%2 = struct $UInt8 (%1 : $Builtin.Int8) // users: %3, %7
|
|
store %2 to [trivial] %0 : $*UInt8 // id: %3
|
|
// function_ref specialize.useClosure <A>(fun : () -> A) -> A
|
|
%4 = function_ref @useClosure : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> @out τ_0_0) -> @out τ_0_0 // user: %14
|
|
// function_ref specialize.getGenericClosure <A>(t : A) -> () -> A
|
|
%5 = function_ref @getGenericClosure : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned () -> @out τ_0_0 // user: %8
|
|
%6 = alloc_stack $UInt8 // users: %7, %8, %17
|
|
store %2 to [trivial] %6 : $*UInt8 // id: %7
|
|
%8 = apply %5<UInt8>(%6) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> @owned @callee_owned () -> @out τ_0_0 // user: %10
|
|
// function_ref reabstraction thunk helper from @callee_owned () -> (@out Swift.UInt8) to @callee_owned () -> (@unowned Swift.UInt8)
|
|
%9 = function_ref @$ss5UInt8VIxr_ABIxd_TR : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 // user: %10
|
|
%10 = partial_apply %9(%8) : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 // user: %12
|
|
// function_ref reabstraction thunk helper from @callee_owned () -> (@unowned Swift.UInt8) to @callee_owned () -> (@out Swift.UInt8)
|
|
%11 = function_ref @$ss5UInt8VIxd_ABIxr_TR : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 // user: %12
|
|
%12 = partial_apply %11(%10) : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 // user: %14
|
|
%13 = alloc_stack $UInt8 // users: %14, %15, %16
|
|
%14 = apply %4<UInt8>(%13, %12) : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> @out τ_0_0) -> @out τ_0_0
|
|
%15 = load [trivial] %13 : $*UInt8 // user: %19
|
|
dealloc_stack %13 : $*UInt8 // id: %16
|
|
dealloc_stack %6 : $*UInt8 // id: %17
|
|
dealloc_stack %0 : $*UInt8 // id: %18
|
|
return %15 : $UInt8 // id: %19
|
|
}
|
|
|
|
// reabstraction thunk helper from @callee_owned () -> (@out Swift.UInt8) to @callee_owned () -> (@unowned Swift.UInt8)
|
|
sil shared [ossa] [transparent] @$ss5UInt8VIxr_ABIxd_TR : $@convention(thin) (@owned @callee_owned () -> @out UInt8) -> UInt8 {
|
|
bb0(%0 : @owned $@callee_owned () -> @out UInt8):
|
|
%1 = alloc_stack $UInt8 // users: %2, %3, %4
|
|
%2 = apply %0(%1) : $@callee_owned () -> @out UInt8
|
|
%3 = load [trivial] %1 : $*UInt8 // user: %5
|
|
dealloc_stack %1 : $*UInt8 // id: %4
|
|
return %3 : $UInt8 // id: %5
|
|
}
|
|
|
|
// reabstraction thunk helper from @callee_owned () -> (@unowned Swift.UInt8) to @callee_owned () -> (@out Swift.UInt8)
|
|
sil shared [ossa] [transparent] @$ss5UInt8VIxd_ABIxr_TR : $@convention(thin) (@owned @callee_owned () -> UInt8) -> @out UInt8 {
|
|
bb0(%0 : $*UInt8, %1 : @owned $@callee_owned () -> UInt8):
|
|
%2 = apply %1() : $@callee_owned () -> UInt8 // user: %3
|
|
store %2 to [trivial] %0 : $*UInt8 // id: %3
|
|
%4 = tuple () // user: %5
|
|
return %4 : $() // id: %5
|
|
}
|
|
|
|
|
|
class Base {
|
|
}
|
|
sil_vtable Base {
|
|
}
|
|
|
|
sil [ossa] @generic_upcast : $@convention(thin) <T where T : Base> (@owned T) -> @owned Base {
|
|
bb0(%0 : @owned $T):
|
|
%2 = upcast %0 : $T to $Base
|
|
return %2 : $Base
|
|
}
|
|
|
|
sil [ossa] @specialize_generic_upcast : $@convention(thin)(@owned Base) -> @owned Base {
|
|
bb0(%0 : @owned $Base):
|
|
%1 = function_ref @generic_upcast : $@convention(thin)<T where T : Base> (@owned T) -> @owned Base
|
|
%2 = apply %1<Base>(%0) : $@convention(thin)<T where T : Base> (@owned T) -> @owned Base
|
|
return %2 : $Base
|
|
}
|
|
|
|
// CHECK-LABEL: sil shared [ossa] @{{.*}}generic_upcast{{.*}}Tg5 : $@convention(thin) (@owned Base) -> @owned Base {
|
|
// CHECK: bb0(%0 : @owned $Base):
|
|
// CHECK: return %0 : $Base
|
|
|
|
// Check generic specialization of partial_apply
|
|
|
|
protocol P { func get() -> Int32 }
|
|
|
|
struct C : P { func get() -> Int32 }
|
|
|
|
// test4.C.get (test4.C)() -> Swift.Int32
|
|
sil hidden [ossa] @C_get : $@convention(method) (C) -> Int32 {
|
|
bb0(%0 : $C):
|
|
debug_value %0 : $C, let, name "self" // id: %1
|
|
%2 = integer_literal $Builtin.Int32, 1 // user: %3
|
|
%3 = struct $Int32 (%2 : $Builtin.Int32) // user: %4
|
|
return %3 : $Int32 // id: %4
|
|
}
|
|
|
|
// test4.C.init (test4.C.Type)() -> test4.C
|
|
sil hidden [ossa][noinline] @C_init : $@convention(thin) (@thin C.Type) -> C {
|
|
bb0(%0 : $@thin C.Type):
|
|
%1 = alloc_stack $C, var, name "sf" // user: %3
|
|
%2 = struct $C () // user: %4
|
|
dealloc_stack %1 : $*C // id: %3
|
|
return %2 : $C // id: %4
|
|
}
|
|
|
|
// protocol witness for test4.P.get <A : test4.P>(test4.P.Self)() -> Swift.Int32 in conformance test4.C : test4.P in test4
|
|
sil hidden [ossa] [transparent] [thunk] @test4_P_get_witness_C : $@convention(witness_method: P) (@in_guaranteed C) -> Int32 {
|
|
bb0(%0 : $*C):
|
|
%1 = load [trivial] %0 : $*C // user: %3
|
|
// function_ref test4.C.get (test4.C)() -> Swift.Int32
|
|
%2 = function_ref @C_get : $@convention(method) (C) -> Int32 // user: %3
|
|
%3 = apply %2(%1) : $@convention(method) (C) -> Int32 // user: %4
|
|
return %3 : $Int32 // id: %4
|
|
}
|
|
|
|
// test4.boo <A : test4.P, B>(A) -> (Swift.Int32, B) -> Swift.Int32
|
|
sil hidden [ossa] [noinline] @boo : $@convention(thin) <U, T where U : P> (@in U) -> @owned @callee_owned (Int32, @in T) -> Int32 {
|
|
bb0(%0 : $*U):
|
|
debug_value %0 : $*U, let, name "y", expr op_deref // id: %1
|
|
// function_ref test4.(boo <A : test4.P, B>(A) -> (Swift.Int32, B) -> Swift.Int32).(closure #1)
|
|
%2 = function_ref @boo_closure : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> Int32 // user: %5
|
|
%3 = alloc_box $<τ_0_0> { var τ_0_0 } <U> // users: %4, %5, %5
|
|
%3a = project_box %3 : $<τ_0_0> { var τ_0_0 } <U>, 0
|
|
copy_addr %0 to [init] %3a : $*U // id: %4
|
|
%5 = partial_apply %2<U, T>(%3) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (Int32, @in τ_0_1, @owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> Int32 // user: %7
|
|
destroy_addr %0 : $*U // id: %6
|
|
return %5 : $@callee_owned (Int32, @in T) -> Int32 // id: %7
|
|
}
|
|
|
|
// test4.(boo <A : test4.P, B>(A) -> (Swift.Int32, B) -> Swift.Int32).(closure #1)
|
|
sil shared [ossa] [noinline] @boo_closure : $@convention(thin) <U, T where U : P> (Int32, @in T, @owned <τ_0_0> { var τ_0_0 } <U>) -> Int32 {
|
|
bb0(%0 : $Int32, %1 : $*T, %2 : @owned $<τ_0_0> { var τ_0_0 } <U>):
|
|
%3 = project_box %2 : $<τ_0_0> { var τ_0_0 } <U>, 0
|
|
debug_value %0 : $Int32, let, name "x" // id: %4
|
|
debug_value %1 : $*T, let, name "z", expr op_deref // id: %5
|
|
%6 = witness_method $U, #P.get : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %7
|
|
%7 = apply %6<U>(%3) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %8
|
|
%8 = struct_extract %7 : $Int32, #Int32._value // user: %11
|
|
%9 = struct_extract %0 : $Int32, #Int32._value // user: %11
|
|
%10 = integer_literal $Builtin.Int1, -1 // user: %11
|
|
%11 = builtin "sadd_with_overflow_Int32"(%8 : $Builtin.Int32, %9 : $Builtin.Int32, %10 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %12, %13
|
|
%12 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 0 // user: %15
|
|
%13 = tuple_extract %11 : $(Builtin.Int32, Builtin.Int1), 1 // user: %14
|
|
cond_fail %13 : $Builtin.Int1 // id: %14
|
|
%15 = struct $Int32 (%12 : $Builtin.Int32) // user: %18
|
|
destroy_value %2 : $<τ_0_0> { var τ_0_0 } <U> // id: %16
|
|
destroy_addr %1 : $*T // id: %17
|
|
return %15 : $Int32 // id: %18
|
|
}
|
|
|
|
// static Swift.+ infix (Swift.Int32, Swift.Int32) -> Swift.Int32
|
|
sil public_external [ossa] [transparent] [serialized] @$ss1poiys5Int32VAC_ACtFZ : $@convention(thin) (Int32, Int32) -> Int32 {
|
|
bb0(%0 : $Int32, %1 : $Int32):
|
|
%2 = struct_extract %0 : $Int32, #Int32._value // user: %5
|
|
%3 = struct_extract %1 : $Int32, #Int32._value // user: %5
|
|
%4 = integer_literal $Builtin.Int1, -1 // user: %5
|
|
%5 = builtin "sadd_with_overflow_Int32"(%2 : $Builtin.Int32, %3 : $Builtin.Int32, %4 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %6, %7
|
|
%6 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 0 // user: %9
|
|
%7 = tuple_extract %5 : $(Builtin.Int32, Builtin.Int1), 1 // user: %8
|
|
cond_fail %7 : $Builtin.Int1 // id: %8
|
|
%9 = struct $Int32 (%6 : $Builtin.Int32) // user: %10
|
|
return %9 : $Int32 // id: %10
|
|
}
|
|
|
|
// test4.foo <A : test4.P, B : test4.P>(A, B) -> (Swift.Int32, Swift.Float) -> Swift.Int32
|
|
sil hidden [ossa] [noinline] @foo : $@convention(thin) <T, U where T : P, U : P> (@in T, @in U) -> @owned @callee_owned (Int32, Float) -> Int32 {
|
|
bb0(%0 : $*T, %1 : $*U):
|
|
debug_value %0 : $*T, let, name "x", expr op_deref // id: %2
|
|
debug_value %1 : $*U, let, name "y", expr op_deref // id: %3
|
|
// function_ref test4.boo <A : test4.P, B>(A) -> (Swift.Int32, B) -> Swift.Int32
|
|
%4 = function_ref @boo : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %7
|
|
%5 = alloc_stack $U // users: %6, %7, %10
|
|
copy_addr %1 to [init] %5 : $*U // id: %6
|
|
%7 = apply %4<U, Float>(%5) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32, @in τ_0_1) -> Int32 // user: %9
|
|
// function_ref reabstraction thunk helper <T_0_0, T_0_1 where T_0_0: test4.P, T_0_1: test4.P> from @callee_owned (@unowned Swift.Int32, @in Swift.Float) -> (@unowned Swift.Int32) to @callee_owned (@unowned Swift.Int32, @unowned Swift.Float) -> (@unowned Swift.Int32)
|
|
%8 = function_ref @_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 // user: %9
|
|
%9 = partial_apply %8<T, U>(%7) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 // user: %13
|
|
dealloc_stack %5 : $*U // id: %10
|
|
destroy_addr %1 : $*U // id: %11
|
|
destroy_addr %0 : $*T // id: %12
|
|
return %9 : $@callee_owned (Int32, Float) -> Int32 // id: %13
|
|
}
|
|
|
|
// reabstraction thunk helper <T_0_0, T_0_1 where T_0_0: test4.P, T_0_1: test4.P> from @callee_owned (@unowned Swift.Int32, @in Swift.Float) -> (@unowned Swift.Int32) to @callee_owned (@unowned Swift.Int32, @unowned Swift.Float) -> (@unowned Swift.Int32)
|
|
sil shared [ossa] [transparent] [thunk] @_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__XFo_dS1_dSf_dS1__ : $@convention(thin) <T, U where T : P, U : P> (Int32, Float, @owned @callee_owned (Int32, @in Float) -> Int32) -> Int32 {
|
|
bb0(%0 : $Int32, %1 : $Float, %2 : @owned $@callee_owned (Int32, @in Float) -> Int32):
|
|
%3 = alloc_stack $Float // users: %4, %5, %6
|
|
store %1 to [trivial] %3 : $*Float // id: %4
|
|
%5 = apply %2(%0, %3) : $@callee_owned (Int32, @in Float) -> Int32 // user: %7
|
|
dealloc_stack %3 : $*Float // id: %6
|
|
return %5 : $Int32 // id: %7
|
|
}
|
|
|
|
// test4.gen1 <A : test4.P>(A) -> (Swift.Int32) -> Swift.Int32
|
|
sil hidden [ossa] [noinline] @gen1 : $@convention(thin) <T where T : P> (@in T) -> @owned @callee_owned (Int32) -> Int32 {
|
|
bb0(%0 : $*T):
|
|
debug_value %0 : $*T, let, name "x", expr op_deref // id: %1
|
|
// function_ref test4.(gen1 <A : test4.P>(A) -> (Swift.Int32) -> Swift.Int32).(closure #1)
|
|
%2 = function_ref @gen1_closure : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> Int32 // user: %5
|
|
%3 = alloc_box $<τ_0_0> { var τ_0_0 } <T> // users: %4, %5, %5
|
|
%3a = project_box %3 : $<τ_0_0> { var τ_0_0 } <T>, 0
|
|
copy_addr %0 to [init] %3a : $*T // id: %4
|
|
%5 = partial_apply %2<T>(%3) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (Int32, @owned <τ_0_0> { var τ_0_0 } <τ_0_0>) -> Int32 // user: %7
|
|
destroy_addr %0 : $*T // id: %6
|
|
return %5 : $@callee_owned (Int32) -> Int32 // id: %7
|
|
}
|
|
|
|
// test4.(gen1 <A : test4.P>(A) -> (Swift.Int32) -> Swift.Int32).(closure #1)
|
|
sil shared [ossa] [noinline] @gen1_closure : $@convention(thin) <T where T : P> (Int32, @owned <τ_0_0> { var τ_0_0 } <T>) -> Int32 {
|
|
bb0(%0 : $Int32, %1 : @owned $<τ_0_0> { var τ_0_0 } <T>):
|
|
%2 = project_box %1 : $<τ_0_0> { var τ_0_0 } <T>, 0
|
|
debug_value %0 : $Int32 , let, name "$0" // id: %3
|
|
%4 = witness_method $T, #P.get : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %5
|
|
%5 = apply %4<T>(%2) : $@convention(witness_method: P) <τ_0_0 where τ_0_0 : P> (@in_guaranteed τ_0_0) -> Int32 // user: %6
|
|
%6 = struct_extract %5 : $Int32, #Int32._value // user: %9
|
|
%7 = struct_extract %0 : $Int32, #Int32._value // user: %9
|
|
%8 = integer_literal $Builtin.Int1, -1 // user: %9
|
|
%9 = builtin "sadd_with_overflow_Int32"(%6 : $Builtin.Int32, %7 : $Builtin.Int32, %8 : $Builtin.Int1) : $(Builtin.Int32, Builtin.Int1) // users: %10, %11
|
|
%10 = tuple_extract %9 : $(Builtin.Int32, Builtin.Int1), 0 // user: %13
|
|
%11 = tuple_extract %9 : $(Builtin.Int32, Builtin.Int1), 1 // user: %12
|
|
cond_fail %11 : $Builtin.Int1 // id: %12
|
|
%13 = struct $Int32 (%10 : $Builtin.Int32) // user: %15
|
|
destroy_value %1 : $<τ_0_0> { var τ_0_0 } <T> // id: %14
|
|
return %13 : $Int32 // id: %15
|
|
}
|
|
|
|
// check that there is a generic specialization of boo
|
|
// CHECK-LABEL: sil shared [noinline] [ossa] @$s3booxs5Int32VSfACIexyid_4main1PRzSfRs_r0_lIetio_Tp5AD1CV_Tg5 : $@convention(thin) (C) -> @owned @callee_owned (Int32, @in Float) -> Int32
|
|
// CHECK: [[CLOSURE_SPECIALIZATION:%[0-9]+]] = function_ref @$s11boo_closures5Int32VSfxz_x_lXXAC4main1PRzSfRs_r0_lIetyyxd_TP5AD1CV_TG5
|
|
// CHECK: partial_apply [[CLOSURE_SPECIALIZATION:%[0-9]+]]
|
|
// CHECK: return
|
|
|
|
// Check that there is a generic specialization of a closure from boo
|
|
// CHECK-LABEL: sil shared [noinline] [ossa] @$s11boo_closures5Int32VSfxz_x_lXXAC4main1PRzSfRs_r0_lIetyyxd_Tp5AD1CV_Tg5
|
|
// CHECK: return
|
|
|
|
// Check that there is a generic specialization of foo
|
|
// CHECK-LABEL: sil shared [noinline] [ossa] @$s3foo4main1CV_ADTg5 : $@convention(thin) (C, C) -> @owned @callee_owned (Int32, Float) -> Int32
|
|
// CHECK: function_ref @$s3booxs5Int32VSfACIexyid_4main1PRzSfRs_r0_lIetio_Tp5AD1CV_Tg5
|
|
// check that it invokes a generic specialization of the reabstraction thunk helper which invokes a specialization boo
|
|
// CHECK: [[THUNK_SPECIALIZATION:%[0-9]+]] = function_ref @$s053_TTRG1_RPq_P5test41P_Pq0_PS0___XFo_dVs5Int32iSf_dS1__f2_dj2_di2_dJ2__4main1CV_ADTg5
|
|
// CHECK-NOT: apply
|
|
// CHECK: partial_apply [[THUNK_SPECIALIZATION]]
|
|
// CHECK-NOT: apply
|
|
// CHECK: return
|
|
|
|
|
|
// Check that there is a generic specialization of gen1
|
|
// CHECK-LABEL: sil shared [noinline] [ossa] @$s4gen14main1CV_Tg5 : $@convention(thin) (C) -> @owned @callee_owned (Int32) -> Int32
|
|
// check that it invokes a generic specialization of the closure by mean of partial_apply
|
|
// CHECK: [[CLOSURE_SPECIALIZATION:%[0-9]+]] = function_ref @$s12gen1_closure4main1CV_Tg5
|
|
// CHECK-NOT: apply
|
|
// CHECK: partial_apply [[CLOSURE_SPECIALIZATION]]
|
|
// CHECK-NOT: apply
|
|
// CHECK: return
|
|
|
|
// Check that there is a generic specialization of a closure from gen1
|
|
// CHECK-LABEL: sil shared [noinline] [ossa] @$s12gen1_closure4main1CV_Tg5 : $@convention(thin) (Int32, @owned <τ_0_0> { var τ_0_0 } <C>) -> Int32
|
|
// CHECK: return
|
|
|
|
|
|
|
|
// test4.bar () -> Swift.Int32
|
|
// CHECK-LABEL: sil hidden [ossa] @bar
|
|
// check that it does not invoke a generic specialization of foo
|
|
// CHECK-NOT: function_ref @foo
|
|
// check that it invokes a generic specialization of foo
|
|
// CHECK: function_ref @$s3foo4main1CV_ADTg5
|
|
sil hidden [ossa] @bar : $@convention(thin) () -> Int32 {
|
|
bb0:
|
|
%0 = alloc_stack $@callee_owned (Int32, Float) -> Int32, var, name "f" // users: %11, %22
|
|
// function_ref test4.C.init (test4.C.Type)() -> test4.C
|
|
%1 = function_ref @C_init : $@convention(thin) (@thin C.Type) -> C // user: %3
|
|
%2 = metatype $@thin C.Type // user: %3
|
|
%3 = apply %1(%2) : $@convention(thin) (@thin C.Type) -> C // users: %4, %7, %9
|
|
debug_value %3 : $C, let, name "c" // id: %4
|
|
// function_ref test4.foo <A : test4.P, B : test4.P>(A, B) -> (Swift.Int32, Swift.Float) -> Swift.Int32
|
|
%5 = function_ref @foo : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // user: %10
|
|
%6 = alloc_stack $C // users: %7, %10, %13
|
|
store %3 to [trivial] %6 : $*C // id: %7
|
|
%8 = alloc_stack $C // users: %9, %10, %12
|
|
store %3 to [trivial] %8 : $*C // id: %9
|
|
%10 = apply %5<C, C>(%6, %8) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_0 : P, τ_0_1 : P> (@in τ_0_0, @in τ_0_1) -> @owned @callee_owned (Int32, Float) -> Int32 // users: %11, %14, %20, %21
|
|
store %10 to [init] %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %11
|
|
dealloc_stack %8 : $*C // id: %12
|
|
dealloc_stack %6 : $*C // id: %13
|
|
%11 = load [take] %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %14
|
|
%15 = integer_literal $Builtin.Int32, 3 // user: %16
|
|
%16 = struct $Int32 (%15 : $Builtin.Int32) // user: %20
|
|
%17 = float_literal $Builtin.FPIEEE80, 0x4000C8F5C28F5C28F5C3 // 3.1400000000000000001 // user: %18
|
|
%18 = builtin "fptrunc_FPIEEE80_FPIEEE32"(%17 : $Builtin.FPIEEE80) : $Builtin.FPIEEE32 // user: %19
|
|
%19 = struct $Float (%18 : $Builtin.FPIEEE32) // user: %20
|
|
%20 = apply %11(%16, %19) : $@callee_owned (Int32, Float) -> Int32 // user: %23
|
|
dealloc_stack %0 : $*@callee_owned (Int32, Float) -> Int32 // id: %22
|
|
return %20 : $Int32 // id: %23
|
|
}
|
|
|
|
// test4.testBar () -> Swift.Int32
|
|
sil [ossa] @testBar : $@convention(thin) () -> Int32 {
|
|
bb0:
|
|
// function_ref test4.bar () -> Swift.Int32
|
|
%0 = function_ref @bar : $@convention(thin) () -> Int32 // user: %1
|
|
%1 = apply %0() : $@convention(thin) () -> Int32 // user: %2
|
|
return %1 : $Int32 // id: %2
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @testGen1
|
|
// Call of C_init
|
|
// CHECK: function_ref @C_init
|
|
// CHECK: apply
|
|
// Reference to the generic specialization of gen1
|
|
// CHECK-NOT: function_ref @gen1
|
|
// CHECK: function_ref @$s4gen14main1CV_Tg5 : $@convention(thin) (C) -> @owned @callee_owned (Int32) -> Int32
|
|
sil [ossa] @testGen1 : $@convention(thin) () -> Int32 {
|
|
bb0:
|
|
%0 = alloc_stack $@callee_owned (Int32) -> Int32, var, name "f" // users: %9, %16
|
|
// function_ref test4.C.init (test4.C.Type)() -> test4.C
|
|
%1 = function_ref @C_init : $@convention(thin) (@thin C.Type) -> C // user: %3
|
|
%2 = metatype $@thin C.Type // user: %3
|
|
%3 = apply %1(%2) : $@convention(thin) (@thin C.Type) -> C // users: %4, %7
|
|
debug_value %3 : $C, let, name "c" // id: %4
|
|
// function_ref test4.gen1 <A : test4.P>(A) -> (Swift.Int32) -> Swift.Int32
|
|
%5 = function_ref @gen1 : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // user: %8
|
|
%6 = alloc_stack $C // users: %7, %8, %10
|
|
store %3 to [trivial] %6 : $*C // id: %7
|
|
%8 = apply %5<C>(%6) : $@convention(thin) <τ_0_0 where τ_0_0 : P> (@in τ_0_0) -> @owned @callee_owned (Int32) -> Int32 // users: %9, %11, %14, %15
|
|
store %8 to [init] %0 : $*@callee_owned (Int32) -> Int32 // id: %9
|
|
dealloc_stack %6 : $*C // id: %10
|
|
%8a = load [take] %0 : $*@callee_owned (Int32) -> Int32 // id: %11
|
|
%12 = integer_literal $Builtin.Int32, 3 // user: %13
|
|
%13 = struct $Int32 (%12 : $Builtin.Int32) // user: %14
|
|
%14 = apply %8a(%13) : $@callee_owned (Int32) -> Int32 // user: %17
|
|
dealloc_stack %0 : $*@callee_owned (Int32) -> Int32 // id: %16
|
|
return %14 : $Int32 // id: %17
|
|
}
|
|
|
|
// test_bind<A> (Builtin.RawPointer, A.Type) -> ()
|
|
// Check that this is specialized as T=Int.
|
|
// CHECK-LABEL: sil shared [ossa] @$s9test_bindSi_Tt0g5 : $@convention(thin) (Builtin.RawPointer) -> () {
|
|
// CHECK: bind_memory %0 : $Builtin.RawPointer, {{%.*}} : $Builtin.Word to $*Int
|
|
// CHECK: return
|
|
sil hidden [ossa] @test_bind : $@convention(thin) <T> (Builtin.RawPointer, @thick T.Type) -> () {
|
|
bb0(%0 : $Builtin.RawPointer, %1 : $@thick T.Type):
|
|
%4 = integer_literal $Builtin.Word, 1
|
|
%5 = metatype $@thick T.Type
|
|
%6 = bind_memory %0 : $Builtin.RawPointer, %4 : $Builtin.Word to $*T
|
|
%7 = tuple ()
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
// Invoke test_bind with T=Int.
|
|
sil [ossa] @call_bind : $@convention(thin) (Builtin.RawPointer) -> () {
|
|
bb0(%0 : $Builtin.RawPointer):
|
|
// function_ref test_bind<A> (Builtin.RawPointer, A.Type) -> ()
|
|
%2 = function_ref @test_bind : $@convention(thin) <τ_0_0> (Builtin.RawPointer, @thick τ_0_0.Type) -> ()
|
|
%3 = metatype $@thick Int.Type
|
|
%4 = apply %2<Int>(%0, %3) : $@convention(thin) <τ_0_0> (Builtin.RawPointer, @thick τ_0_0.Type) -> ()
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// invokeGenericClosure<A>(todo:)
|
|
sil [ossa] [noinline] @invokeGenericClosure : $@convention(thin) <R> (@owned @callee_owned () -> (@out R, @error Error)) -> (@out R, @error Error) {
|
|
bb0(%0 : $*R, %1 : @owned $@callee_owned () -> (@out R, @error Error)):
|
|
debug_value %1 : $@callee_owned () -> (@out R, @error Error), let, name "todo", argno 1 // id: %2
|
|
debug_value undef : $Error, var, name "$error", argno 2 // id: %3
|
|
%1a = copy_value %1 : $@callee_owned () -> (@out R, @error Error) // id: %4
|
|
try_apply %1a(%0) : $@callee_owned () -> (@out R, @error Error), normal bb1, error bb2 // id: %5
|
|
|
|
bb1(%6 : $()): // Preds: bb0
|
|
destroy_value %1 : $@callee_owned () -> (@out R, @error Error) // id: %7
|
|
%8 = tuple () // user: %9
|
|
return %8 : $() // id: %9
|
|
|
|
// %10 // user: %12
|
|
bb2(%10 : @owned $Error): // Preds: bb0
|
|
destroy_value %1 : $@callee_owned () -> (@out R, @error Error) // id: %11
|
|
throw %10 : $Error // id: %12
|
|
} // end sil function 'invokeGenericClosure'
|
|
|
|
sil public_external @error : $@convention(thin) () -> Never
|
|
|
|
// action()
|
|
sil @action : $@convention(thin) () -> Never
|
|
|
|
// thunk for @callee_owned () -> (@unowned Never, @error @owned Error)
|
|
sil @action_thunk : $@convention(thin) (@owned @callee_owned () -> (Never, @error Error)) -> (@out Never, @error Error)
|
|
|
|
// Check that in a case where a generic specialization is a non-return function,
|
|
// the return value is not stored after the call and an unreachable instruction
|
|
// is inserted as a terminator of a basic block.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @testGenericClosureSpecialization
|
|
// Call of the generic specialization of invokeGenericClosure<Never>
|
|
// CHECK: function_ref @$s20invokeGenericClosures5NeverO_Tg5 : $@convention(thin) (@owned @callee_owned () -> (@out Never, @error any Error)) -> (Never, @error any Error)
|
|
// CHECK: apply [nothrow]
|
|
// CHECK: unreachable
|
|
// CHECK: end sil function 'testGenericClosureSpecialization'
|
|
sil [ossa] @testGenericClosureSpecialization : $@convention(thin) () -> @error Error {
|
|
bb0:
|
|
// function_ref invokeGenericClosure<A>(todo:)
|
|
%1 = function_ref @invokeGenericClosure : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error)
|
|
%2 = alloc_stack $Never
|
|
// function_ref action()
|
|
%3 = function_ref @action : $@convention(thin) () -> Never
|
|
%4 = thin_to_thick_function %3 : $@convention(thin) () -> Never to $@callee_owned () -> Never
|
|
%5 = convert_function %4 : $@callee_owned () -> Never to $@callee_owned () -> (Never, @error Error)
|
|
// function_ref thunk for @callee_owned () -> (@unowned Never, @error @owned Error)
|
|
%6 = function_ref @action_thunk : $@convention(thin) (@owned @callee_owned () -> (Never, @error Error)) -> (@out Never, @error Error)
|
|
%7 = partial_apply %6(%5) : $@convention(thin) (@owned @callee_owned () -> (Never, @error Error)) -> (@out Never, @error Error)
|
|
%8 = apply [nothrow] %1<Never>(%2, %7) : $@convention(thin) <τ_0_0> (@owned @callee_owned () -> (@out τ_0_0, @error Error)) -> (@out τ_0_0, @error Error)
|
|
unreachable
|
|
} // end sil function 'testGenericClosureSpecialization'
|
|
|
|
// Test a specialization of a self-recursive generic closure.
|
|
|
|
// CHECK-LABEL: sil shared [ossa] @$s27selfReferringGenericClosurexBi64_Bi64_Bi64_Rs_r0_lIetnyy_Tp5 : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 == Builtin.Int64> (@in_guaranteed τ_0_0, Builtin.Int64, Builtin.Int64) -> () {
|
|
// CHECK: [[SPECIALIZED_FN:%[0-9]+]] = function_ref @$s27selfReferringGenericClosurexBi64_Bi64_Bi64_Rs_r0_lIetnyy_Tp5
|
|
// CHECK: partial_apply [[SPECIALIZED_FN]]{{.*}}({{.*}}) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 == Builtin.Int64> (@in_guaranteed τ_0_0, Builtin.Int64, Builtin.Int64) -> ()
|
|
|
|
// CHECK-LABEL: sil [ossa] @selfReferringGenericClosure : $@convention(thin) <R, S> (@in_guaranteed R, @in_guaranteed S, Builtin.Int64) -> ()
|
|
// Refer to the specialized version of the function
|
|
// CHECK: [[SPECIALIZED_FN:%[0-9]+]] = function_ref @$s27selfReferringGenericClosurexBi64_Bi64_Bi64_Rs_r0_lIetnyy_Tp5
|
|
// CHECK: partial_apply [[SPECIALIZED_FN]]<R, Builtin.Int64>({{.*}}) : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 == Builtin.Int64> (@in_guaranteed τ_0_0, Builtin.Int64, Builtin.Int64) -> ()
|
|
sil [ossa] @selfReferringGenericClosure : $@convention(thin) <R, S> (@in_guaranteed R, @in_guaranteed S, Builtin.Int64) -> () {
|
|
bb0(%0 : $*R, %1 : $*S, %2 : $Builtin.Int64):
|
|
%4 = integer_literal $Builtin.Int64, 100
|
|
%5 = builtin "cmp_eq_Int64"(%2 : $Builtin.Int64, %4 : $Builtin.Int64) : $Builtin.Int1
|
|
cond_br %5, bb2, bb1
|
|
|
|
bb1:
|
|
%val_storage = alloc_stack $Builtin.Int64
|
|
%val = integer_literal $Builtin.Int64, 4
|
|
store %val to [trivial] %val_storage : $*Builtin.Int64
|
|
%fn = function_ref @selfReferringGenericClosure : $@convention(thin) <U, V> (@in_guaranteed U, @in_guaranteed V, Builtin.Int64) -> ()
|
|
%s = alloc_stack $R
|
|
copy_addr %0 to [init] %s : $*R
|
|
%7 = partial_apply %fn<R, Builtin.Int64>(%s, %val_storage, %4) : $@convention(thin) <U, V> (@in_guaranteed U, @in_guaranteed V, Builtin.Int64) -> ()
|
|
dealloc_stack %s : $*R
|
|
dealloc_stack %val_storage : $*Builtin.Int64
|
|
destroy_value %7 : $@callee_owned () -> ()
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
sil [ossa] @selfReferringGenericClosure_nontrivial_guaranteed : $@convention(thin) <R, S> (@in_guaranteed R, @in_guaranteed S, @guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*R, %1 : $*S, %2 : @guaranteed $Builtin.NativeObject):
|
|
cond_br undef, bb2, bb1
|
|
|
|
bb1:
|
|
%val_storage = alloc_stack $Builtin.NativeObject
|
|
%val = copy_value %2 : $Builtin.NativeObject
|
|
%val2 = copy_value %2 : $Builtin.NativeObject
|
|
store %val to [init] %val_storage : $*Builtin.NativeObject
|
|
%fn = function_ref @selfReferringGenericClosure_nontrivial_guaranteed : $@convention(thin) <U, V> (@in_guaranteed U, @in_guaranteed V, @guaranteed Builtin.NativeObject) -> ()
|
|
%s = alloc_stack $R
|
|
copy_addr %0 to [init] %s : $*R
|
|
%7 = partial_apply %fn<R, Builtin.NativeObject>(%s, %val_storage, %val2) : $@convention(thin) <U, V> (@in_guaranteed U, @in_guaranteed V, @guaranteed Builtin.NativeObject) -> ()
|
|
dealloc_stack %s : $*R
|
|
dealloc_stack %val_storage : $*Builtin.NativeObject
|
|
destroy_value %7 : $@callee_owned () -> ()
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
sil [ossa] @selfReferringGenericClosure_nontrivial_guaranteed_applied : $@convention(thin) <R, S> (@in_guaranteed R, @in_guaranteed S, @guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*R, %1 : $*S, %2 : @guaranteed $Builtin.NativeObject):
|
|
cond_br undef, bb2, bb1
|
|
|
|
bb1:
|
|
%val_storage = alloc_stack $Builtin.NativeObject
|
|
%val = copy_value %2 : $Builtin.NativeObject
|
|
%val2 = copy_value %2 : $Builtin.NativeObject
|
|
store %val to [init] %val_storage : $*Builtin.NativeObject
|
|
%fn = function_ref @selfReferringGenericClosure_nontrivial_guaranteed_applied : $@convention(thin) <U, V> (@in_guaranteed U, @in_guaranteed V, @guaranteed Builtin.NativeObject) -> ()
|
|
%s = alloc_stack $R
|
|
copy_addr %0 to [init] %s : $*R
|
|
%7 = partial_apply %fn<R, Builtin.NativeObject>(%s, %val_storage, %val2) : $@convention(thin) <U, V> (@in_guaranteed U, @in_guaranteed V, @guaranteed Builtin.NativeObject) -> ()
|
|
dealloc_stack %s : $*R
|
|
apply %7() :$@callee_owned () -> ()
|
|
dealloc_stack %val_storage : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb2:
|
|
br bb3
|
|
|
|
bb3:
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
//----
|
|
|
|
// CHECK-LABEL: sil [ossa] @selfReferringGenericClosure_nontrivial_owned : $@convention(thin) <R, S> (@in R, @in S, @owned Builtin.NativeObject) -> () {
|
|
// CHECK: [[FUNC:%.*]] = function_ref @$s44selfReferringGenericClosure_nontrivial_ownedxBoBoBoRs_r0_lIetixx_Tp5 : $@convention(thin) <τ_0_0, τ_0_1 where τ_0_1 == Builtin.NativeObject> (@in τ_0_0, @owned Builtin.NativeObject, @owned Builtin.NativeObject) -> ()
|
|
// CHECK: [[PAI:%.*]] = partial_apply [[FUNC]]<
|
|
// CHECK: destroy_value [[PAI]]
|
|
// CHECK: } // end sil function 'selfReferringGenericClosure_nontrivial_owned'
|
|
sil [ossa] @selfReferringGenericClosure_nontrivial_owned : $@convention(thin) <R, S> (@in R, @in S, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*R, %1 : $*S, %2 : @owned $Builtin.NativeObject):
|
|
cond_br undef, bb2, bb1
|
|
|
|
bb1:
|
|
%val_storage = alloc_stack $Builtin.NativeObject
|
|
%val = copy_value %2 : $Builtin.NativeObject
|
|
store %val to [init] %val_storage : $*Builtin.NativeObject
|
|
%fn = function_ref @selfReferringGenericClosure_nontrivial_owned : $@convention(thin) <U, V> (@in U, @in V, @owned Builtin.NativeObject) -> ()
|
|
%7 = partial_apply %fn<R, Builtin.NativeObject>(%0, %val_storage, %2) : $@convention(thin) <U, V> (@in U, @in V, @owned Builtin.NativeObject) -> ()
|
|
dealloc_stack %val_storage : $*Builtin.NativeObject
|
|
destroy_value %7 : $@callee_owned () -> ()
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_value %2 : $Builtin.NativeObject
|
|
destroy_addr %0 : $*R
|
|
br bb3
|
|
|
|
bb3:
|
|
destroy_addr %1 : $*S
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
sil [ossa] @selfReferringGenericClosure_nontrivial_owned_applied : $@convention(thin) <R, S> (@in R, @in S, @owned Builtin.NativeObject) -> () {
|
|
bb0(%0 : $*R, %1 : $*S, %2 : @owned $Builtin.NativeObject):
|
|
cond_br undef, bb2, bb1
|
|
|
|
bb1:
|
|
%val_storage = alloc_stack $Builtin.NativeObject
|
|
%val = copy_value %2 : $Builtin.NativeObject
|
|
store %val to [init] %val_storage : $*Builtin.NativeObject
|
|
%fn = function_ref @selfReferringGenericClosure_nontrivial_owned_applied : $@convention(thin) <U, V> (@in U, @in V, @owned Builtin.NativeObject) -> ()
|
|
%7 = partial_apply %fn<R, Builtin.NativeObject>(%0, %val_storage, %2) : $@convention(thin) <U, V> (@in U, @in V, @owned Builtin.NativeObject) -> ()
|
|
apply %7() :$@callee_owned () -> ()
|
|
dealloc_stack %val_storage : $*Builtin.NativeObject
|
|
br bb3
|
|
|
|
bb2:
|
|
destroy_value %2 : $Builtin.NativeObject
|
|
destroy_addr %0 : $*R
|
|
br bb3
|
|
|
|
bb3:
|
|
destroy_addr %1 : $*S
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
struct YYY<T> {
|
|
}
|
|
|
|
enum MyOptional<T> {
|
|
case none
|
|
case some(T)
|
|
}
|
|
|
|
// Check that a specialization of a self-recursive function is produced
|
|
// and it is not crashing the compiler.
|
|
// CHECK-LABEL: sil shared [ossa] @$s25testSelfRecursiveFunction4main10MyOptionalOyAB3YYYVyypGG_Tg5 : $@convention(thin) (MyOptional<YYY<Any>>) -> ()
|
|
sil [ossa] @testSelfRecursiveFunction : $@convention(thin) <T> (@in T) -> () {
|
|
bb0(%0 : $*T):
|
|
%2 = function_ref @testSelfRecursiveFunction : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
|
|
%3 = alloc_stack $MyOptional<YYY<Any>>
|
|
inject_enum_addr %3 : $*MyOptional<YYY<Any>>, #MyOptional.none!enumelt
|
|
%5 = tuple ()
|
|
%6 = load [trivial] %3 : $*MyOptional<YYY<Any>>
|
|
%7 = alloc_stack $MyOptional<YYY<Any>>
|
|
store %6 to [trivial] %7 : $*MyOptional<YYY<Any>>
|
|
%9 = apply %2<MyOptional<YYY<Any>>>(%7) : $@convention(thin) <τ_0_0> (@in τ_0_0) -> ()
|
|
dealloc_stack %7 : $*MyOptional<YYY<Any>>
|
|
dealloc_stack %3 : $*MyOptional<YYY<Any>>
|
|
destroy_addr %0 : $*T
|
|
%13 = tuple ()
|
|
return %13 : $()
|
|
} // end sil function 'testSelfRecursiveFunction'
|
|
|
|
sil [ossa] @id : $@convention(thin) <T> (@in T) -> @out T {
|
|
bb0(%0 : $*T, %1 :$*T):
|
|
copy_addr [take] %1 to [init] %0 : $*T
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
// This should not assert.
|
|
// CHECK-LABEL: sil shared [ossa] @$s26specialize_no_return_applys5NeverO_Ttg5 : $@convention(thin) () -> () {
|
|
// CHECK: apply
|
|
// CHECK-NEXT: unreachable
|
|
|
|
sil [ossa] @specialize_no_return_apply: $@convention(thin) <T> (@thick T.Type) -> () {
|
|
bb0(%0 : $@thick T.Type):
|
|
%in = alloc_stack $T
|
|
copy_addr [take] undef to [init] %in : $*T
|
|
%out = alloc_stack $T
|
|
%f = function_ref @id : $@convention(thin) <T> (@in T) -> @out T
|
|
%r = apply %f<T>(%out, %in) : $@convention(thin) <T> (@in T) -> @out T
|
|
destroy_addr %out : $*T
|
|
dealloc_stack %out : $*T
|
|
dealloc_stack %in : $*T
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
sil [ossa] @test_specialize_noreturn_apply : $@convention(thin) () -> () {
|
|
bb0:
|
|
%f = function_ref @specialize_no_return_apply : $@convention(thin) <T> (@thick T.Type) -> ()
|
|
%m = metatype $@thick Never.Type
|
|
%r = apply %f<Never>(%m) : $@convention(thin) <T> (@thick T.Type) -> ()
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
////////////////////
|
|
// TryApply Tests //
|
|
////////////////////
|
|
|
|
sil @getError : $@convention(thin) () -> @owned Error
|
|
|
|
sil [ossa] @generic_try_apply_callee2 : $@convention(thin) <T> (@in_guaranteed T) -> @error Error {
|
|
bb0(%0 : $*T):
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%f = function_ref @getError : $@convention(thin) () -> @owned Error
|
|
%e = apply %f() : $@convention(thin) () -> @owned Error
|
|
throw %e : $Error
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @generic_try_apply_callee : $@convention(thin) <T> (@in_guaranteed T) -> @error Error {
|
|
bb0(%0 : $*T):
|
|
%f = function_ref @generic_try_apply_callee2 : $@convention(thin) <T> (@in_guaranteed T) -> @error Error
|
|
try_apply %f<T>(%0) : $@convention(thin) <T> (@in_guaranteed T) -> @error Error, normal bb1, error bb2
|
|
|
|
bb1(%result : $()):
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
|
|
bb2(%e : @owned $Error):
|
|
throw %e : $Error
|
|
}
|
|
|
|
sil [ossa] @generic_try_apply_callee2_out_param : $@convention(thin) <T> (@in_guaranteed T) -> (@out T, @error Error) {
|
|
bb0(%0 : $*T, %1 : $*T):
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%f = function_ref @getError : $@convention(thin) () -> @owned Error
|
|
%e = apply %f() : $@convention(thin) () -> @owned Error
|
|
throw %e : $Error
|
|
|
|
bb2:
|
|
copy_addr %1 to [init] %0 : $*T
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
|
|
sil [ossa] @generic_try_apply_callee_out_param : $@convention(thin) <T> (@in_guaranteed T) -> (@out T, @error Error) {
|
|
bb0(%0 : $*T, %1 : $*T):
|
|
%f = function_ref @generic_try_apply_callee2_out_param : $@convention(thin) <T> (@in_guaranteed T) -> (@out T, @error Error)
|
|
try_apply %f<T>(%0, %1) : $@convention(thin) <T> (@in_guaranteed T) -> (@out T, @error Error), normal bb1, error bb2
|
|
|
|
bb1(%result : $()):
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
|
|
bb2(%e : @owned $Error):
|
|
throw %e : $Error
|
|
}
|
|
|
|
// Just make sure we pass the verifiers.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @test_try_apply : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () {
|
|
// CHECK: try_apply {{%.*}}({{%.*}}) : $@convention(thin) (Builtin.Int32) -> @error any Error, normal bb1, error bb2
|
|
// CHECK: try_apply {{%.*}}({{%.*}}) : $@convention(thin) (@guaranteed Builtin.NativeObject) -> @error any Error, normal bb4, error bb5
|
|
// CHECK: } // end sil function 'test_try_apply'
|
|
sil [ossa] @test_try_apply : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject):
|
|
%f = function_ref @generic_try_apply_callee : $@convention(thin) <T> (@in_guaranteed T) -> @error Error
|
|
|
|
%0a = alloc_stack $Builtin.Int32
|
|
store %0 to [trivial] %0a : $*Builtin.Int32
|
|
try_apply %f<Builtin.Int32>(%0a) : $@convention(thin) <T> (@in_guaranteed T) -> @error Error, normal bb1, error bb2
|
|
|
|
bb1(%result : $()):
|
|
br bb3
|
|
|
|
bb2(%e : @owned $Error):
|
|
destroy_value %e : $Error
|
|
br bb3
|
|
|
|
bb3:
|
|
dealloc_stack %0a : $*Builtin.Int32
|
|
|
|
%0b = alloc_stack $Builtin.NativeObject
|
|
%sb1 = store_borrow %1 to %0b : $*Builtin.NativeObject
|
|
try_apply %f<Builtin.NativeObject>(%sb1) : $@convention(thin) <T> (@in_guaranteed T) -> @error Error, normal bb4, error bb5
|
|
|
|
bb4(%result2 : $()):
|
|
br bb6
|
|
|
|
bb5(%e2 : @owned $Error):
|
|
destroy_value %e2 : $Error
|
|
br bb6
|
|
|
|
bb6:
|
|
end_borrow %sb1 : $*Builtin.NativeObject
|
|
dealloc_stack %0b : $*Builtin.NativeObject
|
|
|
|
%0c = alloc_stack $Builtin.NativeObject
|
|
%sb2 = store_borrow %1 to %0c : $*Builtin.NativeObject
|
|
%outParam = alloc_stack $Builtin.NativeObject
|
|
%f2 = function_ref @generic_try_apply_callee_out_param : $@convention(thin) <T> (@in_guaranteed T) -> (@out T, @error Error)
|
|
try_apply %f2<Builtin.NativeObject>(%outParam, %sb2) : $@convention(thin) <T> (@in_guaranteed T) -> (@out T, @error Error), normal bb7, error bb8
|
|
|
|
bb7(%result3 : $()):
|
|
destroy_addr %outParam : $*Builtin.NativeObject
|
|
br bb9
|
|
|
|
bb8(%error4 : @owned $Error):
|
|
destroy_value %error4 : $Error
|
|
br bb9
|
|
|
|
bb9:
|
|
end_borrow %sb2 : $*Builtin.NativeObject
|
|
dealloc_stack %outParam : $*Builtin.NativeObject
|
|
dealloc_stack %0c : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// Test cases where we throw instead of catch.
|
|
sil [ossa] @test_try_apply_throw_error : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> @error Error {
|
|
bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject):
|
|
%f = function_ref @generic_try_apply_callee : $@convention(thin) <T> (@in_guaranteed T) -> @error Error
|
|
|
|
%0a = alloc_stack $Builtin.Int32
|
|
store %0 to [trivial] %0a : $*Builtin.Int32
|
|
try_apply %f<Builtin.Int32>(%0a) : $@convention(thin) <T> (@in_guaranteed T) -> @error Error, normal bb1, error bb2
|
|
|
|
bb1(%result : $()):
|
|
br bb3
|
|
|
|
bb2(%e : @owned $Error):
|
|
dealloc_stack %0a : $*Builtin.Int32
|
|
br bbError(%e : $Error)
|
|
|
|
bb3:
|
|
dealloc_stack %0a : $*Builtin.Int32
|
|
%0b = alloc_stack $Builtin.NativeObject
|
|
%sb = store_borrow %1 to %0b : $*Builtin.NativeObject
|
|
try_apply %f<Builtin.NativeObject>(%sb) : $@convention(thin) <T> (@in_guaranteed T) -> @error Error, normal bb4, error bb5
|
|
|
|
bb4(%result2 : $()):
|
|
end_borrow %sb : $*Builtin.NativeObject
|
|
br bb6
|
|
|
|
bb5(%e2 : @owned $Error):
|
|
end_borrow %sb : $*Builtin.NativeObject
|
|
dealloc_stack %0b : $*Builtin.NativeObject
|
|
br bbError(%e2 : $Error)
|
|
|
|
bbError(%eOut : @owned $Error):
|
|
throw %eOut : $Error
|
|
|
|
bb6:
|
|
dealloc_stack %0b : $*Builtin.NativeObject
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @generic_try_apply_callee_loadable_2 : $@convention(thin) <T : AnyObject> (@inout T, @guaranteed T) -> @error Error {
|
|
bb0(%0 : $*T, %1 : @guaranteed $T
|
|
):
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
%f = function_ref @getError : $@convention(thin) () -> @owned Error
|
|
%e = apply %f() : $@convention(thin) () -> @owned Error
|
|
throw %e : $Error
|
|
|
|
bb2:
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @generic_try_apply_callee_loadable_1 : $@convention(thin) <T : AnyObject> (@inout T, @in_guaranteed T) -> @error Error {
|
|
bb0(%0 : $*T, %1 : $*T):
|
|
%f = function_ref @generic_try_apply_callee_loadable_2 : $@convention(thin) <T : AnyObject> (@inout T, @guaranteed T) -> @error Error
|
|
%1b = load_borrow %1 : $*T
|
|
try_apply %f<T>(%0, %1b) : $@convention(thin) <T : AnyObject> (@inout T, @guaranteed T) -> @error Error, normal bb1, error bb2
|
|
|
|
bb1(%result : $()):
|
|
end_borrow %1b : $T
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
|
|
bb2(%e : @owned $Error):
|
|
end_borrow %1b : $T
|
|
throw %e : $Error
|
|
}
|
|
|
|
sil [ossa] @test_try_apply_loadable : $@convention(thin) (@inout Klass, @guaranteed Klass) -> () {
|
|
bb0(%0 : $*Klass, %1 : @guaranteed $Klass):
|
|
%f = function_ref @generic_try_apply_callee_loadable_1 : $@convention(thin) <T : AnyObject> (@inout T, @in_guaranteed T) -> @error Error
|
|
%1b = alloc_stack $Klass
|
|
%sb = store_borrow %1 to %1b : $*Klass
|
|
try_apply %f<Klass>(%0, %sb) : $@convention(thin) <T : AnyObject> (@inout T, @in_guaranteed T) -> @error Error, normal bb4, error bb5
|
|
|
|
bb4(%result2 : $()):
|
|
br bb6
|
|
|
|
bb5(%e2 : @owned $Error):
|
|
destroy_value %e2 : $Error
|
|
br bb6
|
|
|
|
bb6:
|
|
end_borrow %sb : $*Klass
|
|
dealloc_stack %1b : $*Klass
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @loadable_partial_apply_user : $@convention(thin) (@guaranteed @callee_guaranteed (@inout Klass) -> @error Error) -> () {
|
|
bb0(%0 : @guaranteed $@callee_guaranteed (@inout Klass) -> @error Error):
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @test_try_apply_loadable_partial_apply : $@convention(thin) (@inout Klass, @guaranteed Klass) -> () {
|
|
bb0(%0 : $*Klass, %1 : @guaranteed $Klass):
|
|
%f = function_ref @generic_try_apply_callee_loadable_1 : $@convention(thin) <T : AnyObject> (@inout T, @in_guaranteed T) -> @error Error
|
|
%1b = alloc_stack $Klass
|
|
%1a = copy_value %1 : $Klass
|
|
store %1a to [init] %1b : $*Klass
|
|
%f2 = partial_apply [callee_guaranteed] %f<Klass>(%1b) : $@convention(thin) <T : AnyObject> (@inout T, @in_guaranteed T) -> @error Error
|
|
%f3 = function_ref @loadable_partial_apply_user : $@convention(thin) (@guaranteed @callee_guaranteed (@inout Klass) -> @error Error) -> ()
|
|
apply %f3(%f2) : $@convention(thin) (@guaranteed @callee_guaranteed (@inout Klass) -> @error Error) -> ()
|
|
destroy_value %f2 : $@callee_guaranteed (@inout Klass) -> @error Error
|
|
dealloc_stack %1b : $*Klass
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
//////////////////////
|
|
// BeginApply Tests //
|
|
//////////////////////
|
|
|
|
sil [ossa] @generic_begin_apply_callee_inguaranteed : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @in_guaranteed T {
|
|
bb0(%0 : $*T):
|
|
%1 = alloc_stack $*T
|
|
copy_addr %0 to [init] %1 : $*T
|
|
yield %1 : $*T, resume bb1, unwind bb2
|
|
|
|
bb1:
|
|
destroy_addr %1 : $*T
|
|
dealloc_stack %1 : $*T
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
|
|
bb2:
|
|
destroy_addr %1 : $*T
|
|
dealloc_stack %1 : $*T
|
|
unwind
|
|
}
|
|
|
|
sil [ossa] @generic_begin_apply_callee_in : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @in T {
|
|
bb0(%0 : $*T):
|
|
%1 = alloc_stack $*T
|
|
copy_addr %0 to [init] %1 : $*T
|
|
yield %1 : $*T, resume bb1, unwind bb2
|
|
|
|
bb1:
|
|
dealloc_stack %1 : $*T
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
|
|
bb2:
|
|
dealloc_stack %1 : $*T
|
|
unwind
|
|
}
|
|
|
|
sil [ossa] @generic_begin_apply_callee_inout : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @inout T {
|
|
bb0(%0 : $*T):
|
|
%1 = alloc_stack $*T
|
|
copy_addr %0 to [init] %1 : $*T
|
|
yield %1 : $*T, resume bb1, unwind bb2
|
|
|
|
bb1:
|
|
destroy_addr %1 : $*T
|
|
dealloc_stack %1 : $*T
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
|
|
bb2:
|
|
destroy_addr %1 : $*T
|
|
dealloc_stack %1 : $*T
|
|
unwind
|
|
}
|
|
|
|
sil [ossa] @calling_generic_co_routine_with_exit_edge : $@convention(thin) <T> (@in_guaranteed T) -> () {
|
|
bb0(%0 : $*T):
|
|
%1 = function_ref @generic_begin_apply_callee_inout : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @inout T
|
|
(%2, %3) = begin_apply %1<T>(%0) : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @inout T
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
end_borrow %3
|
|
unreachable
|
|
|
|
bb2:
|
|
%7 = end_apply %3 as $()
|
|
%8 = tuple ()
|
|
return %8
|
|
}
|
|
|
|
|
|
// Just make sure we pass the verifiers.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @test_calling_generic_co_routine_with_exit_edge :
|
|
// CHECK: %2 = load_borrow %0
|
|
// CHECK: apply %1(%2)
|
|
// CHECK: } // end sil function 'test_calling_generic_co_routine_with_exit_edge'
|
|
sil [ossa] @test_calling_generic_co_routine_with_exit_edge : $@convention(thin) (@in_guaranteed String) -> () {
|
|
bb0(%0 : $*String):
|
|
%1 = function_ref @calling_generic_co_routine_with_exit_edge : $@convention(thin) <T> (@in_guaranteed T) -> ()
|
|
%2 = apply %1<String>(%0) : $@convention(thin) <T> (@in_guaranteed T) -> ()
|
|
%3 = tuple ()
|
|
return %3
|
|
}
|
|
|
|
// Just make sure we pass the verifiers.
|
|
//
|
|
// CHECK-LABEL: sil [ossa] @test_begin_apply_inguaranteed : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () {
|
|
// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (Builtin.Int32) -> @yields @in_guaranteed Builtin.Int32
|
|
// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> @yields @in_guaranteed Builtin.NativeObject
|
|
// CHECK: } // end sil function 'test_begin_apply_inguaranteed'
|
|
sil [ossa] @test_begin_apply_inguaranteed : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject):
|
|
%f = function_ref @generic_begin_apply_callee_inguaranteed : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @in_guaranteed T
|
|
|
|
%0a = alloc_stack $Builtin.Int32
|
|
store %0 to [trivial] %0a : $*Builtin.Int32
|
|
(%0r, %0token) = begin_apply %f<Builtin.Int32>(%0a) : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @in_guaranteed T
|
|
end_apply %0token as $()
|
|
dealloc_stack %0a : $*Builtin.Int32
|
|
|
|
%1b = alloc_stack $Builtin.NativeObject
|
|
%1c = copy_value %1 : $Builtin.NativeObject
|
|
store %1c to [init] %1b : $*Builtin.NativeObject
|
|
(%1result, %1token) = begin_apply %f<Builtin.NativeObject>(%1b) : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @in_guaranteed T
|
|
|
|
end_apply %1token as $()
|
|
destroy_addr %1b : $*Builtin.NativeObject
|
|
dealloc_stack %1b : $*Builtin.NativeObject
|
|
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_begin_apply_in : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () {
|
|
// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (Builtin.Int32) -> @yields @in Builtin.Int32
|
|
// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> @yields @in Builtin.NativeObject
|
|
// CHECK: } // end sil function 'test_begin_apply_in'
|
|
sil [ossa] @test_begin_apply_in : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject):
|
|
%f = function_ref @generic_begin_apply_callee_in : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @in T
|
|
|
|
%0a = alloc_stack $Builtin.Int32
|
|
store %0 to [trivial] %0a : $*Builtin.Int32
|
|
(%0r, %0token) = begin_apply %f<Builtin.Int32>(%0a) : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @in T
|
|
end_apply %0token as $()
|
|
dealloc_stack %0a : $*Builtin.Int32
|
|
|
|
%1b = alloc_stack $Builtin.NativeObject
|
|
%1c = copy_value %1 : $Builtin.NativeObject
|
|
store %1c to [init] %1b : $*Builtin.NativeObject
|
|
(%1result, %1token) = begin_apply %f<Builtin.NativeObject>(%1b) : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @in T
|
|
destroy_addr %1result : $*Builtin.NativeObject
|
|
|
|
end_apply %1token as $()
|
|
destroy_addr %1b : $*Builtin.NativeObject
|
|
dealloc_stack %1b : $*Builtin.NativeObject
|
|
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @test_begin_apply_inout : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () {
|
|
// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (Builtin.Int32) -> @yields @inout Builtin.Int32
|
|
// CHECK: begin_apply {{%.*}}({{%.*}}) : $@yield_once @convention(thin) (@guaranteed Builtin.NativeObject) -> @yields @inout Builtin.NativeObject
|
|
// CHECK: } // end sil function 'test_begin_apply_inout'
|
|
sil [ossa] @test_begin_apply_inout : $@convention(thin) (Builtin.Int32, @guaranteed Builtin.NativeObject) -> () {
|
|
bb0(%0 : $Builtin.Int32, %1 : @guaranteed $Builtin.NativeObject):
|
|
%f = function_ref @generic_begin_apply_callee_inout : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @inout T
|
|
|
|
%0a = alloc_stack $Builtin.Int32
|
|
store %0 to [trivial] %0a : $*Builtin.Int32
|
|
(%0r, %0token) = begin_apply %f<Builtin.Int32>(%0a) : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @inout T
|
|
end_apply %0token as $()
|
|
dealloc_stack %0a : $*Builtin.Int32
|
|
|
|
%1b = alloc_stack $Builtin.NativeObject
|
|
%1c = copy_value %1 : $Builtin.NativeObject
|
|
store %1c to [init] %1b : $*Builtin.NativeObject
|
|
(%1result, %1token) = begin_apply %f<Builtin.NativeObject>(%1b) : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @inout T
|
|
|
|
end_apply %1token as $()
|
|
destroy_addr %1b : $*Builtin.NativeObject
|
|
dealloc_stack %1b : $*Builtin.NativeObject
|
|
|
|
%9999 = tuple()
|
|
return %9999 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @co_routine_with_exit_edge :
|
|
// CHECK: [[L:%.*]] = load_borrow %0
|
|
// CHECK: ({{%.*}}, [[T:%.*]]) = begin_apply {{%.*}}([[L]]) : $@yield_once @convention(thin) (@guaranteed String) -> @yields @inout String
|
|
// CHECK: bb1:
|
|
// CHECK: end_borrow [[T]]
|
|
// CHECK: end_borrow [[L]]
|
|
// CHECK: unreachable
|
|
// CHECK: bb2:
|
|
// CHECK: end_apply [[T]]
|
|
// CHECK: end_borrow [[L]]
|
|
// CHECK: } // end sil function 'co_routine_with_exit_edge'
|
|
sil [ossa] @co_routine_with_exit_edge : $@convention(thin) (@in_guaranteed String) -> () {
|
|
bb0(%0 : $*String):
|
|
%1 = function_ref @generic_begin_apply_callee_inout : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @inout T
|
|
(%2, %3) = begin_apply %1<String>(%0) : $@yield_once @convention(thin) <T> (@in_guaranteed T) -> @yields @inout T
|
|
cond_br undef, bb1, bb2
|
|
|
|
bb1:
|
|
end_borrow %3
|
|
unreachable
|
|
|
|
bb2:
|
|
%7 = end_apply %3 as $()
|
|
%8 = tuple ()
|
|
return %8
|
|
}
|
|
|
|
sil @genericReturn : $@convention(thin) <τ_0_0> (@guaranteed AnyObject) -> @out τ_0_0
|
|
|
|
// rdar://99874173: assert; PrunedLiveness; No user in LiveWithin block
|
|
//
|
|
// end_borrow becomes unreachable after specializing genericReturn with Never.
|
|
//
|
|
// The generic cloner needs to be able to compute liveness to fixup a
|
|
// store borrow scope when the only use is in unreachable code.
|
|
// specialized testNoReturnSpecialization
|
|
// CHECK-LABEL: sil shared [ossa] @$s26testNoReturnSpecializations5NeverO_Tt0g5 : $@convention(thin) (@guaranteed AnyObject) -> () {
|
|
// CHECK: [[SB:%.*]] = store_borrow %0 to %{{.*}} : $*AnyObject
|
|
// CHECK: [[LB:%.*]] = load_borrow [[SB]] : $*AnyObject
|
|
// CHECK: apply %{{.*}}<Never>(%{{.*}}, [[LB]]) : $@convention(thin) <τ_0_0> (@guaranteed AnyObject) -> @out τ_0_0
|
|
// CHECK-NEXT: end_borrow [[LB]]
|
|
// CHECK-NEXT: end_borrow [[SB]]
|
|
// CHECK-NEXT: unreachable
|
|
// CHECK-LABEL: } // end sil function '$s26testNoReturnSpecializations5NeverO_Tt0g5'
|
|
sil [ossa] @testNoReturnSpecialization : $@convention(thin) <T> (@in_guaranteed AnyObject, @thick T.Type) -> () {
|
|
bb0(%0 : $*AnyObject, %1 : $@thick T.Type):
|
|
%2 = load_borrow %0 : $*AnyObject
|
|
%f = function_ref @genericReturn : $@convention(thin) <τ_0_0> (@guaranteed AnyObject) -> @out τ_0_0
|
|
%out = alloc_stack $T
|
|
%dummy = apply %f<T>(%out, %2) : $@convention(thin) <τ_0_0> (@guaranteed AnyObject) -> @out τ_0_0
|
|
destroy_addr %out : $*T
|
|
dealloc_stack %out : $*T
|
|
end_borrow %2 : $AnyObject
|
|
%99 = tuple ()
|
|
return %99 : $()
|
|
}
|
|
|
|
sil [ossa] @testCallNoReturnSpecialization : $@convention(thin) (@in_guaranteed AnyObject) -> () {
|
|
bb0(%0 : $*AnyObject):
|
|
%f = function_ref @testNoReturnSpecialization : $@convention(thin) <T> (@in_guaranteed AnyObject, @thick T.Type) -> ()
|
|
%m = metatype $@thick Never.Type
|
|
%r = apply %f<Never>(%0, %m) : $@convention(thin) <T> (@in_guaranteed AnyObject, @thick T.Type) -> ()
|
|
%t = tuple ()
|
|
return %t : $()
|
|
}
|
|
|
|
sil [ossa] @metatypeUsed : $@convention(thin) <T> (@thick GenericKlass<T>.Type) -> () {
|
|
bb0(%0 : $@thick GenericKlass<T>.Type):
|
|
%1 = alloc_ref_dynamic %0 : $@thick GenericKlass<T>.Type, $GenericKlass<T>
|
|
destroy_value %1 : $GenericKlass<T>
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
sil [ossa] @metatypeUnused : $@convention(thin) <T> (@thick GenericKlass<T>.Type) -> () {
|
|
bb0(%0 : $@thick GenericKlass<T>.Type):
|
|
debug_value %0 : $@thick GenericKlass<T>.Type, let, name "mt", argno 0
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @callUsedMetatypeWithConcreteMetatype :
|
|
// CHECK: = function_ref @$s12metatypeUsedSi_Ttg5 : $@convention(thin) () -> ()
|
|
// CHECK-LABEL: } // end sil function 'callUsedMetatypeWithConcreteMetatype'
|
|
sil [ossa] @callUsedMetatypeWithConcreteMetatype : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = metatype $@thick GenericKlass<Int>.Type
|
|
%1 = function_ref @metatypeUsed : $@convention(thin) <T> (@thick GenericKlass<T>.Type) -> ()
|
|
%2 = apply %1<Int>(%0) : $@convention(thin) <T> (@thick GenericKlass<T>.Type) -> ()
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @callUsedMetatypeWithUnknownMetatype :
|
|
// CHECK: = function_ref @$s12metatypeUsedSi_Tg5 : $@convention(thin) (@thick GenericKlass<Int>.Type) -> ()
|
|
// CHECK-LABEL: } // end sil function 'callUsedMetatypeWithUnknownMetatype'
|
|
sil [ossa] @callUsedMetatypeWithUnknownMetatype : $@convention(thin) (@thick GenericKlass<Int>.Type) -> () {
|
|
bb0(%0 : $@thick GenericKlass<Int>.Type):
|
|
%1 = function_ref @metatypeUsed : $@convention(thin) <T> (@thick GenericKlass<T>.Type) -> ()
|
|
%2 = apply %1<Int>(%0) : $@convention(thin) <T> (@thick GenericKlass<T>.Type) -> ()
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @callUnusedMetatypeWithUnknownMetatype :
|
|
// CHECK: = function_ref @$s14metatypeUnusedSi_Ttg5 : $@convention(thin) () -> ()
|
|
// CHECK-LABEL: } // end sil function 'callUnusedMetatypeWithUnknownMetatype'
|
|
sil [ossa] @callUnusedMetatypeWithUnknownMetatype : $@convention(thin) (@thick GenericKlass<Int>.Type) -> () {
|
|
bb0(%0 : $@thick GenericKlass<Int>.Type):
|
|
%1 = function_ref @metatypeUnused : $@convention(thin) <T> (@thick GenericKlass<T>.Type) -> ()
|
|
%2 = apply %1<Int>(%0) : $@convention(thin) <T> (@thick GenericKlass<T>.Type) -> ()
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
sil [ossa] @closure_with_metatype : $@convention(thin) <T> (@in_guaranteed T, @thick GenericKlass<T>.Type) -> () {
|
|
bb0(%0 : $*T, %1 : $@thick GenericKlass<T>.Type):
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @returnClosureWithAppliedMetatype :
|
|
// CHECK: = function_ref @$s21closure_with_metatypeSi_Tt0G5 : $@convention(thin) (@in_guaranteed Int) -> ()
|
|
// CHECK-LABEL: } // end sil function 'returnClosureWithAppliedMetatype'
|
|
sil [ossa] @returnClosureWithAppliedMetatype : $@convention(thin) () -> @owned @callee_owned (@in_guaranteed Int) -> () {
|
|
bb0:
|
|
%0 = metatype $@thick GenericKlass<Int>.Type
|
|
%1 = function_ref @closure_with_metatype : $@convention(thin) <T> (@in_guaranteed T, @thick GenericKlass<T>.Type) -> ()
|
|
%2 = partial_apply %1<Int>(%0) : $@convention(thin) <T> (@in_guaranteed T, @thick GenericKlass<T>.Type) -> ()
|
|
return %2 : $@callee_owned (@in_guaranteed Int) -> ()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @returnClosureWithNotAppliedMetatype :
|
|
// CHECK: = function_ref @$s21closure_with_metatypeSi_TG5 : $@convention(thin) (@in_guaranteed Int, @thick GenericKlass<Int>.Type) -> ()
|
|
// CHECK-LABEL: } // end sil function 'returnClosureWithNotAppliedMetatype'
|
|
sil [ossa] @returnClosureWithNotAppliedMetatype : $@convention(thin) () -> @owned @callee_owned (@in_guaranteed Int, @thick GenericKlass<Int>.Type) -> () {
|
|
bb0:
|
|
%1 = function_ref @closure_with_metatype : $@convention(thin) <T> (@in_guaranteed T, @thick GenericKlass<T>.Type) -> ()
|
|
%2 = partial_apply %1<Int>() : $@convention(thin) <T> (@in_guaranteed T, @thick GenericKlass<T>.Type) -> ()
|
|
return %2 : $@callee_owned (@in_guaranteed Int, @thick GenericKlass<Int>.Type) -> ()
|
|
}
|
|
|
|
sil [ossa] @method_with_dynamic_self : $@convention(method) <T> (@thick GenericKlass<T>.Type) -> () {
|
|
bb0(%0 : $@thick GenericKlass<T>.Type):
|
|
%1 = metatype $@thick @dynamic_self GenericKlass<T>.Type
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @callMethodWithDynamicSelf :
|
|
// CHECK: = function_ref @$s24method_with_dynamic_selfSi_Tg5 : $@convention(method) (@thick GenericKlass<Int>.Type) -> ()
|
|
// CHECK-LABEL: } // end sil function 'callMethodWithDynamicSelf'
|
|
sil [ossa] @callMethodWithDynamicSelf : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = metatype $@thick GenericKlass<Int>.Type
|
|
%1 = function_ref @method_with_dynamic_self : $@convention(method) <T> (@thick GenericKlass<T>.Type) -> ()
|
|
%2 = apply %1<Int>(%0) : $@convention(method) <T> (@thick GenericKlass<T>.Type) -> ()
|
|
return %2 : $()
|
|
}
|
|
|
|
sil @complex_closure : $@convention(thin) <T> (@thick T.Type, @in_guaranteed T, Bool) -> @out T {
|
|
bb0(%0 : $*T, %2 : $@thick T.Type, %3 : $*T, %4 : $Bool):
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @returnComplexClosure :
|
|
// CHECK: = function_ref @$s15complex_closureSi_Tt0G5 : $@convention(thin) (@in_guaranteed Int, Bool) -> @out Int
|
|
// CHECK-LABEL: } // end sil function 'returnComplexClosure'
|
|
sil [ossa] @returnComplexClosure : $@convention(thin) (@in Int, Bool) -> @owned @callee_owned () -> @out Int {
|
|
bb0(%0: $*Int, %1 : $Bool):
|
|
%2 = metatype $@thick Int.Type
|
|
%3 = function_ref @complex_closure : $@convention(thin) <T> (@thick T.Type, @in_guaranteed T, Bool) -> @out T
|
|
%4 = partial_apply %3<Int>(%2, %0, %1) : $@convention(thin) <T> (@thick T.Type, @in_guaranteed T, Bool) -> @out T
|
|
return %4 : $@callee_owned () -> @out Int
|
|
}
|
|
|
|
sil [ossa] @closure_with_thin_metatype : $@convention(thin) <T> (@in_guaranteed T, @thin GenericKlass<T>.Type) -> @out T {
|
|
bb0(%0 : $*T, %1 : $*T, %2 : $@thin GenericKlass<T>.Type):
|
|
copy_addr %1 to [init] %0: $*T
|
|
%3 = tuple ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @returnClosureWithNotAppliedThinMetatype :
|
|
// CHECK: = function_ref @$s26closure_with_thin_metatypeSi_TG5 : $@convention(thin) (@in_guaranteed Int, @thin GenericKlass<Int>.Type) -> @out Int
|
|
// CHECK-LABEL: } // end sil function 'returnClosureWithNotAppliedThinMetatype'
|
|
sil [ossa] @returnClosureWithNotAppliedThinMetatype : $@convention(thin) () -> @owned @callee_owned (@in_guaranteed Int, @thin GenericKlass<Int>.Type) -> @out Int {
|
|
bb0:
|
|
%1 = function_ref @closure_with_thin_metatype : $@convention(thin) <T> (@in_guaranteed T, @thin GenericKlass<T>.Type) -> @out T
|
|
%2 = partial_apply %1<Int>() : $@convention(thin) <T> (@in_guaranteed T, @thin GenericKlass<T>.Type) -> @out T
|
|
return %2 : $@callee_owned (@in_guaranteed Int, @thin GenericKlass<Int>.Type) -> @out Int
|
|
}
|
|
|
|
sil [ossa] @method_with_dynamic_self_arg : $@convention(method) <T> (@thick @dynamic_self GenericKlass<T>.Type) -> () {
|
|
bb0(%0 : $@thick @dynamic_self GenericKlass<T>.Type):
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @callMethodWithDynamicSelfArg :
|
|
// CHECK: = function_ref @$s28method_with_dynamic_self_argSi_Tg5 : $@convention(method) (@thick @dynamic_self GenericKlass<Int>.Type) -> ()
|
|
// CHECK-LABEL: } // end sil function 'callMethodWithDynamicSelfArg'
|
|
sil [ossa] @callMethodWithDynamicSelfArg : $@convention(method) (@guaranteed GenericKlass<Int>) -> () {
|
|
bb0(%0 : @guaranteed $GenericKlass<Int>):
|
|
%1 = metatype $@thick @dynamic_self GenericKlass<Int>.Type
|
|
%2 = function_ref @method_with_dynamic_self_arg : $@convention(method) <T> (@thick @dynamic_self GenericKlass<T>.Type) -> ()
|
|
%3 = apply %2<Int>(%1) : $@convention(method) <T> (@thick @dynamic_self GenericKlass<T>.Type) -> ()
|
|
return %3 : $()
|
|
}
|
|
|
|
// Specialize tuple_addr_constructor
|
|
|
|
// In this case we specialized using all non-tuple types
|
|
// CHECK-LABEL: sil shared [ossa] @$s29tuple_addr_constructor_calleeBo_4main4BaseCBoADTg5 : $@convention(thin) (@owned Builtin.NativeObject, @owned Base, @owned Builtin.NativeObject, @owned Base) -> () {
|
|
// CHECK: tuple_addr_constructor [init] {{%.*}} : $*(Builtin.NativeObject, Base, Builtin.NativeObject, Base) with ({{%.*}} : $*Builtin.NativeObject, {{%.*}} : $*Base, {{%.*}} : $Builtin.NativeObject, {{%.*}} : $Base)
|
|
// CHECK: } // end sil function '$s29tuple_addr_constructor_calleeBo_4main4BaseCBoADTg5'
|
|
|
|
// In this case, we specialized where a single parameter was an empty
|
|
// tuple... make sure that we eliminated it as a parameter to tuple_addr_constructor
|
|
// CHECK-LABEL: sil shared [ossa] @$s29tuple_addr_constructor_calleeBo_4main4BaseCytADTg5 : $@convention(thin) (@owned Builtin.NativeObject, @owned Base, @owned (), @owned Base) -> () {
|
|
// CHECK: tuple_addr_constructor [init] {{%.*}} : $*(Builtin.NativeObject, Base, (), Base) with ({{%.*}} : $*Builtin.NativeObject, {{%.*}} : $*Base, {{%.*}} : $Base)
|
|
// CHECK: } // end sil function '$s29tuple_addr_constructor_calleeBo_4main4BaseCytADTg5'
|
|
|
|
// Make sure we handle this with multiple level tuples
|
|
// CHECK-LABEL: sil shared [ossa] @$s29tuple_addr_constructor_calleeBo_4main4BaseCyt_yt_ytttADTg5 : $@convention(thin) (@owned Builtin.NativeObject, @owned Base, @owned ((), ((), ())), @owned Base) -> () {
|
|
// CHECK: tuple_addr_constructor [init] {{%.*}} : $*(Builtin.NativeObject, Base, ((), ((), ())), Base) with ({{%.*}} : $*Builtin.NativeObject, {{%.*}} : $*Base, {{%.*}} : $Base)
|
|
// CHECK: } // end sil function '$s29tuple_addr_constructor_calleeBo_4main4BaseCyt_yt_ytttADTg5'
|
|
|
|
// Make sure we keep in the parameter if we have one leaf node.
|
|
// CHECK-LABEL: sil shared [ossa] @$s29tuple_addr_constructor_calleeBo_4main4BaseCyt_Bo_ytttADTg5 : $@convention(thin) (@owned Builtin.NativeObject, @owned Base, @owned ((), (Builtin.NativeObject, ())), @owned Base) -> () {
|
|
// CHECK: tuple_addr_constructor [init] {{%.*}} : $*(Builtin.NativeObject, Base, ((), (Builtin.NativeObject, ())), Base) with ({{%.*}} : $*Builtin.NativeObject, {{%.*}} : $*Base, {{%.*}} : $((), (Builtin.NativeObject, ())), {{%.*}} : $Base)
|
|
// CHECK: } // end sil function '$s29tuple_addr_constructor_calleeBo_4main4BaseCyt_Bo_ytttADTg5'
|
|
|
|
// CHECK-LABEL: sil shared [ossa] @$s29tuple_addr_constructor_calleeyt_ytyt_yt_ytttytTg5 : $@convention(thin) ((), (), @owned ((), ((), ())), @owned ()) -> () {
|
|
// CHECK-NOT: tuple_addr_constructor
|
|
// CHECK: } // end sil function '$s29tuple_addr_constructor_calleeyt_ytyt_yt_ytttytTg5'
|
|
|
|
sil [ossa] @tuple_addr_constructor_callee : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> () {
|
|
bb0(%arg0 : $*T1, %arg1 : $*T2, %arg2 : @owned $T3, %arg3 : @owned $T4):
|
|
%tup = alloc_stack $(T1, T2, T3, T4)
|
|
tuple_addr_constructor [init] %tup : $*(T1, T2, T3, T4) with (%arg0 : $*T1, %arg1 : $*T2, %arg2 : $T3, %arg3 : $T4)
|
|
destroy_addr %tup : $*(T1, T2, T3, T4)
|
|
dealloc_stack %tup : $*(T1, T2, T3, T4)
|
|
%2 = tuple ()
|
|
return %2 : $()
|
|
}
|
|
|
|
sil [ossa] @specializeTupleAddrConstructorSimple : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Base) -> () {
|
|
bb0(%0 : @guaranteed $Builtin.NativeObject, %1 : @guaranteed $Base):
|
|
%2 = function_ref @tuple_addr_constructor_callee : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
%3 = alloc_stack $*Builtin.NativeObject
|
|
%4 = alloc_stack $*Base
|
|
%0a = copy_value %0 : $Builtin.NativeObject
|
|
%0b = copy_value %0 : $Builtin.NativeObject
|
|
store %0b to [init] %3 : $*Builtin.NativeObject
|
|
%1a = copy_value %1 : $Base
|
|
%1b = copy_value %1 : $Base
|
|
store %1b to [init] %4 : $*Base
|
|
apply %2<Builtin.NativeObject, Base, Builtin.NativeObject, Base>(%3, %4, %0a, %1a) : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
dealloc_stack %4 : $*Base
|
|
dealloc_stack %3 : $*Builtin.NativeObject
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @specializeTupleAddrConstructorEliminateTuple : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Base) -> () {
|
|
bb0(%0 : @guaranteed $Builtin.NativeObject, %1 : @guaranteed $Base):
|
|
%2 = function_ref @tuple_addr_constructor_callee : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
%3 = alloc_stack $*Builtin.NativeObject
|
|
%4 = alloc_stack $*Base
|
|
%0a = tuple ()
|
|
%0b = copy_value %0 : $Builtin.NativeObject
|
|
store %0b to [init] %3 : $*Builtin.NativeObject
|
|
%1a = copy_value %1 : $Base
|
|
%1b = copy_value %1 : $Base
|
|
store %1b to [init] %4 : $*Base
|
|
apply %2<Builtin.NativeObject, Base, (), Base>(%3, %4, %0a, %1a) : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
dealloc_stack %4 : $*Base
|
|
dealloc_stack %3 : $*Builtin.NativeObject
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @specializeTupleAddrConstructorEliminateMultiLevelTuple : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Base) -> () {
|
|
bb0(%0 : @guaranteed $Builtin.NativeObject, %1 : @guaranteed $Base):
|
|
%2 = function_ref @tuple_addr_constructor_callee : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
%3 = alloc_stack $*Builtin.NativeObject
|
|
%4 = alloc_stack $*Base
|
|
%0b = copy_value %0 : $Builtin.NativeObject
|
|
store %0b to [init] %3 : $*Builtin.NativeObject
|
|
%1a = copy_value %1 : $Base
|
|
%1b = copy_value %1 : $Base
|
|
store %1b to [init] %4 : $*Base
|
|
%tup = tuple ()
|
|
%tup2 = tuple (%tup : $(), %tup : $())
|
|
%tup3 = tuple (%tup : $(), %tup2 : $((), ()))
|
|
apply %2<Builtin.NativeObject, Base, ((), ((), ())), Base>(%3, %4, %tup3, %1a) : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
dealloc_stack %4 : $*Base
|
|
dealloc_stack %3 : $*Builtin.NativeObject
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @specializeTupleAddrConstructorEliminateNoEliminateIfOneElt : $@convention(thin) (@guaranteed Builtin.NativeObject, @guaranteed Base) -> () {
|
|
bb0(%0 : @guaranteed $Builtin.NativeObject, %1 : @guaranteed $Base):
|
|
%2 = function_ref @tuple_addr_constructor_callee : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
%3 = alloc_stack $*Builtin.NativeObject
|
|
%4 = alloc_stack $*Base
|
|
%0a = copy_value %0 : $Builtin.NativeObject
|
|
%0b = copy_value %0 : $Builtin.NativeObject
|
|
store %0b to [init] %3 : $*Builtin.NativeObject
|
|
%1a = copy_value %1 : $Base
|
|
%1b = copy_value %1 : $Base
|
|
store %1b to [init] %4 : $*Base
|
|
%tup = tuple ()
|
|
%tup2 = tuple (%0a : $Builtin.NativeObject, %tup : $())
|
|
%tup3 = tuple (%tup : $(), %tup2 : $(Builtin.NativeObject, ()))
|
|
apply %2<Builtin.NativeObject, Base, ((), (Builtin.NativeObject, ())), Base>(%3, %4, %tup3, %1a) : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
dealloc_stack %4 : $*Base
|
|
dealloc_stack %3 : $*Builtin.NativeObject
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @specializeTupleAddrConstructorNoEmitIfAllTuple : $@convention(thin) () -> () {
|
|
bb0:
|
|
%2 = function_ref @tuple_addr_constructor_callee : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
%3 = alloc_stack $*()
|
|
%4 = alloc_stack $*()
|
|
%tup = tuple ()
|
|
%tup2 = tuple (%tup : $(), %tup : $())
|
|
%tup3 = tuple (%tup : $(), %tup2 : $((), ()))
|
|
apply %2<(), (), ((), ((), ())), ()>(%3, %4, %tup3, %tup) : $@convention(thin) <T1, T2, T3, T4> (@in T1, @in T2, @owned T3, @owned T4) -> ()
|
|
dealloc_stack %4 : $*()
|
|
dealloc_stack %3 : $*()
|
|
%9999 = tuple ()
|
|
return %9999 : $()
|
|
}
|
|
|
|
sil [ossa] @unused_argument : $@convention(thin) <T> (@in_guaranteed T) -> () {
|
|
[global: ]
|
|
bb0(%0 : $*T):
|
|
%1 = tuple ()
|
|
return %1 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @call_generic_func_with_no_arg_read :
|
|
// CHECK-NOT: load
|
|
// CHECK: [[L:%.*]] = load_borrow %1
|
|
// CHECK: = apply {{%[0-9]+}}([[L]]) :
|
|
// CHECK: end_borrow [[L]]
|
|
// CHECK: } // end sil function 'call_generic_func_with_no_arg_read'
|
|
sil [ossa] @call_generic_func_with_no_arg_read : $@convention(thin) (@owned Klass) -> () {
|
|
bb0(%0 : @owned $Klass):
|
|
%1 = alloc_stack $Klass
|
|
store %0 to [init] %1
|
|
%2 = function_ref @unused_argument : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
|
|
%3 = apply %2<Klass>(%1) : $@convention(thin) <τ_0_0> (@in_guaranteed τ_0_0) -> ()
|
|
destroy_addr %1
|
|
dealloc_stack %1 : $*Klass
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
sil [ossa] @callee : $@convention(thin) <Result> (@inout Result, @in_guaranteed Int, Int) -> () {
|
|
bb0(%0 : $*Result, %1 : $*Int, %2 : $Int):
|
|
unreachable
|
|
}
|
|
|
|
sil [reabstraction_thunk] [ossa] @thunk : $@convention(thin) <τ_0_0> (@inout τ_0_0, Int, @guaranteed @noescape @callee_guaranteed (@inout τ_0_0, @in_guaranteed Int) -> ()) -> ()
|
|
|
|
// CHECK-LABEL: sil [ossa] @insert_copy_when_removing_thunk :
|
|
// CHECK: [[P:%.*]] = partial_apply [callee_guaranteed] [on_stack] %2(%0)
|
|
// CHECK: [[C:%.*]] = copy_value [[P]]
|
|
// CHECK: [[V:%.*]] = convert_function [[C]]
|
|
// CHECK: apply [[V]]
|
|
// CHECK: destroy_value [[V]]
|
|
// CHECK: destroy_value [[P]]
|
|
// CHECK: } // end sil function 'insert_copy_when_removing_thunk'
|
|
sil [ossa] @insert_copy_when_removing_thunk : $@convention(method) (Int) -> Int {
|
|
bb0(%0 : $Int):
|
|
%1 = alloc_stack $Int
|
|
%2 = function_ref @callee : $@convention(thin) <τ_0_0> (@inout τ_0_0, @in_guaranteed Int, Int) -> ()
|
|
%3 = partial_apply [callee_guaranteed] [on_stack] %2<Int>(%0) : $@convention(thin) <τ_0_0> (@inout τ_0_0, @in_guaranteed Int, Int) -> ()
|
|
%4 = function_ref @thunk : $@convention(thin) <τ_0_0> (@inout τ_0_0, Int, @guaranteed @noescape @callee_guaranteed (@inout τ_0_0, @in_guaranteed Int) -> ()) -> ()
|
|
%5 = partial_apply [callee_guaranteed] [on_stack] %4<Int>(%3) : $@convention(thin) <τ_0_0> (@inout τ_0_0, Int, @guaranteed @noescape @callee_guaranteed (@inout τ_0_0, @in_guaranteed Int) -> ()) -> ()
|
|
%6 = convert_function %5 to $@noescape @callee_guaranteed @substituted <τ_0_0> (@inout τ_0_0, Int) -> () for <Int>
|
|
store %0 to [trivial] %1
|
|
%8 = apply %6(%1, %0) : $@noescape @callee_guaranteed @substituted <τ_0_0> (@inout τ_0_0, Int) -> () for <Int>
|
|
destroy_value %6
|
|
destroy_value %3
|
|
%11 = load [trivial] %1
|
|
dealloc_stack %1
|
|
return %11
|
|
}
|
|
|
|
|
|
sil hidden [ossa] @$s_custom_not_demangable_name : $@convention(thin) <T> (@thick T.Type) -> () {
|
|
bb0(%0 : $@thick T.Type):
|
|
%8 = tuple ()
|
|
return %8 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil [ossa] @call_custom_name :
|
|
// CHECK: function_ref @$s29$s_custom_not_demangable_nameSi_Ttg5 : $@convention(thin) () -> ()
|
|
// CHECK: } // end sil function 'call_custom_name'
|
|
sil [ossa] @call_custom_name : $@convention(thin) () -> () {
|
|
bb0:
|
|
%2 = function_ref @$s_custom_not_demangable_name : $@convention(thin) <τ_0_0> (@thick τ_0_0.Type) -> ()
|
|
%3 = metatype $@thick Int.Type
|
|
%4 = apply %2<Int>(%3) : $@convention(thin) <τ_0_0> (@thick τ_0_0.Type) -> ()
|
|
%5 = tuple ()
|
|
return %5 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: sil shared [ossa] @$s19alloc_stack_of_packSS_QP_Tg5 :
|
|
// CHECK: %1 = alloc_stack [dynamic_lifetime] $String
|
|
// CHECK: } // end sil function '$s19alloc_stack_of_packSS_QP_Tg5'
|
|
sil [ossa] @alloc_stack_of_pack : $@convention(thin) <each T> (@pack_guaranteed Pack{repeat each T}) -> () {
|
|
bb0(%0 : $*Pack{repeat each T}):
|
|
%1 = alloc_stack $(repeat each T)
|
|
dealloc_stack %1
|
|
%3 = tuple ()
|
|
return %3
|
|
}
|
|
|
|
sil [ossa] @call_alloc_stack_of_pack : $@convention(thin) (@guaranteed String) -> () {
|
|
bb0(%0 : @guaranteed $String):
|
|
%2 = alloc_pack $Pack{String}
|
|
%3 = alloc_stack $String
|
|
%4 = copy_value %0
|
|
store %4 to [init] %3
|
|
%6 = scalar_pack_index 0 of $Pack{String}
|
|
pack_element_set %3 into %6 of %2
|
|
%8 = function_ref @alloc_stack_of_pack : $@convention(thin) <each τ_0_0> (@pack_guaranteed Pack{repeat each τ_0_0}) -> ()
|
|
%9 = apply %8<Pack{String}>(%2) : $@convention(thin) <each τ_0_0> (@pack_guaranteed Pack{repeat each τ_0_0}) -> ()
|
|
destroy_addr %3
|
|
dealloc_stack %3
|
|
dealloc_pack %2
|
|
%13 = tuple ()
|
|
return %13
|
|
}
|