[PATCH] D101980: [RFC] [Coroutines] Put the contents of byval argument to the frame
Chuanqi Xu via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu May 6 01:08:27 PDT 2021
ChuanqiXu created this revision.
ChuanqiXu added reviewers: lxfind, rjmccall, junparser.
Herald added subscribers: rriddle, hiraditya.
ChuanqiXu requested review of this revision.
Herald added subscribers: llvm-commits, stephenneuendorffer.
Herald added a project: LLVM.
This patch solves bug 48857 <https://bugs.llvm.org/show_bug.cgi?id=48857>.
>From my perspective, the root cause for problem `bug 48857` is that the arguments marked with `byval` wouldn't be put to the frame actually. Consider the following example:
void foo() {
A a;
// Some works with a
coro_func(a);
// Other works with a
}
Every C++ programmer would believe there would be an copy for `a` in the frame of `coro_func`. From 9.5.4 of N4878, we can found:
When a coroutine is invoked, after initializing its parameters (7.6.1.3), a copy is created for each coroutine
parameter. For a parameter of type cv T, the copy is a variable of type cv T with automatic storage duration
that is direct-initialized from an xvalue of type T referring to the parameter.
However, there would be only a pointer to type `A` in the frame. The problems comes from that LLVM would copy the `byval` value in the caller site instead of callee site. In other words, the IR for the example above would be:
void foo() {
%a = Alloca A
// Some works with %a
%a.byval-temp = Alloca A
memcpy(%a.byval-temp, %a)
coro_func(%a.byval-temp);
// Other works with %a
}
The actual type for the argument of `coro_func` would be `A*` marked with `byval`.
This patch tries to solve this by copying the byval arguments in the callee site if the callee is a coroutine. Now the semantic looks more consistent with the standard of C++. And I believe it should be good for Swift and MLIR. However, the down side for this approach is the extra copy. It is normal that this would make us worry about the performance. It shows that we lack a benchmark for coroutine again. But now, I could only argue for that it wouldn't hurt the performance much since the extra copy happens after the previous one and it should hit the cache.
BTW, I tried to modify the front end to make the coroutine special again - if the callee is a coroutine, we should copy the byval argument in the callee side instead of caller side.
However, the frontend looks complex and we would make coroutine violates the principle of LLVM again.
Test-Plan: check-llvm, check-clang
https://reviews.llvm.org/D101980
Files:
llvm/lib/Transforms/Coroutines/CoroFrame.cpp
llvm/test/Transforms/Coroutines/coro-alloca-byval-param.ll
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D101980.343317.patch
Type: text/x-patch
Size: 4731 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210506/8d6ae7f2/attachment.bin>
More information about the llvm-commits
mailing list