mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Those functions are effectively outlined functions with an alwaysinline attribute. By removing their debug info and relying on the inliner to propagate the call site location to the inlined instructions, we restore the "original" locations as if the function had never been outlined. This is technically relying on an implementation detail of the inliner, but it seems to be the simplest way of addressing this issue.
136 lines
5.6 KiB
Plaintext
136 lines
5.6 KiB
Plaintext
// RUN: %target-swift-frontend -g -enable-objc-interop -primary-file %s -emit-irgen -sil-verify-all | %IRGenFileCheck %s
|
|
// RUN: %target-swift-frontend -enable-objc-interop -primary-file %s -emit-ir -sil-verify-all
|
|
|
|
// REQUIRES: concurrency, objc_codegen
|
|
|
|
import Builtin
|
|
import Swift
|
|
import _Concurrency
|
|
|
|
sil @not_async_test : $@convention(thin) () -> () {
|
|
bb0:
|
|
%0 = tuple ()
|
|
return %0 : $()
|
|
}
|
|
|
|
// CHECK-LABEL: define{{.*}} @async_continuation(
|
|
// CHECK: [[ctxt_addr:%.*]] = alloca ptr
|
|
// CHECK: [[cont_context:%.*]] = alloca %swift.continuation_context
|
|
// CHECK: [[result_storage:%.*]] = alloca i32
|
|
// CHECK: call token @llvm.coro.id.async
|
|
// CHECK: call ptr @llvm.coro.begin(
|
|
|
|
// Initialize the async continuation context:
|
|
|
|
// Initialize Parent.
|
|
// CHECK: [[base_context:%.*]] = getelementptr inbounds %swift.continuation_context, ptr [[cont_context]], i32 0, i32 0
|
|
// CHECK: [[context_addr:%.*]] = getelementptr inbounds %swift.context, ptr [[base_context]], i32 0, i32 0
|
|
// CHECK: [[ctxt:%.*]] = load ptr, ptr [[ctxt_addr]]
|
|
// CHECK-arm64e: [[ctxt_addr_int:%[0-9]+]] = ptrtoint ptr [[context_addr]] to i64
|
|
// CHECK-arm64e: [[ptrauth_blend:%[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 [[ctxt_addr_int]], i64 48546)
|
|
// CHECK-arm64e: [[ctxt_int:%[0-9]+]] = ptrtoint ptr [[ctxt]] to i64
|
|
// CHECK-arm64e: [[signed_int:%[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 [[ctxt_int]], i32 2, i64 [[ptrauth_blend]])
|
|
// CHECK-arm64e: [[signed_ctxt:%[0-9]+]] = inttoptr i64 [[signed_int]] to ptr
|
|
// CHECK-arm64e: store ptr [[signed_ctxt]], ptr [[context_addr]]
|
|
// CHECK-x86_64: store ptr [[ctxt]], ptr [[context_addr]]
|
|
|
|
// Initialize NormalResult.
|
|
// CHECK: [[result_addr:%.*]] = getelementptr inbounds %swift.continuation_context, ptr [[cont_context]], i32 0, i32 4
|
|
// CHECK: store ptr [[result_storage]], ptr [[result_addr]]
|
|
|
|
// Initialize ResumeParent.
|
|
// CHECK: [[resume_intrinsic:%.*]] = call ptr @llvm.coro.async.resume()
|
|
// CHECK: [[continuation_fn_addr:%.*]] = getelementptr inbounds %swift.context, ptr [[base_context]], i32 0, i32 1
|
|
// CHECK-arm64e: [[continuation_fn_addr_int:%[0-9]+]] = ptrtoint ptr [[continuation_fn_addr]] to i64
|
|
// CHECK-arm64e: [[ptrauth_blend:%[0-9]+]] = call i64 @llvm.ptrauth.blend(i64 [[continuation_fn_addr_int]], i64 55047)
|
|
// CHECK-arm64e: [[continuation_fn_int:%[0-9]+]] = ptrtoint ptr [[resume_intrinsic]] to i64
|
|
// CHECK-arm64e: [[signed_int:%[0-9]+]] = call i64 @llvm.ptrauth.sign(i64 [[continuation_fn_int]], i32 0, i64 [[ptrauth_blend]])
|
|
// CHECK-arm64e: [[signed_continuation_fn:%[0-9]+]] = inttoptr i64 [[signed_int]] to ptr
|
|
// CHECK-arm64e: store ptr [[signed_continuation_fn]], ptr [[continuation_fn_addr]]
|
|
// CHECK-x86_64: store ptr [[resume_intrinsic]], ptr [[continuation_fn_addr]]
|
|
|
|
// Call the runtime to retrieve and initialize the continuation.
|
|
// CHECK: call swiftcc ptr @swift_continuation_init(ptr [[cont_context]], [[INT]] 0)
|
|
|
|
// Do some stuff.
|
|
// CHECK: call swiftcc void @not_async_test()
|
|
|
|
// Arrive at the await_async_continuation point.
|
|
// CHECK: [[suspend:%.*]] = call { ptr } (i32, ptr, ptr, ...) @llvm.coro.suspend.async.sl_p0s(i32 0, ptr [[resume_intrinsic]], ptr @__swift_async_resume_project_context, ptr @__swift_continuation_await_point, ptr [[cont_context]])
|
|
// CHECK: [[result_addr_addr:%.*]] = getelementptr inbounds %swift.continuation_context, ptr [[cont_context]], i32 0, i32 4
|
|
// CHECK: [[result_addr:%.*]] = load ptr, ptr [[result_addr_addr]]
|
|
// CHECK: [[result_value:%.*]] = load i32, ptr [[result_addr]]
|
|
// CHECK: br label %[[result_bb:[0-9]+]]
|
|
|
|
// CHECK: [[result_bb]]:
|
|
// CHECK: phi i32 [ [[result_value]], %entry ]
|
|
|
|
// CHECK: define {{.*}} void @__swift_continuation_await_point(ptr %0)
|
|
// CHECK: {{musttail call swifttailcc|tail call swiftcc}} void @swift_continuation_await(ptr %0)
|
|
// CHECK-NEXT: ret void
|
|
|
|
// CHECK: define {{.*}} void @async_continuation.0(ptr %0, ptr %1)
|
|
// CHECK-NOT: define
|
|
// CHECK: tail call swift{{(tail)?}}cc void %{{.*}}(ptr swiftasync %1)
|
|
// CHECK-NEXT: ret void
|
|
|
|
sil @async_continuation : $@async () -> () {
|
|
entry:
|
|
%c = get_async_continuation Builtin.Int32
|
|
%f = function_ref @not_async_test : $@convention(thin) () -> ()
|
|
apply %f() : $@convention(thin) () -> ()
|
|
await_async_continuation %c : $Builtin.RawUnsafeContinuation, resume bb1
|
|
|
|
bb1(%r : $Builtin.Int32):
|
|
%t = tuple()
|
|
return %t : $()
|
|
}
|
|
|
|
sil @async_continuation_throws : $@async () -> () {
|
|
entry:
|
|
%c = get_async_continuation [throws] Builtin.Int32
|
|
%f = function_ref @not_async_test : $@convention(thin) () -> ()
|
|
apply %f() : $@convention(thin) () -> ()
|
|
await_async_continuation %c : $Builtin.RawUnsafeContinuation, resume bb1, error bb2
|
|
bb1(%r : $Builtin.Int32):
|
|
br bb3
|
|
bb2(%e : $Error):
|
|
br bb3
|
|
|
|
bb3:
|
|
%t = tuple()
|
|
return %t : $()
|
|
}
|
|
|
|
sil @async_continuation_addr : $@async () -> () {
|
|
entry:
|
|
%a = alloc_stack $Builtin.Int32
|
|
%c = get_async_continuation_addr Builtin.Int32, %a : $*Builtin.Int32
|
|
%f = function_ref @not_async_test : $@convention(thin) () -> ()
|
|
apply %f() : $@convention(thin) () -> ()
|
|
await_async_continuation %c : $Builtin.RawUnsafeContinuation, resume bb1
|
|
bb1:
|
|
dealloc_stack %a : $*Builtin.Int32
|
|
%t = tuple()
|
|
return %t : $()
|
|
}
|
|
|
|
sil @async_continuation_throws_addr : $@async () -> () {
|
|
entry:
|
|
%a = alloc_stack $Builtin.Int32
|
|
%c = get_async_continuation_addr [throws] Builtin.Int32, %a : $*Builtin.Int32
|
|
%f = function_ref @not_async_test : $@convention(thin) () -> ()
|
|
apply %f() : $@convention(thin) () -> ()
|
|
await_async_continuation %c : $Builtin.RawUnsafeContinuation, resume bb1, error bb2
|
|
bb1:
|
|
dealloc_stack %a : $*Builtin.Int32
|
|
br bb3
|
|
bb2(%e : $Error):
|
|
dealloc_stack %a : $*Builtin.Int32
|
|
br bb3
|
|
|
|
bb3:
|
|
%t = tuple()
|
|
return %t : $()
|
|
}
|