mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Use the generic type lowering algorithm described in "docs/CallingConvention.rst#physical-lowering" to map from IRGen's explosion type to the type expected by the ABI. Change IRGen to use the swift calling convention (swiftcc) for native swift functions. Use the 'swiftself' attribute on self parameters and for closures contexts. Use the 'swifterror' parameter for swift error parameters. Change functions in the runtime that are called as native swift functions to use the swift calling convention. rdar://19978563
160 lines
9.2 KiB
Plaintext
160 lines
9.2 KiB
Plaintext
// RUN: %target-swift-frontend -assume-parsing-unqualified-ownership-sil -gnone -sdk %S/Inputs %s -emit-ir | %FileCheck %s
|
|
|
|
// REQUIRES: CPU=x86_64
|
|
// REQUIRES: objc_interop
|
|
|
|
sil_stage canonical
|
|
|
|
import Builtin
|
|
import Swift
|
|
import gizmo
|
|
|
|
// CHECK: [[BLOCK_ISA:@_NSConcreteStackBlock]] = external global %objc_class
|
|
// CHECK: [[VOID_BLOCK_SIGNATURE:@.*]] = private unnamed_addr constant {{.*}} c"v8@?0\00"
|
|
// CHECK: [[TRIVIAL_BLOCK_DESCRIPTOR:@.*]] = internal constant { {{.*}} } {
|
|
// CHECK: i64 0,
|
|
// CHECK: i64 40,
|
|
// CHECK: i8* {{.*}} [[VOID_BLOCK_SIGNATURE]]
|
|
// CHECK: }
|
|
// CHECK: [[BLOCK_PARAM_BLOCK_SIGNATURE:@.*]] = private unnamed_addr constant {{.*}} c"v16@?0@?<q@?q>8\00"
|
|
// CHECK: [[BLOCK_PARAM_BLOCK_DESCRIPTOR:@.*]] = internal constant { {{.*}} } {
|
|
// CHECK: i64 0,
|
|
// CHECK: i64 40,
|
|
// CHECK: i8* {{.*}} [[BLOCK_PARAM_BLOCK_SIGNATURE]]
|
|
// CHECK: }
|
|
// CHECK: [[NONTRIVIAL_BLOCK_DESCRIPTOR:@.*]] = internal constant { {{.*}} } {
|
|
// CHECK: i64 0,
|
|
// CHECK: i64 40,
|
|
// CHECK: void ({ %objc_block, %swift.refcounted* }*, { %objc_block, %swift.refcounted* }*)* [[NONTRIVIAL_BLOCK_COPY:@[A-Za-z0-9_]+]],
|
|
// CHECK: void ({ %objc_block, %swift.refcounted* }*)* [[NONTRIVIAL_BLOCK_DISPOSE:@[A-Za-z0-9_]+]],
|
|
// CHECK: i8* {{.*}} [[VOID_BLOCK_SIGNATURE]]
|
|
// CHECK: }
|
|
// CHECK: [[NSRECT_BLOCK_SIGNATURE:@.*]] = private unnamed_addr constant {{.*}} c"{NSRect={NSPoint=dd}{NSSize=dd}}8@?0\00"
|
|
// CHECK: [[STRET_BLOCK_DESCRIPTOR:@.*]] = internal constant { {{.*}} } {
|
|
// CHECK: i64 0,
|
|
// CHECK: i64 40,
|
|
// CHECK: i8* {{.*}} [[NSRECT_BLOCK_SIGNATURE]]
|
|
// CHECK: }
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} swiftcc i8* @project_block_storage({ %objc_block, i8* }* nocapture dereferenceable({{.*}})) {{.*}} {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: %1 = getelementptr inbounds { %objc_block, i8* }, { %objc_block, i8* }* %0, i32 0, i32 1
|
|
// CHECK-NEXT: %2 = load i8*, i8** %1, align 8
|
|
// CHECK-NEXT: ret i8* %2
|
|
// CHECK-NEXT: }
|
|
sil @project_block_storage : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> Builtin.RawPointer {
|
|
entry(%0 : $*@block_storage Builtin.RawPointer):
|
|
%c = project_block_storage %0 : $*@block_storage Builtin.RawPointer
|
|
%p = load %c : $*Builtin.RawPointer
|
|
return %p : $Builtin.RawPointer
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} swiftcc fp128 @overaligned_project_block_storage({ %objc_block, fp128 }* nocapture dereferenceable({{.*}})) {{.*}} {
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: %1 = getelementptr inbounds { %objc_block, fp128 }, { %objc_block, fp128 }* %0, i32 0, i32 1
|
|
// CHECK-NEXT: %2 = load fp128, fp128* %1, align 16
|
|
// CHECK-NEXT: ret fp128 %2
|
|
// CHECK-NEXT: }
|
|
sil @overaligned_project_block_storage : $@convention(thin) (@inout_aliasable @block_storage Builtin.FPIEEE128) -> Builtin.FPIEEE128 {
|
|
entry(%0 : $*@block_storage Builtin.FPIEEE128):
|
|
%c = project_block_storage %0 : $*@block_storage Builtin.FPIEEE128
|
|
%p = load %c : $*Builtin.FPIEEE128
|
|
return %p : $Builtin.FPIEEE128
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} swiftcc %objc_block* @init_block_header_trivial({ %objc_block, i8* }* nocapture dereferenceable({{.*}})) {{.*}} {
|
|
// CHECK: %1 = getelementptr inbounds { %objc_block, i8* }, { %objc_block, i8* }* %0, i32 0, i32 0
|
|
// CHECK: store %objc_block {
|
|
// CHECK: %objc_class* [[BLOCK_ISA]]
|
|
// -- 0x4000_0000 -- HAS_SIGNATURE
|
|
// CHECK: i32 1073741824
|
|
// CHECK: i32 0
|
|
// CHECK: i8* bitcast {{.*}} @invoke_trivial
|
|
// CHECK: i8* bitcast {{.*}} [[TRIVIAL_BLOCK_DESCRIPTOR]]
|
|
// CHECK: }, %objc_block* %1
|
|
// CHECK: %2 = bitcast {{.*}} %0 to %objc_block*
|
|
// CHECK: ret %objc_block* %2
|
|
sil @init_block_header_trivial : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> @convention(block) () -> () {
|
|
entry(%0 : $*@block_storage Builtin.RawPointer):
|
|
%i = function_ref @invoke_trivial : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> ()
|
|
%b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> (), type $@convention(block) () -> ()
|
|
return %b : $@convention(block) () -> ()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} void @invoke_trivial(void (...)*) {{.*}} {
|
|
// CHECK: %1 = bitcast void (...)* %0 to { %objc_block, i8* }*
|
|
// CHECK: %2 = getelementptr inbounds { %objc_block, i8* }, { %objc_block, i8* }* %1, i32 0, i32 1
|
|
sil @invoke_trivial : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> () {
|
|
entry(%0 : $*@block_storage Builtin.RawPointer):
|
|
%c = project_block_storage %0 : $*@block_storage Builtin.RawPointer
|
|
return undef : $()
|
|
}
|
|
|
|
sil @init_block_header_trivial_block_param : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> @convention(block) (@convention(block) (Int) -> Int) -> () {
|
|
entry(%0 : $*@block_storage Builtin.RawPointer):
|
|
%i = function_ref @invoke_trivial_block_param : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> ()
|
|
%b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> (), type $@convention(block) (@convention(block) (Int) -> Int) -> ()
|
|
return %b : $@convention(block) (@convention(block) (Int) -> Int) -> ()
|
|
}
|
|
|
|
sil @invoke_trivial_block_param : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer, @convention(block) (Int) -> Int) -> ()
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} i64 @invoke_trivial_with_arg(void (...)*, i64) {{.*}} {
|
|
// CHECK: ret i64 %1
|
|
sil @invoke_trivial_with_arg : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer, Int) -> Int {
|
|
entry(%0 : $*@block_storage Builtin.RawPointer, %1 : $Int):
|
|
return %1 : $Int
|
|
}
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} swiftcc %objc_block* @init_block_header_nontrivial({ %objc_block, %swift.refcounted* }* nocapture dereferenceable({{.*}})) {{.*}} {
|
|
// CHECK: store %objc_block {
|
|
// CHECK: %objc_class* [[BLOCK_ISA]]
|
|
// -- 0x4200_0000 -- HAS_SIGNATURE, HAS_COPY_DISPOSE
|
|
// CHECK: i32 1107296256
|
|
// CHECK: i32 0
|
|
// CHECK: i8* {{.*}} @invoke_nontrivial
|
|
// CHECK: i8* bitcast {{.*}} [[NONTRIVIAL_BLOCK_DESCRIPTOR]]
|
|
// CHECK: }, %objc_block* %1
|
|
sil @init_block_header_nontrivial : $@convention(thin) (@inout_aliasable @block_storage Builtin.NativeObject) -> @convention(block) () -> () {
|
|
entry(%0 : $*@block_storage Builtin.NativeObject):
|
|
%i = function_ref @invoke_nontrivial : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> ()
|
|
%b = init_block_storage_header %0 : $*@block_storage Builtin.NativeObject, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> (), type $@convention(block) () -> ()
|
|
return %b : $@convention(block) () -> ()
|
|
}
|
|
|
|
// CHECK: define internal void [[NONTRIVIAL_BLOCK_COPY]]
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: %2 = getelementptr inbounds { %objc_block, %swift.refcounted* }, { %objc_block, %swift.refcounted* }* %0, i32 0, i32 1
|
|
// CHECK-NEXT: %3 = getelementptr inbounds { %objc_block, %swift.refcounted* }, { %objc_block, %swift.refcounted* }* %1, i32 0, i32 1
|
|
// CHECK-NEXT: %4 = load %swift.refcounted*, %swift.refcounted** %3, align 8
|
|
// CHECK-NEXT: call void @swift_rt_swift_retain(%swift.refcounted* %4) {{#[0-9]+}}
|
|
// CHECK-NEXT: store %swift.refcounted* %4, %swift.refcounted** %2, align 8
|
|
// CHECK-NEXT: ret void
|
|
|
|
// CHECK: define internal void [[NONTRIVIAL_BLOCK_DISPOSE]]
|
|
// CHECK-NEXT: entry:
|
|
// CHECK-NEXT: %1 = getelementptr inbounds { %objc_block, %swift.refcounted* }, { %objc_block, %swift.refcounted* }* %0, i32 0, i32 1
|
|
// CHECK-NEXT: %toDestroy = load %swift.refcounted*, %swift.refcounted** %1, align 8
|
|
// CHECK-NEXT: call void @swift_rt_swift_release(%swift.refcounted* %toDestroy) {{#[0-9]+}}
|
|
// CHECK-NEXT: ret void
|
|
|
|
sil public_external @invoke_nontrivial : $@convention(c) (@inout_aliasable @block_storage Builtin.NativeObject) -> ()
|
|
|
|
// CHECK-LABEL: define{{( protected)?}} swiftcc %objc_block* @init_block_header_stret({ %objc_block, i8* }* nocapture dereferenceable({{.*}})) {{.*}} {
|
|
// CHECK: store %objc_block {
|
|
// CHECK: %objc_class* [[BLOCK_ISA]]
|
|
// -- 0x6000_0000 -- HAS_STRET, HAS_SIGNATURE
|
|
// CHECK: i32 1610612736
|
|
// CHECK: i32 0
|
|
// CHECK: i8* {{.*}} @invoke_stret
|
|
// CHECK: i8* bitcast {{.*}} [[STRET_BLOCK_DESCRIPTOR]]
|
|
// CHECK: }, %objc_block* %1
|
|
sil @init_block_header_stret : $@convention(thin) (@inout_aliasable @block_storage Builtin.RawPointer) -> @convention(block) () -> NSRect {
|
|
entry(%0 : $*@block_storage Builtin.RawPointer):
|
|
%i = function_ref @invoke_stret : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> NSRect
|
|
%b = init_block_storage_header %0 : $*@block_storage Builtin.RawPointer, invoke %i : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> NSRect, type $@convention(block) () -> NSRect
|
|
return %b : $@convention(block) () -> NSRect
|
|
}
|
|
|
|
sil public_external @invoke_stret : $@convention(c) (@inout_aliasable @block_storage Builtin.RawPointer) -> NSRect
|