mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Codegen is the same, but `begin_dealloc_ref` consumes the operand and produces a new SSA value. This cleanly splits the liferange to the region before and within the destructor of a class.
154 lines
5.4 KiB
Plaintext
154 lines
5.4 KiB
Plaintext
// 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) -> ()
|
|
|