Skip to content

Commit 42f1916

Browse files
committed
Revert "Start of an llvm.coro.async implementation"
This reverts commit ea606cc. This patch causes memory sanitizer failures sanitizer-x86_64-linux-fast.
1 parent 9d58dab commit 42f1916

File tree

10 files changed

+32
-815
lines changed

10 files changed

+32
-815
lines changed

llvm/docs/Coroutines.rst

Lines changed: 0 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -174,61 +174,6 @@ This may be acceptable if LLVM's coroutine support is primarily being
174174
used for low-level lowering and inlining is expected to be applied
175175
earlier in the pipeline.
176176

177-
Async Lowering
178-
--------------
179-
180-
In async-continuation lowering, signaled by the use of `llvm.coro.id.async`,
181-
handling of control-flow must be handled explicitly by the frontend.
182-
183-
In this lowering, a coroutine is assumed to take the current `async context` as
184-
its first argument. It is used to marshal arguments and return values of the
185-
coroutine. Therefore a async coroutine returns `void`.
186-
187-
.. code-block:: llvm
188-
define swiftcc void @async_coroutine(i8* %async.ctxt, i8*, i8*) {
189-
}
190-
191-
192-
Every suspend point takes an `async context` argument which provides the context
193-
and the coroutine frame of the callee function. Every
194-
suspend point has an associated `resume function` denoted by the
195-
`llvm.coro.async.resume` intrinsic. The coroutine is resumed by
196-
calling this `resume function` passing the `async context` as the first
197-
argument. It is assumed that the `resume function` can restore its (the
198-
caller's) `async context` by loading the first field in the `async context`.
199-
200-
.. code-block:: c
201-
202-
struct async_context {
203-
struct async_context *caller_context;
204-
...
205-
}
206-
207-
The frontend should provide a `async function pointer` struct associated with
208-
each async coroutine by `llvm.coro.id.async`'s argument. The initial size and
209-
alignment of the `async context` must be provided as arguments to the
210-
`llvm.coro.id.async` intrinsic. Lowering will update the size entry with the
211-
coroutine frame requirements. The frontend is responsible for allocating the
212-
memory for the `async context` but can use the `async function pointer` struct
213-
to obtain the required size.
214-
215-
.. code-block:: c
216-
struct async_function_pointer {
217-
uint32_t context_size;
218-
uint32_t relative_function_pointer_to_async_impl;
219-
}
220-
221-
Lowering will split an async coroutine into a ramp function and one resume
222-
function per suspend point.
223-
224-
How control-flow is passed between caller, suspension point, and back to
225-
resume function is left up to the frontend.
226-
227-
The suspend point takes a function and its arguments. The function is intended
228-
to model the transfer to the callee function. It will be tail called by
229-
lowering and therefore must have the same signature and calling convention as
230-
the async coroutine.
231-
232177
Coroutines by Example
233178
=====================
234179

@@ -1148,45 +1093,6 @@ duplicated.
11481093

11491094
A frontend should emit exactly one `coro.id` intrinsic per coroutine.
11501095

1151-
.. _coro.id.async:
1152-
1153-
'llvm.coro.id.async' Intrinsic
1154-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1155-
::
1156-
1157-
declare token @llvm.coro.id.async(i32 <context size>, i32 <align>,
1158-
i8* <context arg>,
1159-
i8* <async function pointer>)
1160-
1161-
Overview:
1162-
"""""""""
1163-
1164-
The '``llvm.coro.id.async``' intrinsic returns a token identifying an async coroutine.
1165-
1166-
Arguments:
1167-
""""""""""
1168-
1169-
The first argument provides the initial size of the `async context` as required
1170-
from the frontend. Lowering will add to this size the size required by the frame
1171-
storage and store that value to the `async function pointer`.
1172-
1173-
The second argument, is the alignment guarantee of the memory of the
1174-
`async context`. The frontend guarantees that the memory will be aligned by this
1175-
value.
1176-
1177-
The third argument is the `async context` argument in the current coroutine.
1178-
1179-
The fourth argument is the address of the `async function pointer` struct.
1180-
Lowering will update the context size requirement in this struct by adding the
1181-
coroutine frame size requirement to the initial size requirement as specified by
1182-
the first argument of this intrinisc.
1183-
1184-
1185-
Semantics:
1186-
""""""""""
1187-
1188-
A frontend should emit exactly one `coro.id.async` intrinsic per coroutine.
1189-
11901096
.. _coro.id.retcon:
11911097

11921098
'llvm.coro.id.retcon' Intrinsic
@@ -1474,46 +1380,6 @@ to the coroutine:
14741380
switch i8 %suspend1, label %suspend [i8 0, label %resume1
14751381
i8 1, label %cleanup]
14761382
1477-
.. _coro.suspend.async:
1478-
1479-
'llvm.coro.suspend.async' Intrinsic
1480-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1481-
::
1482-
1483-
declare {i8*, i8*, i8*} @llvm.coro.suspend.async(i8* <resume function>,
1484-
i8* <callee context>,
1485-
... <function to call>
1486-
... <arguments to function>)
1487-
1488-
Overview:
1489-
"""""""""
1490-
1491-
The '``llvm.coro.suspend.async``' intrinsic marks the point where
1492-
execution of a async coroutine is suspended and control is passed to a callee.
1493-
1494-
Arguments:
1495-
""""""""""
1496-
1497-
The first argument should be the result of the `llvm.coro.async.resume` intrinsic.
1498-
Lowering will replace this intrinsic with the resume function for this suspend
1499-
point.
1500-
1501-
The second argument is the `async context` allocation for the callee. It should
1502-
provide storage the `async context` header and the coroutine frame.
1503-
1504-
The third argument is the function that models tranfer to the callee at the
1505-
suspend point. It should take 3 arguments. Lowering will `musttail` call this
1506-
function.
1507-
1508-
The fourth to six argument are the arguments for the third argument.
1509-
1510-
Semantics:
1511-
""""""""""
1512-
1513-
The result of the intrinsic are mapped to the arguments of the resume function.
1514-
Execution is suspended at this intrinsic and resumed when the resume function is
1515-
called.
1516-
15171383
.. _coro.suspend.retcon:
15181384

15191385
'llvm.coro.suspend.retcon' Intrinsic

llvm/include/llvm/IR/Intrinsics.td

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,21 +1187,6 @@ def int_coro_id_retcon_once : Intrinsic<[llvm_token_ty],
11871187
llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
11881188
[]>;
11891189
def int_coro_alloc : Intrinsic<[llvm_i1_ty], [llvm_token_ty], []>;
1190-
def int_coro_id_async : Intrinsic<[llvm_token_ty],
1191-
[llvm_i32_ty, llvm_i32_ty, llvm_ptr_ty, llvm_ptr_ty],
1192-
[]>;
1193-
def int_coro_async_context_alloc : Intrinsic<[llvm_ptr_ty],
1194-
[llvm_ptr_ty, llvm_ptr_ty],
1195-
[]>;
1196-
def int_coro_async_context_dealloc : Intrinsic<[],
1197-
[llvm_ptr_ty],
1198-
[]>;
1199-
def int_coro_async_resume : Intrinsic<[llvm_ptr_ty],
1200-
[],
1201-
[]>;
1202-
def int_coro_suspend_async : Intrinsic<[llvm_ptr_ty, llvm_ptr_ty, llvm_ptr_ty],
1203-
[llvm_ptr_ty, llvm_ptr_ty, llvm_vararg_ty],
1204-
[]>;
12051190
def int_coro_begin : Intrinsic<[llvm_ptr_ty], [llvm_token_ty, llvm_ptr_ty],
12061191
[WriteOnly<ArgIndex<1>>]>;
12071192

llvm/lib/Transforms/Coroutines/CoroCleanup.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ bool Lowerer::lowerRemainingCoroIntrinsics(Function &F) {
7474
case Intrinsic::coro_id:
7575
case Intrinsic::coro_id_retcon:
7676
case Intrinsic::coro_id_retcon_once:
77-
case Intrinsic::coro_id_async:
7877
II->replaceAllUsesWith(ConstantTokenNone::get(Context));
7978
break;
8079
case Intrinsic::coro_subfn_addr:

llvm/lib/Transforms/Coroutines/CoroEarly.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,6 @@ bool Lowerer::lowerEarlyIntrinsics(Function &F) {
187187
break;
188188
case Intrinsic::coro_id_retcon:
189189
case Intrinsic::coro_id_retcon_once:
190-
case Intrinsic::coro_id_async:
191190
F.addFnAttr(CORO_PRESPLIT_ATTR, PREPARED_FOR_SPLIT);
192191
break;
193192
case Intrinsic::coro_resume:

llvm/lib/Transforms/Coroutines/CoroFrame.cpp

Lines changed: 7 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,10 @@ struct SuspendCrossingInfo {
135135

136136
BasicBlock *UseBB = I->getParent();
137137

138-
// As a special case, treat uses by an llvm.coro.suspend.retcon or an
139-
// llvm.coro.suspend.async as if they were uses in the suspend's single
140-
// predecessor: the uses conceptually occur before the suspend.
141-
if (isa<CoroSuspendRetconInst>(I) || isa<CoroSuspendAsyncInst>(I)) {
138+
// As a special case, treat uses by an llvm.coro.suspend.retcon
139+
// as if they were uses in the suspend's single predecessor: the
140+
// uses conceptually occur before the suspend.
141+
if (isa<CoroSuspendRetconInst>(I)) {
142142
UseBB = UseBB->getSinglePredecessor();
143143
assert(UseBB && "should have split coro.suspend into its own block");
144144
}
@@ -788,18 +788,6 @@ static StructType *buildFrameType(Function &F, coro::Shape &Shape,
788788
B.getStructAlign() <= Id->getStorageAlignment());
789789
break;
790790
}
791-
case coro::ABI::Async: {
792-
Shape.AsyncLowering.FrameOffset =
793-
alignTo(Shape.AsyncLowering.ContextHeaderSize, Shape.FrameAlign);
794-
Shape.AsyncLowering.ContextSize =
795-
Shape.AsyncLowering.FrameOffset + Shape.FrameSize;
796-
if (Shape.AsyncLowering.getContextAlignment() < Shape.FrameAlign) {
797-
report_fatal_error(
798-
"The alignment requirment of frame variables cannot be higher than "
799-
"the alignment of the async function context");
800-
}
801-
break;
802-
}
803791
}
804792

805793
return FrameTy;
@@ -1155,8 +1143,7 @@ static Instruction *insertSpills(const FrameDataInfo &FrameData,
11551143
Shape.AllocaSpillBlock = SpillBlock;
11561144

11571145
// retcon and retcon.once lowering assumes all uses have been sunk.
1158-
if (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce ||
1159-
Shape.ABI == coro::ABI::Async) {
1146+
if (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce) {
11601147
// If we found any allocas, replace all of their remaining uses with Geps.
11611148
Builder.SetInsertPoint(&SpillBlock->front());
11621149
for (const auto &P : FrameData.Allocas) {
@@ -1879,8 +1866,7 @@ static void sinkSpillUsesAfterCoroBegin(Function &F,
18791866
for (User *U : Def->users()) {
18801867
auto Inst = cast<Instruction>(U);
18811868
if (Inst->getParent() != CoroBegin->getParent() ||
1882-
Dom.dominates(CoroBegin, Inst) ||
1883-
isa<CoroIdAsyncInst>(Inst) /*'fake' use of async context argument*/)
1869+
Dom.dominates(CoroBegin, Inst))
18841870
continue;
18851871
if (ToMove.insert(Inst))
18861872
Worklist.push_back(Inst);
@@ -2176,8 +2162,7 @@ void coro::buildCoroutineFrame(Function &F, Shape &Shape) {
21762162
}
21772163
}
21782164
LLVM_DEBUG(dumpSpills("Spills", FrameData.Spills));
2179-
if (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce ||
2180-
Shape.ABI == coro::ABI::Async)
2165+
if (Shape.ABI == coro::ABI::Retcon || Shape.ABI == coro::ABI::RetconOnce)
21812166
sinkSpillUsesAfterCoroBegin(F, FrameData, Shape.CoroBegin);
21822167
Shape.FrameTy = buildFrameType(F, Shape, FrameData);
21832168
// Add PromiseAlloca to Allocas list so that it is processed in insertSpills.

0 commit comments

Comments
 (0)