Iain Sandoe 6d85947d23 coroutines: Implement n4849 recommended symmetric transfer.
Although the note in the text [expr.await] / 5.1.1 is not normative,
it is asserted by users that an implementation that is unable to
perform unlimited symmetric transfers is not terribly useful.

This relates to the following circumstance:

try {
 users-function-body:
 {
    ....
    { some suspend context
      continuation_handle = await_suspend (another handle);
      continuation_handle.resume ();
      'return' (actually a suspension operation).
    }
  }
} catch (...) {}

The call to 'continuation_handle.resume ()' needs to be a tail-
call in order that an arbitrary number of coroutines can be handled
in this manner.  There are two issues with this:

1. That the user's function body is wrapped in a try/catch block and
   one cannot tail-call from within those.

2. That GCC doesn't usually produce tail-calls when the optimisation
   level is < O2.

After considerable discussion at WG21 meetings, it has been determined
that the intent is that the operation behaves as if the resume call is
executed in the context of the caller.

So, we can remap the fragment above like this:

{
  void_coroutine_handle continuation;

  try {
   users-function-body:
   {
      ....
      { some suspend context
        continuation = await_suspend (another handle);
        <scope exit without cleanup> symmetric_transfer;
      }
    }
  } catch (...) {}

symmetric_transfer:
  continuation.resume(); [tail call] [must tail call]
}

Thus we take the call outside the try-catch block which solves
issue (1) and mark it as a tail call and as "must tail call" for
correctness which solves (2).

As bonuses, since we no longer need to differentiate handle types
returned from await_suspend() methods, nor do we need to keep them
in the coroutine frame, since they are ephemeral, we save entries in
the frame and reduce some code too.

gcc/cp/ChangeLog:

2020-03-26  Iain Sandoe  <iain@sandoe.co.uk>

	* coroutines.cc (coro_init_identifiers): Initialize an identifier
	for the cororoutine handle 'address' method name.
	(struct coro_aw_data): Add fields to cover the continuations.
	(co_await_expander): Determine the kind of await_suspend in use.
	If we have the case that returns a continuation handle, then save
	this and make the target for 'scope exit without cleanup' be the
	continuation resume label.
	(expand_co_awaits): Remove.
	(struct suspend_point_info): Remove fields that kept the returned
	await_suspend handle type.
	(transform_await_expr): Remove code tracking continuation handles.
	(build_actor_fn): Add the continuation handle as an actor-function
	scope var.  Build the symmetric transfer continuation point. Call
	the tree walk for co_await expansion directly, rather than via a
	trivial shim function.
	(register_await_info): Remove fields tracking continuation handles.
	(get_await_suspend_return_type): Remove.
	(register_awaits): Remove code tracking continuation handles.
	(morph_fn_to_coro): Remove code tracking continuation handles.

gcc/testsuite/ChangeLog:

2020-03-26  Iain Sandoe  <iain@sandoe.co.uk>

	* g++.dg/coroutines/torture/co-ret-09-bool-await-susp.C: Amend
	to n4849 behaviour.
	* g++.dg/coroutines/torture/symmetric-transfer-00-basic.C: New
	test.
2020-03-26 21:01:13 +00:00
2020-03-24 11:40:10 +01:00

This directory contains the GNU Compiler Collection (GCC).

The GNU Compiler Collection is free software.  See the files whose
names start with COPYING for copying permission.  The manuals, and
some of the runtime libraries, are under different terms; see the
individual source files for details.

The directory INSTALL contains copies of the installation information
as HTML and plain text.  The source of this information is
gcc/doc/install.texi.  The installation information includes details
of what is included in the GCC sources and what files GCC installs.

See the file gcc/doc/gcc.texi (together with other files that it
includes) for usage and porting information.  An online readable
version of the manual is in the files gcc/doc/gcc.info*.

See http://gcc.gnu.org/bugs/ for how to report bugs usefully.

Copyright years on GCC source files may be listed using range
notation, e.g., 1987-2012, indicating that every year in the range,
inclusive, is a copyrightable year that could otherwise be listed
individually.
Description
No description provided
Readme 2.1 GiB
Languages
C++ 31.9%
C 31.3%
Ada 12%
D 6.5%
Go 6.4%
Other 11.5%