On 8/21/24 3:09 PM, Iain Sandoe wrote:
This change is preparation for fixes to the ramp and codegen to follow.
The primary motivation is that we have thee activities; analysis, ramp
synthesis and outlined coroutine body synthesis. These are currently
carried out in sequence in the 'morph_fn_to_coro' code, which means that
we are nesting the synthesis of the outlined coroutine body inside the
finish_function call for the original function (which becomes the ramp).
The revised code splits the three interests so that the analysis can be
used independently by the ramp and body synthesis. This avoids some issues
seen with global state that start/finish function use and allows us to
use more of the high-level APIs in fixing bugs.
The resultant implementation is more self-contained, and has less impact
on finish_function.
gcc/cp/ChangeLog:
* coroutines.cc (struct suspend_point_info, struct param_info,
struct local_var_info, struct susp_frame_data,
struct local_vars_frame_data): Move to coroutines.h.
(build_actor_fn): Use start/finish function APIs.
(build_destroy_fn): Likewise.
(coro_build_actor_or_destroy_function): No longer mark the
actor / destroyer as DECL_COROUTINE_P.
(coro_rewrite_function_body): Use class members.
(cp_coroutine_transform::wrap_original_function_body): Likewise.
(build_ramp_function): Replace by...
(cp_coroutine_transform::complete_ramp_function): ...this.
(cp_coroutine_transform::cp_coroutine_transform): New.
(cp_coroutine_transform::~cp_coroutine_transform): New
(morph_fn_to_coro): Replace by...
(cp_coroutine_transform::apply_transforms): ...this.
(cp_coroutine_transform::finish_transforms): New.
* cp-tree.h (morph_fn_to_coro): Remove.
* decl.cc (emit_coro_helper): Remove.
(finish_function): Revise handling of coroutine transforms.
* coroutines.h: New file.
@@ -2309,12 +2270,10 @@ build_actor_fn (location_t loc, tree coro_frame_type,
tree actor, tree fnbody,
/* One param, the coro frame pointer. */
tree actor_fp = DECL_ARGUMENTS (actor);
+ bool spf = start_preparsed_function (actor, NULL_TREE, SF_PRE_PARSED);
+ gcc_checking_assert (spf);
+ gcc_checking_assert (cfun && current_function_decl && TREE_STATIC (actor));
+ tree stmt = begin_function_body ();
As in the last patch, "stmt" seems an obscure name for the result of
begin_function_body.
+void
+cp_coroutine_transform::wrap_original_function_body ()
{
+ /* Avoid the code here attaching a location that makes the debugger jump. */
+ location_t save_input_loc = input_location;
+ location_t loc = UNKNOWN_LOCATION;
+ input_location = loc;
Maybe use iloc_sentinel? It's a bit awkward because it won't set
UNKNOWN_LOCATION, but avoids needing to restore it at the end of the
function.
@@ -4425,7 +4345,7 @@ coro_rewrite_function_body (location_t fn_start, tree
fnbody, tree orig,
/* Add the initial await to the start of the user-authored function. */
finish_expr_stmt (initial_await);
/* Append the original function body. */
- add_stmt (fnbody);
+ add_stmt (coroutine_body);
if (return_void)
add_stmt (return_void);
Incidentally, if return_void is false, I wonder if you want something
like cp_maybe_instrument_return? Not in this patch, certainly.
+ if (coroutine && coroutine->cp_valid_coroutine())
You have a few cases of a missing space after cp_valid_coroutine.
Jason