C++ Coroutines

This page describes the GCC implementation state for the C++ coroutines TS.

The objective of this work is to provide an implementation of the coroutines facility as accepted into the C++20 working draft.

Coroutines are part of C++ 20 and implemented in GCC 10. Much of this page describes the moving target and status during development.

Implementation State

Development branch: 'c++-coroutines' (svn://gcc.gnu.org/svn/gcc/branches/c++-coroutines). Reporting bugs

The branch was created, by Iain Sandoe, Sept 2018

The specification is fairly stable now [IS for C++20] as is the design. However, the implementation is ongoing and at a given time an area you might be interested could be unimplemented or incomplete/fragile.

Notable events:

Invoking the Compiler

g++ -fcoroutines

Bugs

Bugs should be reported by the usual mechanism.

Design

Interoperation goals

Design Outline

The design is split along three lines (the implementation is in the C++ front end and the tree passes in the middle end):

  1. Process the IS requirements for semantic content in the Front End retaining library builtins, but lowering control flow to a "IFN_CO_YIELD()" which wraps the suspend / resume deferring the split until a later lowering. The intention here is that we present the middle end with mostly unspecialized code, and that the placement of EH edges can be done by the "normal" front end code. One difference from other implementations is that we outline the "ramp" function early so that GCC's ME incliners can get a good view of its size in the analysis phases that precede LTO.
  2. Lower the builtins early in the ME pipeline (mostly trivial inspection of coroutine frame offsets)
  3. Re-write IFN_CO_YIELD, deferred to post-LTO (this was expected to produce the best opportunities for optimisation, but it's a CHECK-ME to compare pre and post). This rewrites the actor function so that the suspend/resume paths are distinct from the destruction ones, allowing the ME optimiser to inline the functionality separately and DCE the unused portions.
  4. Frame allocation, deferred to very late in the tree passes, so that the frame can be revised (with elimination of dead entries) or allocated in the caller's stack frame, should that be possible [NOTE: this is a future objective, not part of the current work].
  5. Library support. This is a single header (there's no object code in the current designs, although future library additions are planned once the coroutines implementation is available).

Examples

Without an existing library header (currently unimplemented), the best place to look for examples of coroutines that are functional with the on-going implementation is in the testsuite.

For general testcases (e.g. of syntax or error reporting) the examples are found in svn://gcc.gnu.org/svn/gcc/branches/c++-coroutines/gcc/testsuite/g++.dg/coroutines

For testcases that involve code generation that might be optimisation-level-sensitive, the examples are found in svn://gcc.gnu.org/svn/gcc/branches/c++-coroutines/gcc/testsuite/g++.dg/coroutines/torture (a conventional name in GCC testing to indicate that a test is exercised for a number of different optimisations and with LTO etc.)

Once the library header is implemented and installs with libstdc++, it will be feasible to add some small examples here.

Timeline

Documentation

None: cxx-coroutines (last edited 2021-08-18 18:13:42 by NathanSidwell)