[all-commits] [llvm/llvm-project] 234cc8: [LLVM][Coroutines] Create `.noalloc` variant of sw...

Yuxuan Chen via All-commits all-commits at lists.llvm.org
Sun Sep 8 23:09:42 PDT 2024


  Branch: refs/heads/main
  Home:   https://github.com/llvm/llvm-project
  Commit: 234cc81625030e934651d6ae0ace66e37138ba4a
      https://github.com/llvm/llvm-project/commit/234cc81625030e934651d6ae0ace66e37138ba4a
  Author: Yuxuan Chen <ych at fb.com>
  Date:   2024-09-08 (Sun, 08 Sep 2024)

  Changed paths:
    M llvm/docs/Coroutines.rst
    M llvm/lib/Transforms/Coroutines/CoroInternal.h
    M llvm/lib/Transforms/Coroutines/CoroSplit.cpp
    M llvm/lib/Transforms/Coroutines/Coroutines.cpp
    M llvm/test/Transforms/Coroutines/coro-split-00.ll

  Log Message:
  -----------
  [LLVM][Coroutines] Create `.noalloc` variant of switch ABI coroutine ramp functions during CoroSplit (#99283)

This patch is episode two of the coroutine HALO improvement project
published on discourse:
https://discourse.llvm.org/t/language-extension-for-better-more-deterministic-halo-for-c-coroutines/80044

Previously CoroElide depends on inlining, and its analysis does not work
very well with code generated by the C++ frontend due the existence of
many customization points. There has been issue reported to upstream how
ineffective the original CoroElide was in real world applications.

For C++ users, this set of patches aim to fix this problem by providing
library authors and users deterministic HALO behaviour for some
well-behaved coroutine `Task` types. The stack begins with a library
side attribute on the `Task` class that guarantees no unstructured
concurrency when coroutines are awaited directly with `co_await`ed as a
prvalue. This attribute on Task types gives us lifetime guarantees and
makes C++ FE capable to telling the ME which coroutine calls are
elidable. We convey such information from FE through the attribute
`coro_elide_safe`.

This patch modifies CoroSplit to create a variant of the coroutine ramp
function that 1) does not use heap allocated frame, instead take an
additional parameter as the pointer to the frame. Such parameter is
attributed with `dereferenceble` and `align` to convey size and align
requirements for the frame. 2) always stores cleanup instead of destroy
address for `coro.destroy()` actions.

In a later patch, we will have a new pass that runs right after
CoroSplit to find usages of the callee coroutine attributed
`coro_elide_safe` in presplit coroutine callers, allocates the frame on
its "stack", transform those usages to call the `noalloc` ramp function
variant.

(note I put quotes on the word "stack" here, because for presplit
coroutine, any alloca will be spilled into the frame when it's being
split)

The C++ Frontend attribute implementation that works with this change
can be found at https://github.com/llvm/llvm-project/pull/99282
The pass that makes use of the new `noalloc` split can be found at
https://github.com/llvm/llvm-project/pull/99285



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