1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
|
// RUN: %target-swift-frontend -stack-promotion-limit 48 -Onone -emit-ir %s | %FileCheck %s -DINT=i%target-ptrsize
// REQUIRES: swift_in_compiler
import Builtin
import Swift
class TestClass {
@_hasStorage var a : Int64
init()
}
struct TestStruct {
@_hasStorage var a : Int64
@_hasStorage var b : Int64
@_hasStorage var c : Int64
}
class BigClass {
@_hasStorage var a : Int64
@_hasStorage var b : Int64
@_hasStorage var c : Int64
@_hasStorage var d : Int64
@_hasStorage var e : Int64
@_hasStorage var f : Int64
@_hasStorage var g : Int64
init()
}
sil_vtable TestClass {}
sil_vtable BigClass {}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @simple_promote
// CHECK: %reference.raw = alloca %[[C:[a-zA-Z0-9_]+]], align 8
// CHECK-NEXT: [[MR:%[0-9]+]] = call swiftcc %swift.metadata_response @"$s17class_stack_alloc9TestClassCMa"([[INT]] 0)
// CHECK-NEXT: [[M:%.*]] = extractvalue %swift.metadata_response [[MR]], 0
// CHECK-NEXT: %reference.new = call ptr @swift_initStackObject(ptr [[M]], ptr %reference.raw)
// CHECK-NEXT: call {{.*}} @swift_release(ptr %reference.new)
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr %reference.new)
// CHECK-NEXT: ret void
sil @simple_promote : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $TestClass
strong_release %o1 : $TestClass
dealloc_stack_ref %o1 : $TestClass
%r = tuple()
return %r : $()
}
// A stack promotion limit of 48 bytes allows that one of the two alloc_refs
// can be allocated on the stack.
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @exceed_limit
// CHECK: alloca {{.*}}TestClass
// CHECK: alloca {{.*}}TestStruct
// CHECK-NOT: alloca
// CHECK: call ptr @swift_initStackObject
// CHECK: call noalias ptr @swift_allocObject
// CHECK: ret void
sil @exceed_limit : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $TestClass
%o2 = alloc_ref [stack] $TestClass
%s1 = alloc_stack $TestStruct
%f = function_ref @unknown_func : $@convention(thin) (@inout TestStruct) -> ()
%a = apply %f(%s1) : $@convention(thin) (@inout TestStruct) -> ()
dealloc_stack %s1 : $*TestStruct
strong_release %o1 : $TestClass
strong_release %o2 : $TestClass
dealloc_stack_ref %o2 : $TestClass
dealloc_stack_ref %o1 : $TestClass
%r = tuple()
return %r : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @promoted_with_devirtualized_release
// CHECK: %reference.raw = alloca %[[C:[a-zA-Z0-9_]+]], align 8
// CHECK-NEXT: [[MR:%[0-9]+]] = call swiftcc %swift.metadata_response @"$s17class_stack_alloc9TestClassCMa"([[INT]] 0)
// CHECK-NEXT: [[M:%.*]] = extractvalue %swift.metadata_response [[MR]], 0
// CHECK-NEXT: %reference.new = call ptr @swift_initStackObject(ptr [[M]], ptr %reference.raw)
// CHECK-NEXT: call {{.*}} @swift_setDeallocating(ptr %reference.new)
// CHECK-NEXT: call swiftcc void @not_inlined_destructor(ptr %reference.new)
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr %reference.new)
// CHECK-NEXT: ret void
sil @promoted_with_devirtualized_release : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $TestClass
%d = begin_dealloc_ref %o1 : $TestClass of %o1 : $TestClass
%f = function_ref @not_inlined_destructor : $@convention(thin) (TestClass) -> ()
%a = apply %f(%d) : $@convention(thin) (TestClass) -> ()
dealloc_stack_ref %o1 : $TestClass
%r = tuple()
return %r : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @bare_alloc_ref
// CHECK: %reference.raw = alloca %[[C:[a-zA-Z0-9_]+]], align 8
// CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 -1, ptr %reference.raw)
// CHECK-NEXT: ret void
sil @bare_alloc_ref : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [bare] [stack] $TestClass
%d = begin_dealloc_ref %o1 : $TestClass of %o1 : $TestClass
dealloc_stack_ref %o1 : $TestClass
%r = tuple()
return %r : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @promoted_with_inlined_devirtualized_release
// CHECK: %reference.raw = alloca %[[C:[a-zA-Z0-9_]+]], align 8
// CHECK-NEXT: [[MR:%[0-9]+]] = call swiftcc %swift.metadata_response @"$s17class_stack_alloc9TestClassCMa"([[INT]] 0)
// CHECK-NEXT: [[M:%.*]] = extractvalue %swift.metadata_response [[MR]], 0
// CHECK-NEXT: %reference.new = call ptr @swift_initStackObject(ptr [[M]], ptr %reference.raw)
// CHECK-NOT: call
// CHECK: call void @llvm.lifetime.end.p0(i64 -1, ptr %reference.new)
// CHECK-NEXT: ret void
sil @promoted_with_inlined_devirtualized_release : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $TestClass
%d = begin_dealloc_ref %o1 : $TestClass of %o1 : $TestClass
dealloc_ref %d : $TestClass
dealloc_stack_ref %o1 : $TestClass
%r = tuple()
return %r : $()
}
// CHECK-LABEL: define{{( dllexport)?}}{{( protected)?}} swiftcc void @not_promoted_with_inlined_devirtualized_release
// CHECK: [[O:%[0-9]+]] = call {{.*}} @swift_allocObject
// CHECK-NEXT: call {{.*}} @swift_setDeallocating(ptr [[O]])
// CHECK-NEXT: call void @swift_deallocClassInstance(ptr [[O]], {{.*}})
// CHECK-NEXT: ret void
sil @not_promoted_with_inlined_devirtualized_release : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $BigClass
%d = begin_dealloc_ref %o1 : $BigClass of %o1 : $BigClass
dealloc_ref %d : $BigClass
dealloc_stack_ref %o1 : $BigClass
%r = tuple()
return %r : $()
}
sil @not_inlined_destructor : $@convention(thin) (TestClass) -> ()
sil @unknown_func : $@convention(thin) (@inout TestStruct) -> ()
|