@@ -152,8 +152,8 @@ lowerings:
152
152
- In yield-once returned-continuation lowering, the coroutine must
153
153
suspend itself exactly once (or throw an exception). The ramp
154
154
function returns a continuation function pointer and yielded
155
- values, but the continuation function simply returns ` void `
156
- when the coroutine has run to completion.
155
+ values, the continuation function may optionally return ordinary
156
+ results when the coroutine has run to completion.
157
157
158
158
The coroutine frame is maintained in a fixed-size buffer that is
159
159
passed to the `coro.id ` intrinsic, which guarantees a certain size
@@ -304,7 +304,7 @@ The LLVM IR for this coroutine looks like this:
304
304
call void @free(ptr %mem)
305
305
br label %suspend
306
306
suspend:
307
- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false)
307
+ %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none )
308
308
ret ptr %hdl
309
309
}
310
310
@@ -631,7 +631,7 @@ store the current value produced by a coroutine.
631
631
call void @free(ptr %mem)
632
632
br label %suspend
633
633
suspend:
634
- %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false)
634
+ %unused = call i1 @llvm.coro.end(ptr %hdl, i1 false, token none )
635
635
ret ptr %hdl
636
636
}
637
637
@@ -1313,8 +1313,8 @@ Arguments:
1313
1313
""""""""""
1314
1314
1315
1315
As for ``llvm.core.id.retcon ``, except that the return type of the
1316
- continuation prototype must be ` void ` instead of matching the
1317
- coroutine's return type.
1316
+ continuation prototype must represent the normal return type of the continuation
1317
+ (instead of matching the coroutine's return type) .
1318
1318
1319
1319
Semantics:
1320
1320
""""""""""
@@ -1327,7 +1327,7 @@ A frontend should emit function attribute `presplitcoroutine` for the coroutine.
1327
1327
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1328
1328
::
1329
1329
1330
- declare i1 @llvm.coro.end(ptr <handle>, i1 <unwind>)
1330
+ declare i1 @llvm.coro.end(ptr <handle>, i1 <unwind>, token <result.token> )
1331
1331
1332
1332
Overview:
1333
1333
"""""""""
@@ -1348,6 +1348,12 @@ The second argument should be `true` if this coro.end is in the block that is
1348
1348
part of the unwind sequence leaving the coroutine body due to an exception and
1349
1349
`false ` otherwise.
1350
1350
1351
+ Non-trivial (non-none) token argument can only be specified for unique-suspend
1352
+ returned-continuation coroutines where it must be a token value produced by
1353
+ '``llvm.coro.end.results ``' intrinsic.
1354
+
1355
+ Only none token is allowed for coro.end calls in unwind sections
1356
+
1351
1357
Semantics:
1352
1358
""""""""""
1353
1359
The purpose of this intrinsic is to allow frontends to mark the cleanup and
@@ -1379,7 +1385,7 @@ For landingpad based exception model, it is expected that frontend uses the
1379
1385
.. code-block :: llvm
1380
1386
1381
1387
ehcleanup:
1382
- %InResumePart = call i1 @llvm.coro.end(ptr null, i1 true)
1388
+ %InResumePart = call i1 @llvm.coro.end(ptr null, i1 true, token none )
1383
1389
br i1 %InResumePart, label %eh.resume, label %cleanup.cont
1384
1390
1385
1391
cleanup.cont:
@@ -1404,7 +1410,7 @@ referring to an enclosing cleanuppad as follows:
1404
1410
1405
1411
ehcleanup:
1406
1412
%tok = cleanuppad within none []
1407
- %unused = call i1 @llvm.coro.end(ptr null, i1 true) [ "funclet"(token %tok) ]
1413
+ %unused = call i1 @llvm.coro.end(ptr null, i1 true, token none ) [ "funclet"(token %tok) ]
1408
1414
cleanupret from %tok unwind label %RestOfTheCleanup
1409
1415
1410
1416
The `CoroSplit ` pass, if the funclet bundle is present, will insert
@@ -1429,6 +1435,53 @@ The following table summarizes the handling of `coro.end`_ intrinsic.
1429
1435
| | Landingpad | mark coroutine as done | mark coroutine done |
1430
1436
+------------+-------------+------------------------+---------------------------------+
1431
1437
1438
+ .. _coro.end.results :
1439
+
1440
+ 'llvm.coro.end.results' Intrinsic
1441
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1442
+ ::
1443
+
1444
+ declare token @llvm.coro.end.results(...)
1445
+
1446
+ Overview:
1447
+ """""""""
1448
+
1449
+ The '``llvm.coro.end.results ``' intrinsic captures values to be returned from
1450
+ unique-suspend returned-continuation coroutines.
1451
+
1452
+ Arguments:
1453
+ """"""""""
1454
+
1455
+ The number of arguments must match the return type of the continuation function:
1456
+
1457
+ - if the return type of the continuation function is ``void `` there must be no
1458
+ arguments
1459
+
1460
+ - if the return type of the continuation function is a ``struct ``, the arguments
1461
+ will be of element types of that ``struct `` in order;
1462
+
1463
+ - otherwise, it is just the return value of the continuation function.
1464
+
1465
+ .. code-block :: llvm
1466
+
1467
+ define {ptr, ptr} @g(ptr %buffer, ptr %ptr, i8 %val) presplitcoroutine {
1468
+ entry:
1469
+ %id = call token @llvm.coro.id.retcon.once(i32 8, i32 8, ptr %buffer,
1470
+ ptr @prototype,
1471
+ ptr @allocate, ptr @deallocate)
1472
+ %hdl = call ptr @llvm.coro.begin(token %id, ptr null)
1473
+
1474
+ ...
1475
+
1476
+ cleanup:
1477
+ %tok = call token (...) @llvm.coro.end.results(i8 %val)
1478
+ call i1 @llvm.coro.end(ptr %hdl, i1 0, token %tok)
1479
+ unreachable
1480
+
1481
+ ...
1482
+
1483
+ declare i8 @prototype(ptr, i1 zeroext)
1484
+
1432
1485
1433
1486
'llvm.coro.end.async' Intrinsic
1434
1487
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0 commit comments