[Bug c++/105989] Coroutine frame space for temporaries in a co_await expression is not reused
michal.jankovic59 at gmail dot com
gcc-bugzilla@gcc.gnu.org
Wed Jun 15 17:20:23 GMT 2022
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105989
--- Comment #2 from Michal Jankovič <michal.jankovic59 at gmail dot com> ---
Reading through gcc/cp/coroutines.cc, it seems like the coroutine frame is
indeed composed as a flat struct with fields for all the local variables,
temps, and special stuff needed by the actor.
Relevant code:
coro_make_frame_entry - adds a field to the coro_frame_type structure.
register_local_var_uses - here coro_make_frame_entry is called for each local
variable.
morph_fn_to_coro - here the coro_frame_type structure definition is created
from the collected fields.
Comments in the code state that the mid-end should be able to optimize out
unused fields from this struct, which currently does not happen, but even if it
did, this does not solve the overlapping of variables.
I think that instead of a flat struct, the frontend should generate a structure
recursively composed of unions of structures, having a union for each disjunct
scope (including an implicit scope for expression temporaries).
Example:
task task_1() {
{
char a[128];
co_await task_2();
}
{
char b[128];
co_await task_3(get_temporary());
static awaiter awaiter_not_stored_in_frame;
co_await awaiter_not_stored_in_frame;
}
}
Currently, this generates a coro frame struct that looks something like this:
struct coro_frame {
// builtin state ...
char a[128];
awaiter task_2_awaiter;
char b[128];
int get_temporary_result;
awaiter task_3_awaiter;
awaiter* awaiter_not_stored_in_frame;
};
Instead, the frontend could generate something like this:
struct coro_frame {
// builtin state ...
union {
struct {
char a[128];
awaiter task_2_awaiter;
};
struct {
char b[128];
union {
struct {
int get_temporary_result;
awaiter task_3_awaiter;
};
struct { awaiter* awaiter_not_stored_in_frame; };
};
};
};
};
More information about the Gcc-bugs
mailing list