summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIain Sandoe <iain@sandoe.co.uk>2020-04-16 14:17:51 +0100
committerIain Sandoe <iain@sandoe.co.uk>2020-04-16 21:28:14 +0100
commitd0ce5baeb642bab57252c687cdf0ffb522e7a2a3 (patch)
tree1ca88acb5496e62386de0fc3ef9a9d5f8cf8b053
parenttestsuite: Update pr94426-2 test to handle more targets [PR94426] (diff)
coroutines: Back out mandate for tail-calls at O < 2 [PR94359]
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.
-rw-r--r--gcc/cp/coroutines.cc16
-rw-r--r--gcc/testsuite/g++.dg/coroutines/symmetric-transfer-00-basic.C (renamed from gcc/testsuite/g++.dg/coroutines/torture/symmetric-transfer-00-basic.C)13
2 files changed, 8 insertions, 21 deletions
diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc
index e4ba642d527a..0a8e7521c4f8 100644
--- a/gcc/cp/coroutines.cc
+++ b/gcc/cp/coroutines.cc
@@ -2377,21 +2377,9 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
2377 (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr); 2377 (loc, builtin_decl_explicit (BUILT_IN_CORO_RESUME), 1, addr);
2378 2378
2379 /* In order to support an arbitrary number of coroutine continuations, 2379 /* In order to support an arbitrary number of coroutine continuations,
2380 we must tail call them. However, some targets might not support this 2380 we must tail call them. However, some targets do not support indirect
2381 for indirect calls, or calls between DSOs. 2381 tail calls to arbitrary callees. See PR94359. */
2382 FIXME: see if there's an alternate strategy for such targets. */
2383 /* Now we have the actual call, and we can mark it as a tail. */
2384 CALL_EXPR_TAILCALL (resume) = true; 2382 CALL_EXPR_TAILCALL (resume) = true;
2385 /* Temporarily, switch cfun so that we can use the target hook. */
2386 push_struct_function (actor);
2387 if (targetm.function_ok_for_sibcall (NULL_TREE, resume))
2388 {
2389 /* ... and for optimisation levels 0..1, which do not normally tail-
2390 -call, mark it as requiring a tail-call for correctness. */
2391 if (optimize < 2)
2392 CALL_EXPR_MUST_TAIL_CALL (resume) = true;
2393 }
2394 pop_cfun ();
2395 resume = coro_build_cvt_void_expr_stmt (resume, loc); 2383 resume = coro_build_cvt_void_expr_stmt (resume, loc);
2396 add_stmt (resume); 2384 add_stmt (resume);
2397 2385
diff --git a/gcc/testsuite/g++.dg/coroutines/torture/symmetric-transfer-00-basic.C b/gcc/testsuite/g++.dg/coroutines/symmetric-transfer-00-basic.C
index 6f379c8e77ae..b78ae20d9d48 100644
--- a/gcc/testsuite/g++.dg/coroutines/torture/symmetric-transfer-00-basic.C
+++ b/gcc/testsuite/g++.dg/coroutines/symmetric-transfer-00-basic.C
@@ -1,10 +1,9 @@
1// { dg-do run } 1// See PR94359, we will need either a general solution to this, or at least
2// See PR94359 - some targets are unable to make general indirect tailcalls 2// some hook for targets to opt in, for now the test will work on targets that
3// for example, between different DSOs. 3// can do the tailcall (which would normally be available for O2+)
4// { dg-xfail-run-if "" { hppa*-*-hpux11* } } 4
5// { dg-xfail-run-if "" { ia64-*-linux-gnu } } 5// { dg-do run { target { i?86-*-linux-gnu x86_64-*-linux-gnu *-*-darwin* } } }
6// { dg-xfail-run-if "" { { lp64 && { powerpc*-linux-gnu } } || { *-*-aix* } } } 6// { dg-additional-options "-O2" }
7// { dg-xfail-run-if "" { sparc*-*-* } }
8 7
9#if __has_include(<coroutine>) 8#if __has_include(<coroutine>)
10 9