@@ -95,7 +95,8 @@ The LLVM IR for this coroutine looks like this:
95
95
entry:
96
96
%size = call i32 @llvm.coro.size.i32()
97
97
%alloc = call i8* @malloc(i32 %size)
98
- %hdl = call noalias i8* @llvm.coro.begin(i8* %alloc, i32 0, i8* null, i8* null)
98
+ %beg = call token @llvm.coro.begin(i8* %alloc, i8* null, i32 0, i8* null, i8* null)
99
+ %hdl = call noalias i8* @llvm.coro.frame(token %beg)
99
100
br label %loop
100
101
loop:
101
102
%n.val = phi i32 [ %n, %entry ], [ %inc, %loop ]
@@ -115,9 +116,10 @@ The LLVM IR for this coroutine looks like this:
115
116
116
117
The `entry ` block establishes the coroutine frame. The `coro.size `_ intrinsic is
117
118
lowered to a constant representing the size required for the coroutine frame.
118
- The `coro.begin `_ intrinsic initializes the coroutine frame and returns the
119
- coroutine handle. The first parameter of `coro.begin ` is given a block of memory
120
- to be used if the coroutine frame needs to be allocated dynamically.
119
+ The `coro.begin `_ intrinsic initializes the coroutine frame and returns the a
120
+ token that is used to obtain the coroutine handle via `coro.frame ` intrinsic.
121
+ The first parameter of `coro.begin ` is given a block of memory to be used if the
122
+ coroutine frame needs to be allocated dynamically.
121
123
122
124
The `cleanup ` block destroys the coroutine frame. The `coro.free `_ intrinsic,
123
125
given the coroutine handle, returns a pointer of the memory block to be freed or
@@ -160,12 +162,13 @@ After resume and destroy parts are outlined, function `f` will contain only the
160
162
code responsible for creation and initialization of the coroutine frame and
161
163
execution of the coroutine until a suspend point is reached:
162
164
163
- .. code-block :: llvm
165
+ .. code-block :: none
164
166
165
167
define i8* @f(i32 %n) {
166
168
entry:
167
169
%alloc = call noalias i8* @malloc(i32 24)
168
- %0 = call noalias i8* @llvm.coro.begin(i8* %alloc, i32 0, i8* null, i8* null)
170
+ %beg = call token @llvm.coro.begin(i8* %alloc, i8* null, i32 0, i8* null, i8* null)
171
+ %0 = call i8* @llvm.coro.frame(token %beg)
169
172
%frame = bitcast i8* %0 to %f.frame*
170
173
%1 = getelementptr %f.frame, %f.frame* %frame, i32 0, i32 0
171
174
store void (%f.frame*)* @f.resume, void (%f.frame*)** %1
@@ -219,7 +222,7 @@ In the entry block, we will call `coro.alloc`_ intrinsic that will return `null`
219
222
when dynamic allocation is required, and an address of an alloca on the caller's
220
223
frame where coroutine frame can be stored if dynamic allocation is elided.
221
224
222
- .. code-block :: llvm
225
+ .. code-block :: none
223
226
224
227
entry:
225
228
%elide = call i8* @llvm.coro.alloc()
@@ -231,7 +234,7 @@ frame where coroutine frame can be stored if dynamic allocation is elided.
231
234
br label %coro.begin
232
235
coro.begin:
233
236
%phi = phi i8* [ %elide, %entry ], [ %alloc, %dyn.alloc ]
234
- %hdl = call noalias i8* @llvm.coro.begin(i8* %phi, i32 0, i8* null, i8* null)
237
+ %beg = call token @llvm.coro.begin(i8* %phi, i8* null , i32 0, i8* null, i8* null)
235
238
236
239
In the cleanup block, we will make freeing the coroutine frame conditional on
237
240
`coro.free `_ intrinsic. If allocation is elided, `coro.free `_ returns `null `
@@ -421,7 +424,8 @@ store the current value produced by a coroutine.
421
424
br label %coro.begin
422
425
coro.begin:
423
426
%phi = phi i8* [ %elide, %entry ], [ %alloc, %dyn.alloc ]
424
- %hdl = call noalias i8* @llvm.coro.begin(i8* %phi, i32 0, i8* %pv, i8* null)
427
+ %beg = call token @llvm.coro.begin(i8* %phi, i8* %elide, i32 0, i8* %pv, i8* null)
428
+ %hdl = call i8* @llvm.coro.frame(token %beg)
425
429
br label %loop
426
430
loop:
427
431
%n.val = phi i32 [ %n, %coro.begin ], [ %inc, %loop ]
@@ -687,15 +691,16 @@ a coroutine user are responsible to makes sure there is no data races.
687
691
Example:
688
692
""""""""
689
693
690
- .. code-block :: llvm
694
+ .. code-block :: text
691
695
692
696
define i8* @f(i32 %n) {
693
697
entry:
694
698
%promise = alloca i32
695
699
%pv = bitcast i32* %promise to i8*
696
700
...
697
- ; the third argument to coro.begin points to the coroutine promise.
698
- %hdl = call noalias i8* @llvm.coro.begin(i8* %alloc, i32 0, i8* %pv, i8* null)
701
+ ; the fourth argument to coro.begin points to the coroutine promise.
702
+ %beg = call token @llvm.coro.begin(i8* %alloc, i8* null, i32 0, i8* %pv, i8* null)
703
+ %hdl = call noalias i8* @llvm.coro.frame(token %beg)
699
704
...
700
705
store i32 42, i32* %promise ; store something into the promise
701
706
...
@@ -752,39 +757,43 @@ the coroutine frame.
752
757
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
753
758
::
754
759
755
- declare i8* @llvm.coro.begin(i8* <mem>, i32 <align>, i8* <promise>, i8* <fnaddr>)
760
+ declare i8* @llvm.coro.begin(i8* <mem>, i8* <elide>, i32 <align>, i8* <promise>, i8* <fnaddr>)
756
761
757
762
Overview:
758
763
"""""""""
759
764
760
- The '``llvm.coro.begin ``' intrinsic returns an address of the coroutine frame.
765
+ The '``llvm.coro.begin ``' intrinsic captures coroutine initialization
766
+ information and returns a token that can be used by `coro.frame ` intrinsic to
767
+ return an address of the coroutine frame.
761
768
762
769
Arguments:
763
770
""""""""""
764
771
765
772
The first argument is a pointer to a block of memory where coroutine frame
766
773
will be stored.
767
774
768
- The second argument provides information on the alignment of the memory returned
775
+ The second argument is either null or an SSA value of `coro.alloc ` intrinsic.
776
+
777
+ The third argument provides information on the alignment of the memory returned
769
778
by the allocation function and given to `coro.begin ` by the first argument. If
770
779
this argument is 0, the memory is assumed to be aligned to 2 * sizeof(i8*).
771
780
This argument only accepts constants.
772
781
773
- The third argument, if not `null `, designates a particular alloca instruction to
782
+ The fourth argument, if not `null `, designates a particular alloca instruction to
774
783
be a `coroutine promise `_.
775
784
776
- The fourth argument is `null ` before coroutine is split, and later is replaced
785
+ The fifth argument is `null ` before coroutine is split, and later is replaced
777
786
to point to a private global constant array containing function pointers to
778
787
outlined resume and destroy parts of the coroutine.
779
788
780
789
Semantics:
781
790
""""""""""
782
791
783
792
Depending on the alignment requirements of the objects in the coroutine frame
784
- and/or on the codegen compactness reasons the pointer returned from `coro.begin `
785
- may be at offset to the `%mem ` argument. (This could be beneficial if
786
- instructions that express relative access to data can be more compactly encoded
787
- with small positive and negative offsets).
793
+ and/or on the codegen compactness reasons the pointer returned from `coro.frame `
794
+ associated with a particular ` coro.begin ` may be at offset to the `%mem `
795
+ argument. (This could be beneficial if instructions that express relative access
796
+ to data can be more compactly encoded with small positive and negative offsets).
788
797
789
798
A frontend should emit exactly one `coro.begin ` intrinsic per coroutine.
790
799
@@ -807,7 +816,7 @@ Arguments:
807
816
""""""""""
808
817
809
818
A pointer to the coroutine frame. This should be the same pointer that was
810
- returned by prior `coro.begin ` call.
819
+ returned by prior `coro.frame ` call.
811
820
812
821
Example (custom deallocation function):
813
822
"""""""""""""""""""""""""""""""""""""""
@@ -862,10 +871,13 @@ alloca storing the coroutine frame. Otherwise, it is lowered to constant `null`.
862
871
863
872
A frontend should emit at most one `coro.alloc ` intrinsic per coroutine.
864
873
874
+ If `coro.alloc ` is present, the second parameter to `coro.begin ` should refer
875
+ to it.
876
+
865
877
Example:
866
878
""""""""
867
879
868
- .. code-block :: llvm
880
+ .. code-block :: text
869
881
870
882
entry:
871
883
%elide = call i8* @llvm.coro.alloc()
@@ -879,7 +891,8 @@ Example:
879
891
880
892
coro.begin:
881
893
%phi = phi i8* [ %elide, %entry ], [ %alloc, %coro.alloc ]
882
- %frame = call i8* @llvm.coro.begin(i8* %phi, i32 0, i8* null, i8* null)
894
+ %beg = call token @llvm.coro.begin(i8* %phi, i8* %elide, i32 0, i8* null, i8* null)
895
+ %frame = call i8* @llvm.coro.frame(token %beg)
883
896
884
897
.. _coro.frame :
885
898
@@ -898,14 +911,12 @@ the enclosing coroutine.
898
911
Arguments:
899
912
""""""""""
900
913
901
- None
914
+ A token that refers to ` coro.begin ` instruction.
902
915
903
916
Semantics:
904
917
""""""""""
905
918
906
- This intrinsic is lowered to refer to the `coro.begin `_ instruction. This is
907
- a frontend convenience intrinsic that makes it easier to refer to the
908
- coroutine frame.
919
+ This intrinsic is lowered to refer to address of the coroutine frame.
909
920
910
921
.. _coro.end :
911
922
@@ -1164,7 +1175,7 @@ CoroElide
1164
1175
---------
1165
1176
The pass CoroElide examines if the inlined coroutine is eligible for heap
1166
1177
allocation elision optimization. If so, it replaces `coro.alloc ` and
1167
- `coro.begin ` intrinsic with an address of a coroutine frame placed on its caller
1178
+ `coro.frame ` intrinsic with an address of a coroutine frame placed on its caller
1168
1179
and replaces `coro.free ` intrinsics with `null ` to remove the deallocation code.
1169
1180
This pass also replaces `coro.resume ` and `coro.destroy ` intrinsics with direct
1170
1181
calls to resume and destroy functions for a particular coroutine where possible.
@@ -1178,11 +1189,11 @@ Upstreaming sequence (rough plan)
1178
1189
=================================
1179
1190
#. Add documentation.
1180
1191
#. Add coroutine intrinsics.
1181
- #. Add empty coroutine passes. <== we are here
1192
+ #. Add empty coroutine passes.
1182
1193
#. Add coroutine devirtualization + tests.
1183
1194
#. Add CGSCC restart trigger + tests.
1184
1195
#. Add coroutine heap elision + tests.
1185
- #. Add custom allocation heap elision + tests.
1196
+ #. Add custom allocation heap elision + tests. <== we are here
1186
1197
#. Add coroutine splitting logic + tests.
1187
1198
#. Add simple coroutine frame builder + tests.
1188
1199
#. Add the rest of the logic + tests. (Maybe split further as needed).
0 commit comments