Files
swift-mirror/test/SILOptimizer/lslocation_expansion.sil
John McCall ab3f77baf2 Make SILInstruction no longer a subclass of ValueBase and
introduce a common superclass, SILNode.

This is in preparation for allowing instructions to have multiple
results.  It is also a somewhat more elegant representation for
instructions that have zero results.  Instructions that are known
to have exactly one result inherit from a class, SingleValueInstruction,
that subclasses both ValueBase and SILInstruction.  Some care must be
taken when working with SILNode pointers and testing for equality;
please see the comment on SILNode for more information.

A number of SIL passes needed to be updated in order to handle this
new distinction between SIL values and SIL instructions.

Note that the SIL parser is now stricter about not trying to assign
a result value from an instruction (like 'return' or 'strong_retain')
that does not produce any.
2017-09-25 02:06:26 -04:00

264 lines
8.9 KiB
Plaintext

// RUN: %target-sil-opt -assume-parsing-unqualified-ownership-sil -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 of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK: #1 store
// CHECK-NEXT: [[RET0:%.+]] = alloc_stack
// CHECK-NEXT: Projection Path [$*S1
// CHECK-NEXT: Field: var a: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*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 of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S2
// CHECK-NEXT: Projection Path [$*S2
// CHECK-NEXT: Field: var a: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK: #1 store
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var c: S2 of: $*S2
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var c: S2 of: $*S2
// CHECK-NEXT: Field: var a: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var a: S2 of: $*S2
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S3
// CHECK-NEXT: Projection Path [$*S3
// CHECK-NEXT: Field: var a: S2 of: $*S2
// CHECK-NEXT: Field: var a: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK: #2 store
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 of: $*S3
// CHECK-NEXT: Field: var c: S2 of: $*S2
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 of: $*S3
// CHECK-NEXT: Field: var c: S2 of: $*S2
// CHECK-NEXT: Field: var a: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 of: $*S3
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 of: $*S3
// CHECK-NEXT: Field: var a: S2 of: $*S2
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var y: S3 of: $*S3
// CHECK-NEXT: Field: var a: S2 of: $*S2
// CHECK-NEXT: Field: var a: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 of: $*S3
// CHECK-NEXT: Field: var c: S2 of: $*S2
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 of: $*S3
// CHECK-NEXT: Field: var c: S2 of: $*S2
// CHECK-NEXT: Field: var a: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 of: $*S3
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 of: $*S3
// CHECK-NEXT: Field: var a: S2 of: $*S2
// CHECK-NEXT: Field: var b: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*Builtin.Int64]
// CHECK-NEXT: alloc_stack $S4
// CHECK-NEXT: Projection Path [$*S4
// CHECK-NEXT: Field: var x: S3 of: $*S3
// CHECK-NEXT: Field: var a: S2 of: $*S2
// CHECK-NEXT: Field: var a: Int of: $*Int
// CHECK-NEXT: Field: var value: Int64 of: $*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 of: $*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
}