File: get_async_continuation.sil

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (136 lines) | stat: -rw-r--r-- 5,842 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// 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){{.*}}!dbg ![[DBG:[0-9]+]]
// CHECK-NOT: define
// CHECK:  tail call swift{{(tail)?}}cc void %{{.*}}(ptr swiftasync %1)
// CHECK-NEXT:  ret void
// CHECK: ![[DBG]] = distinct !DISubprogram(linkageName: "async_continuation"

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 : $()
}