blob: 45a5990f2fc19c2c0b7d61720011323437b78694 [file] [log] [blame]
// RUN: %target-swift-frontend -stack-promotion-limit 48 -Onone -emit-ir %s | %FileCheck %s -DINT=i%target-ptrsize
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: [[O:%[0-9]+]] = bitcast %[[C]]* %reference.raw to %swift.refcounted*
// CHECK-NEXT: %reference.new = call %swift.refcounted* @swift_initStackObject(%swift.type* [[M]], %swift.refcounted* [[O]])
// CHECK-NEXT: [[R:%[0-9]+]] = bitcast %swift.refcounted* %reference.new to %[[C]]*
// CHECK-NEXT: call {{.*}} @swift_release {{.*}} [[R]])
// CHECK-NEXT: [[O2:%[0-9]+]] = bitcast %[[C]]* [[R]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[O2]])
// CHECK-NEXT: ret void
sil @simple_promote : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $TestClass
strong_release %o1 : $TestClass
dealloc_ref [stack] %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 %swift.refcounted* @swift_initStackObject
// CHECK: call noalias %swift.refcounted* @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_ref [stack] %o2 : $TestClass
dealloc_ref [stack] %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: [[O:%[0-9]+]] = bitcast %[[C]]* %reference.raw to %swift.refcounted*
// CHECK-NEXT: %reference.new = call %swift.refcounted* @swift_initStackObject(%swift.type* [[M]], %swift.refcounted* [[O]])
// CHECK-NEXT: [[R:%[0-9]+]] = bitcast %swift.refcounted* %reference.new to %[[C]]*
// CHECK-NEXT: call {{.*}} @swift_setDeallocating {{.*}}(%[[C]]* [[R]])
// CHECK-NEXT: call swiftcc void @not_inlined_destructor(%[[C]]* [[R]])
// CHECK-NEXT: [[O2:%[0-9]+]] = bitcast %[[C]]* [[R]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[O2]])
// CHECK-NEXT: ret void
sil @promoted_with_devirtualized_release : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $TestClass
set_deallocating %o1 : $TestClass
%f = function_ref @not_inlined_destructor : $@convention(thin) (TestClass) -> ()
%a = apply %f(%o1) : $@convention(thin) (TestClass) -> ()
dealloc_ref [stack] %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: [[O:%[0-9]+]] = bitcast %[[C]]* %reference.raw to %swift.refcounted*
// CHECK-NEXT: %reference.new = call %swift.refcounted* @swift_initStackObject(%swift.type* [[M]], %swift.refcounted* [[O]])
// CHECK-NEXT: [[R:%[0-9]+]] = bitcast %swift.refcounted* %reference.new to %[[C]]*
// CHECK-NOT: call
// CHECK: [[O2:%[0-9]+]] = bitcast %[[C]]* [[R]] to i8*
// CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 -1, i8* [[O2]])
// CHECK-NEXT: ret void
sil @promoted_with_inlined_devirtualized_release : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $TestClass
set_deallocating %o1 : $TestClass
dealloc_ref %o1 : $TestClass
dealloc_ref [stack] %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: [[BC:%[0-9]+]] = bitcast %swift.refcounted* [[O]] to
// CHECK-NEXT: call {{.*}} @swift_setDeallocating {{.*}}({{.*}} [[BC]])
// CHECK-NEXT: [[BC2:%[0-9]+]] = bitcast {{.*}} [[BC]] to %swift.refcounted*
// CHECK-NEXT: call void @swift_deallocClassInstance(%swift.refcounted* [[BC2]], {{.*}})
// CHECK-NEXT: ret void
sil @not_promoted_with_inlined_devirtualized_release : $@convention(thin) () -> () {
bb0:
%o1 = alloc_ref [stack] $BigClass
set_deallocating %o1 : $BigClass
dealloc_ref %o1 : $BigClass
dealloc_ref [stack] %o1 : $BigClass
%r = tuple()
return %r : $()
}
sil @not_inlined_destructor : $@convention(thin) (TestClass) -> ()
sil @unknown_func : $@convention(thin) (@inout TestStruct) -> ()