Extend coroutines to support a "returned continuation" lowering.
authorJohn McCall <rjmccall@apple.com>
Wed, 14 Aug 2019 03:53:17 +0000 (03:53 +0000)
committerJohn McCall <rjmccall@apple.com>
Wed, 14 Aug 2019 03:53:17 +0000 (03:53 +0000)
commit94010b2b7f47de78f4d0ec9be7eb8414747dfd39
tree54e7f90d1bb7dfb6b08f855966eddca20cfde014
parentdbb757f462054ff9e06a46ce72135843e42f960b
Extend coroutines to support a "returned continuation" lowering.

A quick contrast of this ABI with the currently-implemented ABI:

- Allocation is implicitly managed by the lowering passes, which is fine
  for frontends that are fine with assuming that allocation cannot fail.
  This assumption is necessary to implement dynamic allocas anyway.

- The lowering attempts to fit the coroutine frame into an opaque,
  statically-sized buffer before falling back on allocation; the same
  buffer must be provided to every resume point.  A buffer must be at
  least pointer-sized.

- The resume and destroy functions have been combined; the continuation
  function takes a parameter indicating whether it has succeeded.

- Conversely, every suspend point begins its own continuation function.

- The continuation function pointer is directly returned to the caller
  instead of being stored in the frame.  The continuation can therefore
  directly destroy the frame when exiting the coroutine instead of having
  to leave it in a defunct state.

- Other values can be returned directly to the caller instead of going
  through a promise allocation.  The frontend provides a "prototype"
  function declaration from which the type, calling convention, and
  attributes of the continuation functions are taken.

- On the caller side, the frontend can generate natural IR that directly
  uses the continuation functions as long as it prevents IPO with the
  coroutine until lowering has happened.  In combination with the point
  above, the frontend is almost totally in charge of the ABI of the
  coroutine.

- Unique-yield coroutines are given some special treatment.

llvm-svn: 368788
14 files changed:
llvm/docs/Coroutines.rst
llvm/include/llvm/IR/Intrinsics.td
llvm/lib/Transforms/Coroutines/CoroCleanup.cpp
llvm/lib/Transforms/Coroutines/CoroEarly.cpp
llvm/lib/Transforms/Coroutines/CoroFrame.cpp
llvm/lib/Transforms/Coroutines/CoroInstr.h
llvm/lib/Transforms/Coroutines/CoroInternal.h
llvm/lib/Transforms/Coroutines/CoroSplit.cpp
llvm/lib/Transforms/Coroutines/Coroutines.cpp
llvm/test/Transforms/Coroutines/coro-debug.ll
llvm/test/Transforms/Coroutines/coro-retcon-once-value.ll [new file with mode: 0644]
llvm/test/Transforms/Coroutines/coro-retcon-once-value2.ll [new file with mode: 0644]
llvm/test/Transforms/Coroutines/coro-retcon-value.ll [new file with mode: 0644]
llvm/test/Transforms/Coroutines/coro-retcon.ll [new file with mode: 0644]