Skip to content

Commit 8a3acd8

Browse files
committed
c++, coroutines: Remove use of coroutine handle in the frame.
We have been keeping a copy of coroutine_handle<promise> in the state frame, as it was expected to be efficient to use this to initialize the argument to await_suspend. This does not turn out to be the case and intializing the value is obstructive to CGW2563 fixes. This removes the use. gcc/cp/ChangeLog: * coroutines.cc (struct coroutine_info): Update comments. (struct coro_aw_data): Remove self_handle and add in information to create the handle in lowering. (expand_one_await_expression): Build a temporary coroutine handle. (build_actor_fn): Remove reference to the frame copy of the coroutine handle. (cp_coroutine_transform::wrap_original_function_body): Remove reference to the frame copy of the coroutine handle. Signed-off-by: Iain Sandoe <[email protected]>
1 parent f577a9e commit 8a3acd8

File tree

1 file changed

+27
-35
lines changed

1 file changed

+27
-35
lines changed

gcc/cp/coroutines.cc

Lines changed: 27 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,10 @@ struct GTY((for_user)) coroutine_info
206206
tree traits_type; /* The cached traits type for this function. */
207207
tree handle_type; /* The cached coroutine handle for this function. */
208208
tree self_h_proxy; /* A handle instance that is used as the proxy for the
209-
one that will eventually be allocated in the coroutine
210-
frame. */
209+
one that will eventually be built in lowering. */
211210
tree promise_proxy; /* Likewise, a proxy promise instance. */
212-
tree from_address; /* handle_type from_address function. */
213-
tree return_void; /* The expression for p.return_void() if it exists. */
211+
tree from_address; /* handle_type from_address() function. */
212+
tree return_void; /* The expression for p.return_void(), if it exists. */
214213
location_t first_coro_keyword; /* The location of the keyword that made this
215214
function into a coroutine. */
216215

@@ -1982,12 +1981,13 @@ struct coro_aw_data
19821981
tree coro_fp; /* Frame pointer var. */
19831982
tree resume_idx; /* This is the index var in the frame. */
19841983
tree i_a_r_c; /* initial suspend await_resume() was called if true. */
1985-
tree self_h; /* This is a handle to the current coro (frame var). */
19861984
tree cleanup; /* This is where to go once we complete local destroy. */
19871985
tree cororet; /* This is where to go if we suspend. */
19881986
tree corocont; /* This is where to go if we continue. */
19891987
tree dispatch; /* This is where we go if we restart the dispatch. */
19901988
tree conthand; /* This is the handle for a continuation. */
1989+
tree handle_type; /* Handle type for this coroutine... */
1990+
tree hfa_m; /* ... and handle.from_address() for this. */
19911991
unsigned index; /* This is our current resume index. */
19921992
};
19931993

@@ -2105,6 +2105,18 @@ expand_one_await_expression (tree *expr, tree *await_expr, void *d)
21052105

21062106
tree suspend = TREE_VEC_ELT (awaiter_calls, 1); /* await_suspend(). */
21072107
tree susp_type = TREE_TYPE (suspend);
2108+
tree susp_call = suspend;
2109+
if (TREE_CODE (suspend) == TARGET_EXPR)
2110+
susp_call = TARGET_EXPR_INITIAL (suspend);
2111+
gcc_checking_assert (TREE_CODE (susp_call) == CALL_EXPR);
2112+
tree dummy_ch = build_dummy_object (data->handle_type);
2113+
r = fold_convert (build_pointer_type (void_type_node), data->coro_fp);
2114+
vec<tree, va_gc> *args = make_tree_vector_single (r);
2115+
tree hfa = cp_fold_rvalue (
2116+
build_new_method_call (dummy_ch, data->hfa_m, &args, NULL_TREE,
2117+
LOOKUP_NORMAL, NULL, tf_warning_or_error));
2118+
release_tree_vector (args);
2119+
CALL_EXPR_ARG (susp_call, call_expr_nargs (susp_call) - 1) = hfa;
21082120

21092121
bool is_cont = false;
21102122
/* NOTE: final suspend can't resume; the "resume" label in that case
@@ -2586,22 +2598,6 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
25862598
/* Now we start building the rewritten function body. */
25872599
add_stmt (build_stmt (loc, LABEL_EXPR, actor_begin_label));
25882600

2589-
/* actor's coroutine 'self handle'. */
2590-
tree ash = coro_build_frame_access_expr (actor_frame, coro_self_handle_id,
2591-
false, tf_warning_or_error);
2592-
/* So construct the self-handle from the frame address. */
2593-
tree hfa_m = get_coroutine_from_address (orig);
2594-
/* Should have been set earlier by coro_promise_type_found_p. */
2595-
gcc_assert (hfa_m);
2596-
2597-
tree r = build1 (CONVERT_EXPR, build_pointer_type (void_type_node), actor_fp);
2598-
vec<tree, va_gc> *args = make_tree_vector_single (r);
2599-
tree hfa = build_new_method_call (ash, hfa_m, &args, NULL_TREE, LOOKUP_NORMAL,
2600-
NULL, tf_warning_or_error);
2601-
r = cp_build_init_expr (ash, hfa);
2602-
finish_expr_stmt (r);
2603-
release_tree_vector (args);
2604-
26052601
/* Now we know the real promise, and enough about the frame layout to
26062602
decide where to put things. */
26072603

@@ -2616,7 +2612,7 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
26162612
add_stmt (fnbody);
26172613

26182614
/* Now do the tail of the function; first cleanups. */
2619-
r = build_stmt (loc, LABEL_EXPR, del_promise_label);
2615+
tree r = build_stmt (loc, LABEL_EXPR, del_promise_label);
26202616
add_stmt (r);
26212617

26222618
/* Destructors for the things we built explicitly.
@@ -2684,6 +2680,12 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
26842680
gcc_checking_assert (maybe_cleanup_point_expr_void (r) == r);
26852681
add_stmt (r);
26862682

2683+
/* How to construct the handle for this coroutine from the frame address. */
2684+
tree hfa_m = get_coroutine_from_address (orig);
2685+
/* Should have been set earlier by coro_promise_type_found_p. */
2686+
gcc_assert (hfa_m);
2687+
tree handle_type = TREE_TYPE (get_coroutine_self_handle_proxy (orig));
2688+
26872689
/* We've now rewritten the tree and added the initial and final
26882690
co_awaits. Now pass over the tree and expand the co_awaits. */
26892691
tree i_a_r_c = NULL_TREE;
@@ -2692,8 +2694,9 @@ build_actor_fn (location_t loc, tree coro_frame_type, tree actor, tree fnbody,
26922694
false, tf_warning_or_error);
26932695

26942696
coro_aw_data data = {actor, actor_fp, resume_idx_var, i_a_r_c,
2695-
ash, del_promise_label, ret_label,
2696-
continue_label, restart_dispatch_label, continuation, 2};
2697+
del_promise_label, ret_label,
2698+
continue_label, restart_dispatch_label, continuation,
2699+
handle_type, hfa_m, 2};
26972700
cp_walk_tree (&actor_body, await_statement_expander, &data, NULL);
26982701

26992702
BIND_EXPR_BODY (actor_bind) = pop_stmt_list (actor_body);
@@ -4424,16 +4427,6 @@ cp_coroutine_transform::wrap_original_function_body ()
44244427
var_list = promise;
44254428
add_decl_expr (promise);
44264429

4427-
/* We need a handle to this coroutine, which is passed to every
4428-
await_suspend(). This was created on demand when parsing we now link it
4429-
into our scope. */
4430-
var = get_coroutine_self_handle_proxy (orig_fn_decl);
4431-
DECL_CONTEXT (var) = orig_fn_decl;
4432-
DECL_SOURCE_LOCATION (var) = loc;
4433-
DECL_CHAIN (var) = var_list;
4434-
var_list = var;
4435-
add_decl_expr (var);
4436-
44374430
/* If we have function parms, then these will be copied to the coroutine
44384431
frame as per [dcl.fct.def.coroutine] / 13.
44394432
Here, we create a local (proxy) variable for each parm, since the original
@@ -5285,7 +5278,6 @@ cp_coroutine_transform::~cp_coroutine_transform ()
52855278
bool _Coro_frame_needs_free; free the coro frame mem if set.
52865279
bool _Coro_i_a_r_c; [dcl.fct.def.coroutine] / 5.3
52875280
short _Coro_resume_index;
5288-
handle_type _Coro_self_handle;
52895281
parameter copies (were required).
52905282
local variables saved (including awaitables)
52915283
(maybe) trailing space.

0 commit comments

Comments
 (0)