Thanks for doing this. I'm not qualified to review the patch properly,
but was just curious...
Andi Kleen writes:
> This patch implements a clang compatible [[musttail]] attribute for
> returns.
>
> musttail is useful as an alternative to computed goto for interpreters.
> With computed goto the interpreter function usually ends up very big
> which causes problems with register allocation and other per function
> optimizations not scaling. With musttail the interpreter can be instead
> written as a sequence of smaller functions that call each other. To
> avoid unbounded stack growth this requires forcing a sibling call, which
> this attribute does. It guarantees an error if the call cannot be tail
> called which allows the programmer to fix it instead of risking a stack
> overflow. Unlike computed goto it is also type-safe.
>
> It turns out that David Malcolm had already implemented middle/backend
> support for a musttail attribute back in 2016, but it wasn't exposed
> to any frontend other than a special plugin.
>
> This patch adds a [[gnu::musttail]] attribute for C++ that can be added
> to return statements. The return statement must be a direct call
> (it does not follow dependencies), which is similar to what clang
> implements. It then uses the existing must tail infrastructure.
>
> For compatibility it also detects clang::musttail
>
> One problem is that tree-tailcall usually fails when optimization
> is disabled, which implies the attribute only really works with
> optimization on. But that seems to be a reasonable limitation.
>
> The attribute is only supported for C++, since the C-parser
> has no support for statement attributes for non empty statements.
> It could be added there with __attribute__ too but would need
> some minor grammar adjustments.
>
> Passes bootstrap and full test
> ---
> gcc/c-family/c-attribs.cc | 25 +
> gcc/cp/cp-tree.h | 4 ++--
> gcc/cp/parser.cc | 28 +++-
> gcc/cp/semantics.cc | 6 +++---
> gcc/cp/typeck.cc | 20 ++--
> 5 files changed, 71 insertions(+), 12 deletions(-)
>
> diff --git a/gcc/c-family/c-attribs.cc b/gcc/c-family/c-attribs.cc
> index 40a0cf90295d..f31c62e76665 100644
> --- a/gcc/c-family/c-attribs.cc
> +++ b/gcc/c-family/c-attribs.cc
> @@ -54,6 +54,7 @@ static tree handle_nocommon_attribute (tree *, tree, tree,
> int, bool *);
> static tree handle_common_attribute (tree *, tree, tree, int, bool *);
> static tree handle_hot_attribute (tree *, tree, tree, int, bool *);
> static tree handle_cold_attribute (tree *, tree, tree, int, bool *);
> +static tree handle_musttail_attribute (tree *, tree, tree, int, bool *);
> static tree handle_no_sanitize_attribute (tree *, tree, tree, int, bool *);
> static tree handle_no_sanitize_address_attribute (tree *, tree, tree,
> int, bool *);
> @@ -499,6 +500,8 @@ const struct attribute_spec c_common_gnu_attributes[] =
>{ "hot", 0, 0, false, false, false, false,
> handle_hot_attribute,
> attr_cold_hot_exclusions },
> + { "musttail",0, 0, false, false, false, false,
> + handle_musttail_attribute, NULL },
>{ "no_address_safety_analysis",
> 0, 0, true, false, false, false,
> handle_no_address_safety_analysis_attribute,
> @@ -1290,6 +1293,28 @@ handle_hot_attribute (tree *node, tree name, tree
> ARG_UNUSED (args),
>return NULL_TREE;
> }
>
> +/* Handle a "musttail" and attribute; arguments as in
> + struct attribute_spec.handler. */
> +
> +static tree
> +handle_musttail_attribute (tree *node, tree name, tree ARG_UNUSED (args),
> +int ARG_UNUSED (flags), bool *no_add_attrs)
> +{
> + if (TREE_CODE (*node) == FUNCTION_DECL
> + || TREE_CODE (*node) == LABEL_DECL)
> +{
> + /* Attribute musttail processing is done later with lookup_attribute.
> */
> +}
> + else
> +{
> + warning (OPT_Wattributes, "%qE attribute ignored", name);
> + *no_add_attrs = true;
> +}
> +
> + return NULL_TREE;
> +}
> +
> +
...are the three hunks above needed? The reason for asking is that,
if they were needed, I'd have expected that we'd also need a table
entry for clang::musttail (which is possible to add). But trying it
locally, the patch seemed to work without this.
Also, including the table entry and accepting FUNCTION_DECL means that:
[[gnu::musttail]] void f();
[[gnu::musttail]] void g() { return f(); }
is silently accepted but seems to have no effect.
Thanks,
Richard
> /* Handle a "cold" and attribute; arguments as in
> struct attribute_spec.handler. */
>
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 60e6dafc5494..bed52e860a00 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -7763,7 +7763,7 @@ extern void