[all-commits] [llvm/llvm-project] c46724: [C++20] [Coroutines] Mark await_suspend as noinlin...

Chuanqi Xu via All-commits all-commits at lists.llvm.org
Mon Aug 21 19:03:34 PDT 2023


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: c4672454743e942f148a1aff1e809dae73e464f6
      https://github.com/llvm/llvm-project/commit/c4672454743e942f148a1aff1e809dae73e464f6
  Author: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
  Date:   2023-08-22 (Tue, 22 Aug 2023)

  Changed paths:
    M clang/docs/ReleaseNotes.rst
    M clang/lib/CodeGen/CGCall.cpp
    M clang/lib/CodeGen/CGCoroutine.cpp
    M clang/lib/CodeGen/CodeGenFunction.h
    A clang/test/CodeGenCoroutines/coro-awaiter-noinline-suspend.cpp
    A clang/test/CodeGenCoroutines/pr56301.cpp

  Log Message:
  -----------
  [C++20] [Coroutines] Mark await_suspend as noinline if the awaiter is not empty

Close https://github.com/llvm/llvm-project/issues/56301
Close https://github.com/llvm/llvm-project/issues/64151

See the summary and the discussion of https://reviews.llvm.org/D157070
to get the full context.

As @rjmccall pointed out, the key point of the root cause is that
currently we didn't implement the semantics for '@llvm.coro.save' well
("after the await-ready returns false, the coroutine is considered to be
suspended ") well.
Since the semantics implies that we (the compiler) shouldn't write the
spills into the coroutine frame in the await_suspend. But now it is possible
due to some combinations of the optimizations so the semantics are
broken. And the inlining is the root optimization of such optimizations.
So in this patch, we tried to add the `noinline` attribute to the
await_suspend call.

Also as an optimization, we don't add the `noinline` attribute to the
await_suspend call if the awaiter is an empty class. This should be
correct since the programmers can't access the local variables in
await_suspend if the awaiter is empty. I think this is necessary for the
performance since it is pretty common.

Another potential optimization is:

    call @llvm.coro.await_suspend(ptr %awaiter, ptr %handle,
                                  ptr @awaitSuspendFn)

Then it is much easier to perform the safety analysis in the middle
end.
If it is safe to inline the call to awaitSuspend, we can replace it
in the CoroEarly pass. Otherwise we could replace it in the CoroSplit
pass.

Reviewed By: rjmccall

Differential Revision: https://reviews.llvm.org/D157833




More information about the All-commits mailing list