Files
swift-mirror/test/IRGen/objc_block_storage.sil
Arnold Schwaighofer 39fa2f0228 Use the swift calling convention for swift functions
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
2017-02-14 12:17:57 -08:00

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