xref: /llvm-project/mlir/test/Dialect/Async/async-runtime-ref-counting.mlir (revision 5e7dea225be10d3ba0d01e87fb36e80c6764bd83)
1a6628e59SEugene Zhulenev// RUN: mlir-opt %s -async-runtime-ref-counting | FileCheck %s
2a6628e59SEugene Zhulenev
3a6628e59SEugene Zhulenev// CHECK-LABEL: @token
4*5e7dea22SRiver Riddlefunc.func private @token() -> !async.token
5a6628e59SEugene Zhulenev
6a6628e59SEugene Zhulenev// CHECK-LABEL: @cond
7*5e7dea22SRiver Riddlefunc.func private @cond() -> i1
8a6628e59SEugene Zhulenev
9a6628e59SEugene Zhulenev// CHECK-LABEL: @take_token
10*5e7dea22SRiver Riddlefunc.func private @take_token(%arg0: !async.token)
11a6628e59SEugene Zhulenev
12a6628e59SEugene Zhulenev// CHECK-LABEL: @token_arg_no_uses
13a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token
14*5e7dea22SRiver Riddlefunc.func @token_arg_no_uses(%arg0: !async.token) {
1592db09cdSEugene Zhulenev  // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
16a6628e59SEugene Zhulenev  return
17a6628e59SEugene Zhulenev}
18a6628e59SEugene Zhulenev
19a6628e59SEugene Zhulenev// CHECK-LABEL: @token_value_no_uses
20*5e7dea22SRiver Riddlefunc.func @token_value_no_uses() {
21a6628e59SEugene Zhulenev  // CHECK: %[[TOKEN:.*]] = async.runtime.create : !async.token
2292db09cdSEugene Zhulenev  // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
23a6628e59SEugene Zhulenev  %0 = async.runtime.create : !async.token
24a6628e59SEugene Zhulenev  return
25a6628e59SEugene Zhulenev}
26a6628e59SEugene Zhulenev
27a6628e59SEugene Zhulenev// CHECK-LABEL: @token_returned_no_uses
28*5e7dea22SRiver Riddlefunc.func @token_returned_no_uses() {
29a6628e59SEugene Zhulenev  // CHECK: %[[TOKEN:.*]] = call @token
3092db09cdSEugene Zhulenev  // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
31a6628e59SEugene Zhulenev  %0 = call @token() : () -> !async.token
32a6628e59SEugene Zhulenev  return
33a6628e59SEugene Zhulenev}
34a6628e59SEugene Zhulenev
35a6628e59SEugene Zhulenev// CHECK-LABEL: @token_arg_to_func
36a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token
37*5e7dea22SRiver Riddlefunc.func @token_arg_to_func(%arg0: !async.token) {
3892db09cdSEugene Zhulenev  // CHECK: async.runtime.add_ref %[[TOKEN]] {count = 1 : i64} : !async.token
39a6628e59SEugene Zhulenev  call @take_token(%arg0): (!async.token) -> ()
4092db09cdSEugene Zhulenev  // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64} : !async.token
41a6628e59SEugene Zhulenev  return
42a6628e59SEugene Zhulenev}
43a6628e59SEugene Zhulenev
44a6628e59SEugene Zhulenev// CHECK-LABEL: @token_value_to_func
45*5e7dea22SRiver Riddlefunc.func @token_value_to_func() {
46a6628e59SEugene Zhulenev  // CHECK: %[[TOKEN:.*]] = async.runtime.create : !async.token
47a6628e59SEugene Zhulenev  %0 = async.runtime.create : !async.token
4892db09cdSEugene Zhulenev  // CHECK: async.runtime.add_ref %[[TOKEN]] {count = 1 : i64} : !async.token
49a6628e59SEugene Zhulenev  call @take_token(%0): (!async.token) -> ()
5092db09cdSEugene Zhulenev  // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
51a6628e59SEugene Zhulenev  return
52a6628e59SEugene Zhulenev}
53a6628e59SEugene Zhulenev
54a6628e59SEugene Zhulenev// CHECK-LABEL: @token_arg_cond_br_await_with_fallthough
55a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token
56*5e7dea22SRiver Riddlefunc.func @token_arg_cond_br_await_with_fallthough(%arg0: !async.token, %arg1: i1) {
57ace01605SRiver Riddle  // CHECK: cf.cond_br
58a6628e59SEugene Zhulenev  // CHECK-SAME: ^[[BB1:.*]], ^[[BB2:.*]]
59ace01605SRiver Riddle  cf.cond_br %arg1, ^bb1, ^bb2
60a6628e59SEugene Zhulenev^bb1:
61a6628e59SEugene Zhulenev  // CHECK: ^[[BB1]]:
62ace01605SRiver Riddle  // CHECK:   cf.br ^[[BB2]]
63ace01605SRiver Riddle  cf.br ^bb2
64a6628e59SEugene Zhulenev^bb2:
65a6628e59SEugene Zhulenev  // CHECK: ^[[BB2]]:
66a6628e59SEugene Zhulenev  // CHECK:   async.runtime.await %[[TOKEN]]
6792db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
68a6628e59SEugene Zhulenev  async.runtime.await %arg0 : !async.token
69a6628e59SEugene Zhulenev  return
70a6628e59SEugene Zhulenev}
71a6628e59SEugene Zhulenev
72a6628e59SEugene Zhulenev// CHECK-LABEL: @token_simple_return
73*5e7dea22SRiver Riddlefunc.func @token_simple_return() -> !async.token {
74a6628e59SEugene Zhulenev  // CHECK: %[[TOKEN:.*]] = async.runtime.create : !async.token
75a6628e59SEugene Zhulenev  %token = async.runtime.create : !async.token
76a6628e59SEugene Zhulenev  // CHECK: return %[[TOKEN]]
77a6628e59SEugene Zhulenev  return %token : !async.token
78a6628e59SEugene Zhulenev}
79a6628e59SEugene Zhulenev
80a6628e59SEugene Zhulenev// CHECK-LABEL: @token_coro_return
81a6628e59SEugene Zhulenev// CHECK-NOT: async.runtime.drop_ref
82a6628e59SEugene Zhulenev// CHECK-NOT: async.runtime.add_ref
83*5e7dea22SRiver Riddlefunc.func @token_coro_return() -> !async.token {
84a6628e59SEugene Zhulenev  %token = async.runtime.create : !async.token
85a6628e59SEugene Zhulenev  %id = async.coro.id
86a6628e59SEugene Zhulenev  %hdl = async.coro.begin %id
87a6628e59SEugene Zhulenev  %saved = async.coro.save %hdl
88a6628e59SEugene Zhulenev  async.runtime.resume %hdl
89a6628e59SEugene Zhulenev  async.coro.suspend %saved, ^suspend, ^resume, ^cleanup
90a6628e59SEugene Zhulenev^resume:
91ace01605SRiver Riddle  cf.br ^cleanup
92a6628e59SEugene Zhulenev^cleanup:
93a6628e59SEugene Zhulenev  async.coro.free %id, %hdl
94ace01605SRiver Riddle  cf.br ^suspend
95a6628e59SEugene Zhulenev^suspend:
96a6628e59SEugene Zhulenev  async.coro.end %hdl
97a6628e59SEugene Zhulenev  return %token : !async.token
98a6628e59SEugene Zhulenev}
99a6628e59SEugene Zhulenev
100a6628e59SEugene Zhulenev// CHECK-LABEL: @token_coro_await_and_resume
101a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token
102*5e7dea22SRiver Riddlefunc.func @token_coro_await_and_resume(%arg0: !async.token) -> !async.token {
103a6628e59SEugene Zhulenev  %token = async.runtime.create : !async.token
104a6628e59SEugene Zhulenev  %id = async.coro.id
105a6628e59SEugene Zhulenev  %hdl = async.coro.begin %id
106a6628e59SEugene Zhulenev  %saved = async.coro.save %hdl
107a6628e59SEugene Zhulenev  // CHECK: async.runtime.await_and_resume %[[TOKEN]]
108a6628e59SEugene Zhulenev  async.runtime.await_and_resume %arg0, %hdl : !async.token
10992db09cdSEugene Zhulenev  // CHECK-NEXT: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
110a6628e59SEugene Zhulenev  async.coro.suspend %saved, ^suspend, ^resume, ^cleanup
111a6628e59SEugene Zhulenev^resume:
112ace01605SRiver Riddle  cf.br ^cleanup
113a6628e59SEugene Zhulenev^cleanup:
114a6628e59SEugene Zhulenev  async.coro.free %id, %hdl
115ace01605SRiver Riddle  cf.br ^suspend
116a6628e59SEugene Zhulenev^suspend:
117a6628e59SEugene Zhulenev  async.coro.end %hdl
118a6628e59SEugene Zhulenev  return %token : !async.token
119a6628e59SEugene Zhulenev}
120a6628e59SEugene Zhulenev
121a6628e59SEugene Zhulenev// CHECK-LABEL: @value_coro_await_and_resume
122a6628e59SEugene Zhulenev// CHECK: %[[VALUE:.*]]: !async.value<f32>
123*5e7dea22SRiver Riddlefunc.func @value_coro_await_and_resume(%arg0: !async.value<f32>) -> !async.token {
124a6628e59SEugene Zhulenev  %token = async.runtime.create : !async.token
125a6628e59SEugene Zhulenev  %id = async.coro.id
126a6628e59SEugene Zhulenev  %hdl = async.coro.begin %id
127a6628e59SEugene Zhulenev  %saved = async.coro.save %hdl
128a6628e59SEugene Zhulenev  // CHECK: async.runtime.await_and_resume %[[VALUE]]
129a6628e59SEugene Zhulenev  async.runtime.await_and_resume %arg0, %hdl : !async.value<f32>
130a6628e59SEugene Zhulenev  // CHECK: async.coro.suspend
131a6628e59SEugene Zhulenev  // CHECK-SAME: ^[[SUSPEND:.*]], ^[[RESUME:.*]], ^[[CLEANUP:.*]]
132a6628e59SEugene Zhulenev  async.coro.suspend %saved, ^suspend, ^resume, ^cleanup
133a6628e59SEugene Zhulenev^resume:
134a6628e59SEugene Zhulenev  // CHECK: ^[[RESUME]]:
135a6628e59SEugene Zhulenev  // CHECK:   %[[LOADED:.*]] = async.runtime.load %[[VALUE]]
13692db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[VALUE]] {count = 1 : i64}
137a6628e59SEugene Zhulenev  %0 = async.runtime.load %arg0 : !async.value<f32>
138a54f4eaeSMogball  // CHECK:  arith.addf %[[LOADED]], %[[LOADED]]
139a54f4eaeSMogball  %1 = arith.addf %0, %0 : f32
140ace01605SRiver Riddle  cf.br ^cleanup
141a6628e59SEugene Zhulenev^cleanup:
142a6628e59SEugene Zhulenev  async.coro.free %id, %hdl
143ace01605SRiver Riddle  cf.br ^suspend
144a6628e59SEugene Zhulenev^suspend:
145a6628e59SEugene Zhulenev  async.coro.end %hdl
146a6628e59SEugene Zhulenev  return %token : !async.token
147a6628e59SEugene Zhulenev}
148a6628e59SEugene Zhulenev
149a6628e59SEugene Zhulenev// CHECK-LABEL: @outlined_async_execute
150a6628e59SEugene Zhulenev// CHECK: %[[TOKEN:.*]]: !async.token
151*5e7dea22SRiver Riddlefunc.func private @outlined_async_execute(%arg0: !async.token) -> !async.token {
152a6628e59SEugene Zhulenev  %0 = async.runtime.create : !async.token
153a6628e59SEugene Zhulenev  %1 = async.coro.id
154a6628e59SEugene Zhulenev  %2 = async.coro.begin %1
155a6628e59SEugene Zhulenev  %3 = async.coro.save %2
156a6628e59SEugene Zhulenev  async.runtime.resume %2
157a6628e59SEugene Zhulenev  // CHECK: async.coro.suspend
158a6628e59SEugene Zhulenev  async.coro.suspend %3, ^suspend, ^resume, ^cleanup
159a6628e59SEugene Zhulenev^resume:
160a6628e59SEugene Zhulenev  // CHECK: ^[[RESUME:.*]]:
161a6628e59SEugene Zhulenev  %4 = async.coro.save %2
162a6628e59SEugene Zhulenev  async.runtime.await_and_resume %arg0, %2 : !async.token
16392db09cdSEugene Zhulenev  // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
164a6628e59SEugene Zhulenev  // CHECK: async.coro.suspend
165a6628e59SEugene Zhulenev  async.coro.suspend %4, ^suspend, ^resume_1, ^cleanup
166a6628e59SEugene Zhulenev^resume_1:
167a6628e59SEugene Zhulenev  // CHECK: ^[[RESUME_1:.*]]:
168a6628e59SEugene Zhulenev  // CHECK:   async.runtime.set_available
169a6628e59SEugene Zhulenev  async.runtime.set_available %0 : !async.token
170ace01605SRiver Riddle  cf.br ^cleanup
171a6628e59SEugene Zhulenev^cleanup:
172a6628e59SEugene Zhulenev  // CHECK: ^[[CLEANUP:.*]]:
173a6628e59SEugene Zhulenev  // CHECK:   async.coro.free
174a6628e59SEugene Zhulenev  async.coro.free %1, %2
175ace01605SRiver Riddle  cf.br ^suspend
176a6628e59SEugene Zhulenev^suspend:
177a6628e59SEugene Zhulenev  // CHECK: ^[[SUSPEND:.*]]:
178a6628e59SEugene Zhulenev  // CHECK:   async.coro.end
179a6628e59SEugene Zhulenev  async.coro.end %2
180a6628e59SEugene Zhulenev  return %0 : !async.token
181a6628e59SEugene Zhulenev}
182a6628e59SEugene Zhulenev
183a6628e59SEugene Zhulenev// CHECK-LABEL: @token_await_inside_nested_region
184a6628e59SEugene Zhulenev// CHECK: %[[ARG:.*]]: i1
185*5e7dea22SRiver Riddlefunc.func @token_await_inside_nested_region(%arg0: i1) {
186a6628e59SEugene Zhulenev  // CHECK: %[[TOKEN:.*]] = call @token()
187a6628e59SEugene Zhulenev  %token = call @token() : () -> !async.token
188a6628e59SEugene Zhulenev  // CHECK: scf.if %[[ARG]] {
189a6628e59SEugene Zhulenev  scf.if %arg0 {
190a6628e59SEugene Zhulenev    // CHECK: async.runtime.await %[[TOKEN]]
191a6628e59SEugene Zhulenev    async.runtime.await %token : !async.token
192a6628e59SEugene Zhulenev  }
193a6628e59SEugene Zhulenev  // CHECK: }
19492db09cdSEugene Zhulenev  // CHECK: async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
195a6628e59SEugene Zhulenev  // CHECK: return
196a6628e59SEugene Zhulenev  return
197a6628e59SEugene Zhulenev}
198a6628e59SEugene Zhulenev
199a6628e59SEugene Zhulenev// CHECK-LABEL: @token_defined_in_the_loop
200*5e7dea22SRiver Riddlefunc.func @token_defined_in_the_loop() {
201ace01605SRiver Riddle  cf.br ^bb1
202a6628e59SEugene Zhulenev^bb1:
203a6628e59SEugene Zhulenev  // CHECK: ^[[BB1:.*]]:
204a6628e59SEugene Zhulenev  // CHECK:   %[[TOKEN:.*]] = call @token()
205a6628e59SEugene Zhulenev  %token = call @token() : () -> !async.token
206a6628e59SEugene Zhulenev  // CHECK:   async.runtime.await %[[TOKEN]]
20792db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
208a6628e59SEugene Zhulenev  async.runtime.await %token : !async.token
209a6628e59SEugene Zhulenev  %0 = call @cond(): () -> (i1)
210ace01605SRiver Riddle  cf.cond_br %0, ^bb1, ^bb2
211a6628e59SEugene Zhulenev^bb2:
212a6628e59SEugene Zhulenev  // CHECK: ^[[BB2:.*]]:
213a6628e59SEugene Zhulenev  // CHECK:   return
214a6628e59SEugene Zhulenev  return
215a6628e59SEugene Zhulenev}
216c412979cSEugene Zhulenev
217c412979cSEugene Zhulenev// CHECK-LABEL: @divergent_liveness_one_token
218*5e7dea22SRiver Riddlefunc.func @divergent_liveness_one_token(%arg0 : i1) {
219c412979cSEugene Zhulenev  // CHECK: %[[TOKEN:.*]] = call @token()
220c412979cSEugene Zhulenev  %token = call @token() : () -> !async.token
221ace01605SRiver Riddle  // CHECK: cf.cond_br %arg0, ^[[LIVE_IN:.*]], ^[[REF_COUNTING:.*]]
222ace01605SRiver Riddle  cf.cond_br %arg0, ^bb1, ^bb2
223c412979cSEugene Zhulenev^bb1:
224c412979cSEugene Zhulenev  // CHECK: ^[[LIVE_IN]]:
225c412979cSEugene Zhulenev  // CHECK:   async.runtime.await %[[TOKEN]]
22692db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
227ace01605SRiver Riddle  // CHECK:   cf.br ^[[RETURN:.*]]
228c412979cSEugene Zhulenev  async.runtime.await %token : !async.token
229ace01605SRiver Riddle  cf.br ^bb2
230c412979cSEugene Zhulenev  // CHECK: ^[[REF_COUNTING:.*]]:
23192db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
232ace01605SRiver Riddle  // CHECK:   cf.br ^[[RETURN:.*]]
233c412979cSEugene Zhulenev^bb2:
234c412979cSEugene Zhulenev  // CHECK: ^[[RETURN]]:
235c412979cSEugene Zhulenev  // CHECK:   return
236c412979cSEugene Zhulenev  return
237c412979cSEugene Zhulenev}
238c412979cSEugene Zhulenev
239c412979cSEugene Zhulenev// CHECK-LABEL: @divergent_liveness_unique_predecessor
240*5e7dea22SRiver Riddlefunc.func @divergent_liveness_unique_predecessor(%arg0 : i1) {
241c412979cSEugene Zhulenev  // CHECK: %[[TOKEN:.*]] = call @token()
242c412979cSEugene Zhulenev  %token = call @token() : () -> !async.token
243ace01605SRiver Riddle  // CHECK: cf.cond_br %arg0, ^[[LIVE_IN:.*]], ^[[NO_LIVE_IN:.*]]
244ace01605SRiver Riddle  cf.cond_br %arg0, ^bb2, ^bb1
245c412979cSEugene Zhulenev^bb1:
246c412979cSEugene Zhulenev  // CHECK: ^[[NO_LIVE_IN]]:
24792db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
248ace01605SRiver Riddle  // CHECK:   cf.br ^[[RETURN:.*]]
249ace01605SRiver Riddle  cf.br ^bb3
250c412979cSEugene Zhulenev^bb2:
251c412979cSEugene Zhulenev  // CHECK: ^[[LIVE_IN]]:
252c412979cSEugene Zhulenev  // CHECK:   async.runtime.await %[[TOKEN]]
25392db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN]] {count = 1 : i64}
254ace01605SRiver Riddle  // CHECK:   cf.br ^[[RETURN]]
255c412979cSEugene Zhulenev  async.runtime.await %token : !async.token
256ace01605SRiver Riddle  cf.br ^bb3
257c412979cSEugene Zhulenev^bb3:
258c412979cSEugene Zhulenev  // CHECK: ^[[RETURN]]:
259c412979cSEugene Zhulenev  // CHECK:  return
260c412979cSEugene Zhulenev  return
261c412979cSEugene Zhulenev}
262c412979cSEugene Zhulenev
263c412979cSEugene Zhulenev// CHECK-LABEL: @divergent_liveness_two_tokens
264*5e7dea22SRiver Riddlefunc.func @divergent_liveness_two_tokens(%arg0 : i1) {
265c412979cSEugene Zhulenev  // CHECK: %[[TOKEN0:.*]] = call @token()
266c412979cSEugene Zhulenev  // CHECK: %[[TOKEN1:.*]] = call @token()
267c412979cSEugene Zhulenev  %token0 = call @token() : () -> !async.token
268c412979cSEugene Zhulenev  %token1 = call @token() : () -> !async.token
269ace01605SRiver Riddle  // CHECK: cf.cond_br %arg0, ^[[AWAIT0:.*]], ^[[AWAIT1:.*]]
270ace01605SRiver Riddle  cf.cond_br %arg0, ^await0, ^await1
271c412979cSEugene Zhulenev^await0:
272c412979cSEugene Zhulenev  // CHECK: ^[[AWAIT0]]:
27392db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN1]] {count = 1 : i64}
274c412979cSEugene Zhulenev  // CHECK:   async.runtime.await %[[TOKEN0]]
27592db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN0]] {count = 1 : i64}
276ace01605SRiver Riddle  // CHECK:   cf.br ^[[RETURN:.*]]
277c412979cSEugene Zhulenev  async.runtime.await %token0 : !async.token
278ace01605SRiver Riddle  cf.br ^ret
279c412979cSEugene Zhulenev^await1:
280c412979cSEugene Zhulenev  // CHECK: ^[[AWAIT1]]:
28192db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN0]] {count = 1 : i64}
282c412979cSEugene Zhulenev  // CHECK:   async.runtime.await %[[TOKEN1]]
28392db09cdSEugene Zhulenev  // CHECK:   async.runtime.drop_ref %[[TOKEN1]] {count = 1 : i64}
284ace01605SRiver Riddle  // CHECK:   cf.br ^[[RETURN]]
285c412979cSEugene Zhulenev  async.runtime.await %token1 : !async.token
286ace01605SRiver Riddle  cf.br ^ret
287c412979cSEugene Zhulenev^ret:
288c412979cSEugene Zhulenev  // CHECK: ^[[RETURN]]:
289c412979cSEugene Zhulenev  // CHECK:   return
290c412979cSEugene Zhulenev  return
291c412979cSEugene Zhulenev}
292