[all-commits] [llvm/llvm-project] f78688: [coroutine] Implement llvm.coro.await.suspend intr...
fpasserby via All-commits
all-commits at lists.llvm.org
Sun Mar 10 19:00:22 PDT 2024
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: f78688134026686288a8d310b493d9327753a022
https://github.com/llvm/llvm-project/commit/f78688134026686288a8d310b493d9327753a022
Author: fpasserby <125797601+fpasserby at users.noreply.github.com>
Date: 2024-03-11 (Mon, 11 Mar 2024)
Changed paths:
M clang/include/clang/AST/ExprCXX.h
M clang/lib/CodeGen/CGCoroutine.cpp
M clang/lib/CodeGen/CodeGenFunction.h
M clang/lib/Sema/SemaCoroutine.cpp
M clang/test/AST/coroutine-locals-cleanup.cpp
M clang/test/CodeGenCoroutines/coro-always-inline.cpp
M clang/test/CodeGenCoroutines/coro-await.cpp
R clang/test/CodeGenCoroutines/coro-awaiter-noinline-suspend.cpp
M clang/test/CodeGenCoroutines/coro-dwarf.cpp
M clang/test/CodeGenCoroutines/coro-function-try-block.cpp
M clang/test/CodeGenCoroutines/coro-symmetric-transfer-01.cpp
M clang/test/CodeGenCoroutines/coro-symmetric-transfer-02.cpp
M clang/test/CodeGenCoroutines/pr56329.cpp
M clang/test/CodeGenCoroutines/pr59181.cpp
M clang/test/CodeGenCoroutines/pr65054.cpp
M llvm/docs/Coroutines.rst
M llvm/include/llvm/IR/Intrinsics.td
M llvm/lib/IR/Verifier.cpp
M llvm/lib/Transforms/Coroutines/CoroInstr.h
M llvm/lib/Transforms/Coroutines/CoroInternal.h
M llvm/lib/Transforms/Coroutines/CoroSplit.cpp
M llvm/lib/Transforms/Coroutines/Coroutines.cpp
A llvm/test/Transforms/Coroutines/coro-await-suspend-lower-invoke.ll
A llvm/test/Transforms/Coroutines/coro-await-suspend-lower.ll
Log Message:
-----------
[coroutine] Implement llvm.coro.await.suspend intrinsic (#79712)
Implement `llvm.coro.await.suspend` intrinsics, to deal with performance
regression after prohibiting `.await_suspend` inlining, as suggested in
#64945.
Actually, there are three new intrinsics, which directly correspond to
each of three forms of `await_suspend`:
```
void llvm.coro.await.suspend.void(ptr %awaiter, ptr %frame, ptr @wrapperFunction)
i1 llvm.coro.await.suspend.bool(ptr %awaiter, ptr %frame, ptr @wrapperFunction)
ptr llvm.coro.await.suspend.handle(ptr %awaiter, ptr %frame, ptr @wrapperFunction)
```
There are three different versions instead of one, because in `bool`
case it's result is used for resuming via a branch, and in
`coroutine_handle` case exceptions from `await_suspend` are handled in
the coroutine, and exceptions from the subsequent `.resume()` are
propagated to the caller.
Await-suspend block is simplified down to intrinsic calls only, for
example for symmetric transfer:
```
%id = call token @llvm.coro.save(ptr null)
%handle = call ptr @llvm.coro.await.suspend.handle(ptr %awaiter, ptr %frame, ptr @wrapperFunction)
call void @llvm.coro.resume(%handle)
%result = call i8 @llvm.coro.suspend(token %id, i1 false)
switch i8 %result, ...
```
All await-suspend logic is moved out into a wrapper function, generated
for each suspension point.
The signature of the function is `<type> wrapperFunction(ptr %awaiter,
ptr %frame)` where `<type>` is one of `void` `i1` or `ptr`, depending on
the return type of `await_suspend`.
Intrinsic calls are lowered during `CoroSplit` pass, right after the
split.
Because I'm new to LLVM, I'm not sure if the helper function generation,
calls to them and lowering are implemented in the right way, especially
with regard to various metadata and attributes, i. e. for TBAA. All
things that seemed questionable are marked with `FIXME` comments.
There is another detail: in case of symmetric transfer raw pointer to
the frame of coroutine, that should be resumed, is returned from the
helper function and a direct call to `@llvm.coro.resume` is generated.
C++ standard demands, that `.resume()` method is evaluated. Not sure how
important is this, because code has been generated in the same way
before, sans helper function.
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list