blob: 28f01f40a135077b5b20f0bd3267fb52ad64626e [file] [log] [blame]
// RUN: %target-sil-opt -enable-expand-all %s -lslocation-dump -ml=only-expansion | %FileCheck %s
sil_stage canonical
import Builtin
///////////////////////
// Type Declarations //
///////////////////////
struct Int {
var value : Builtin.Int64
}
struct Int64 {
var value : Builtin.Int64
}
struct Bool {
var value : Builtin.Int1
}
class B {
var i : Builtin.Int32
init()
}
struct S1 {
var a: Int
init(a: Int, b: Int)
init()
}
struct S2 {
var a: Int
var b: Int
init(a: Int, b: Int)
init()
}
struct S3 {
var a: S2
var b: Int
var c: S2
init(a: S2, b: Int, c: S2)
init()
}
struct S4 {
var x: S3
var y: S3
init(x: S3, y: S3)
init()
}
class SelfLoop {
var a: Int
var b: Int
var c: SelfLoop
deinit
init()
}
struct S5 {
var a: SelfLoop
init(a: SelfLoop)
init()
}
sil @S1_init : $@convention(thin) (@thin S1.Type) -> S1
sil @S2_init : $@convention(thin) (@thin S2.Type) -> S2
sil @S3_init : $@convention(thin) (@thin S3.Type) -> S3
sil @S4_init : $@convention(thin) (@thin S4.Type) -> S4
sil @S5_init : $@convention(thin) (@thin S5.Type) -> S5
// CHECK-LABEL: @stack_store
// CHECK: #0 store
// CHECK-NEXT: alloc_stack
sil @stack_store : $@convention(thin) () -> () {
%1 = alloc_stack $Builtin.Int64
%9 = integer_literal $Builtin.Int64, 0
store %9 to %1 : $*Builtin.Int64
%4 = tuple()
dealloc_stack %1 : $*Builtin.Int64 // id: %13
return %4 : $()
}
// CHECK-LABEL: @store_after_store
// CHECK: #0 store
// CHECK-NEXT: [[RET0:%.+]] = alloc_box
// CHECK: #1 store
// CHECK-NEXT: [[RET0:%.+]] = alloc_box
sil @store_after_store : $@convention(thin) (@owned B) -> () {
bb0(%0 : $B):
%1 = alloc_box $_0_0> { var τ_0_0 } <B>
%1a = project_box %1 : $_0_0> { var τ_0_0 } <B>, 0
store %0 to %1a : $*B
store %0 to %1a : $*B
%4 = tuple()
return %4 : $()
}
// CHECK-LABEL: @store_after_store_struct
// CHECK: #0 store
// CHECK-NEXT: [[RET0:%.+]] = alloc_stack
// CHECK-NEXT: Projection Path [$*S1
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK: #1 store
// CHECK-NEXT: [[RET0:%.+]] = alloc_stack
// CHECK-NEXT: Projection Path [$*S1
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
sil @store_after_store_struct : $@convention(thin) () -> () {
%1 = alloc_stack $S1
%9 = integer_literal $Builtin.Int64, 0 // user: %10
%10 = struct $Int (%9 : $Builtin.Int64) // user: %12
%11 = struct_element_addr %1 : $*S1, #S1.a // user: %12
store %10 to %11 : $*Int // id: %12
store %10 to %11 : $*Int
%4 = tuple()
dealloc_stack %1 : $*S1 // id: %13
return %4 : $()
}
// Make sure all the structs get expanded correctly.
//
// CHECK-LABEL: @many_struct_allocs
// CHECK: #0 store
// CHECK-NEXT: alloc_stack $S2
// CHECK-NEXT: Projection Path [$*S2
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S2
// CHECK-NEXT: Projection Path [$*S2
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK: #1 store
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var c: S2 in: $*S2
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var c: S2 in: $*S2
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var a: S2 in: $*S2
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var a: S2 in: $*S2
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK: #2 store
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 in: $*S3
// CHECK-NEXT: Field: var c: S2 in: $*S2
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 in: $*S3
// CHECK-NEXT: Field: var c: S2 in: $*S2
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 in: $*S3
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 in: $*S3
// CHECK-NEXT: Field: var a: S2 in: $*S2
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 in: $*S3
// CHECK-NEXT: Field: var a: S2 in: $*S2
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 in: $*S3
// CHECK-NEXT: Field: var c: S2 in: $*S2
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 in: $*S3
// CHECK-NEXT: Field: var c: S2 in: $*S2
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 in: $*S3
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 in: $*S3
// CHECK-NEXT: Field: var a: S2 in: $*S2
// CHECK-NEXT: Field: var b: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 in: $*S3
// CHECK-NEXT: Field: var a: S2 in: $*S2
// CHECK-NEXT: Field: var a: Int in: $*Int
// CHECK-NEXT: Field: var value: Int64 in: $*Builtin.Int64]
sil hidden @many_struct_allocs : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $S2, var, name "a" // users: %6, %18
%1 = alloc_stack $S3, var, name "b" // users: %10, %17
%2 = alloc_stack $S4, var, name "c" // users: %14, %16
%3 = function_ref @S2_init : $@convention(thin) (@thin S2.Type) -> S2 // user: %5
%4 = metatype $@thin S2.Type // user: %5
%5 = apply %3(%4) : $@convention(thin) (@thin S2.Type) -> S2 // user: %6
store %5 to %0 : $*S2 // id: %6
// function_ref struct.S3.init (struct.S3.Type)() -> struct.S3
%7 = function_ref @S3_init : $@convention(thin) (@thin S3.Type) -> S3 // user: %9
%8 = metatype $@thin S3.Type // user: %9
%9 = apply %7(%8) : $@convention(thin) (@thin S3.Type) -> S3 // user: %10
store %9 to %1 : $*S3 // id: %10
%11 = function_ref @S4_init : $@convention(thin) (@thin S4.Type) -> S4 // user: %13
%12 = metatype $@thin S4.Type // user: %13
%13 = apply %11(%12) : $@convention(thin) (@thin S4.Type) -> S4 // user: %14
store %13 to %2 : $*S4 // id: %14
%15 = tuple () // user: %19
dealloc_stack %2 : $*S4 // id: %16
dealloc_stack %1 : $*S3 // id: %17
dealloc_stack %0 : $*S2 // id: %18
return %15 : $() // id: %19
}
// CHECK-LABEL: self_loop
// CHECK: #0 store
// CHECK-NEXT: alloc_stack $S5, var, name "b"{{.*}} // users: %7, %4
// CHECK-NEXT: Projection Path [$*S5
// CHECK-NEXT: Field: var a: SelfLoop in: $*SelfLoop]
sil hidden @self_loop : $@convention(thin) () -> () {
bb0:
%0 = alloc_stack $S5, var, name "b" // users: %4, %7
%1 = function_ref @S5_init : $@convention(thin) (@thin S5.Type) -> S5 // user: %3
%2 = metatype $@thin S5.Type // user: %3
%3 = apply %1(%2) : $@convention(thin) (@thin S5.Type) -> S5 // users: %4, %5
store %3 to %0 : $*S5 // id: %4
release_value %3 : $S5 // id: %5
%6 = tuple () // user: %8
dealloc_stack %0 : $*S5 // id: %7
return %6 : $() // id: %8
}