]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
coroutines: Back out mandate for tail-calls at O < 2 [PR94359]
authorIain Sandoe <iain@sandoe.co.uk>
Thu, 16 Apr 2020 13:17:51 +0000 (14:17 +0100)
committerIain Sandoe <iain@sandoe.co.uk>
Thu, 16 Apr 2020 20:28:14 +0000 (21:28 +0100)
For symmetric transfers to work with C++20 coroutines, it is
currently necessary to tail call the callee coroutine from resume
method of the caller coroutine.  However there are several targets
which don't support an indirect tail call to an arbitrary callee.

Unfortunately, the target 'function_ok_for_sibcall' is not usable
from the front end in all cases.  While it is possible to add a new
hook to cover this circumstance, it is too late in the release
cycle to be sure of getting the setting correct for all targets.

So, this patch backs out the use of function_ok_for_sibcall () and
the mandate of CALL_EXPR_MUST_TAIL_CALL from the symmetric
transfer.

Targets that can make indirect tail calls to arbitrary callees will
still be able to make use of the symmetric transfer (without risking
overrunning the stack) for optimization levels >= 2.

The draft standard does not mandate unlimited symmetric transfers,
so removing this is a QOI issue (albeit an important one) rather
than a correctness one.

The test is moved and adjusted so that it can be opted into by any
target that supports the necessary tailcall.

gcc/cp/ChangeLog:

2020-04-16  Iain Sandoe  <iain@sandoe.co.uk>

PR c++/94359
* coroutines.cc (build_actor_fn): Back out use of
targetm.function_ok_for_sibcall.  Do not mark the resume
call as CALL_EXPR_MUST_TAIL_CALL.

gcc/testsuite/ChangeLog:

2020-04-16  Iain Sandoe  <iain@sandoe.co.uk>

PR c++/94359
* g++.dg/coroutines/torture/symmetric-transfer-00-basic.C: Move..
* g++.dg/coroutines/symmetric-transfer-00-basic.C: ..here and
adjust to run at O2 for targets supporting the necessary tail
call.

gcc/cp/coroutines.cc
gcc/testsuite/g++.dg/coroutines/symmetric-transfer-00-basic.C [moved from gcc/testsuite/g++.dg/coroutines/torture/symmetric-transfer-00-basic.C with 87% similarity]

index e4ba642d527a0ba531dfff20a087ef244bbeb77f..0a8e7521c4f86d00610974dfcd890a9deefafd45 100644 (file)
@@ -2377,21 +2377,9 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
     (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr);
 
   /* In order to support an arbitrary number of coroutine continuations,
-     we must tail call them.  However, some targets might not support this
-     for indirect calls, or calls between DSOs.
-     FIXME: see if there's an alternate strategy for such targets.  */
-  /* Now we have the actual call, and we can mark it as a tail.  */
+     we must tail call them.  However, some targets do not support indirect
+     tail calls to arbitrary callees.  See PR94359.  */
   CALL_EXPR_TAILCALL (resume) = true;
-  /* Temporarily, switch cfun so that we can use the target hook.  */
-  push_struct_function (actor);
-  if (targetm.function_ok_for_sibcall (NULL_TREE, resume))
-    {
-      /* ... and for optimisation levels 0..1, which do not normally tail-
-       -call, mark it as requiring a tail-call for correctness.  */
-      if (optimize < 2)
-       CALL_EXPR_MUST_TAIL_CALL (resume) = true;
-    }
-  pop_cfun ();
   resume = coro_build_cvt_void_expr_stmt (resume, loc);
   add_stmt (resume);
 
similarity index 87%
rename from gcc/testsuite/g++.dg/coroutines/torture/symmetric-transfer-00-basic.C
rename to gcc/testsuite/g++.dg/coroutines/symmetric-transfer-00-basic.C
index 6f379c8e77ae0e18b769c4e1ae8e9cb551f24647..b78ae20d9d483b5339406a8545846adb7bef06d9 100644 (file)
@@ -1,10 +1,9 @@
-// { dg-do run }
-// See PR94359 - some targets are unable to make general indirect tailcalls
-// for example, between different DSOs.
-// { dg-xfail-run-if "" { hppa*-*-hpux11* } }
-// { dg-xfail-run-if "" { ia64-*-linux-gnu } }
-// { dg-xfail-run-if "" { { lp64 && { powerpc*-linux-gnu } } || { *-*-aix* } } }
-// { dg-xfail-run-if "" { sparc*-*-* } }
+// See PR94359, we will need either a general solution to this, or at least
+// some hook for targets to opt in, for now the test will work on targets that
+// can do the tailcall (which would normally be available for O2+)
+
+// { dg-do run { target { i?86-*-linux-gnu x86_64-*-linux-gnu *-*-darwin* } } }
+// { dg-additional-options "-O2" }
 
 #if __has_include(<coroutine>)