Index: gcc/c-common.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-common.c,v retrieving revision 1.465 diff -u -u -r1.465 c-common.c --- gcc/c-common.c 20 Oct 2003 22:03:32 -0000 1.465 +++ gcc/c-common.c 27 Oct 2003 15:29:30 -0000 @@ -762,6 +762,7 @@ static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_always_inline_attribute (tree *, tree, tree, int, bool *); +static tree handle_leafify_attribute (tree *, tree, tree, int, bool *); static tree handle_used_attribute (tree *, tree, tree, int, bool *); static tree handle_unused_attribute (tree *, tree, tree, int, bool *); static tree handle_const_attribute (tree *, tree, tree, int, bool *); @@ -824,6 +825,8 @@ handle_noinline_attribute }, { "always_inline", 0, 0, true, false, false, handle_always_inline_attribute }, + { "leafify", 0, 0, true, false, false, + handle_leafify_attribute }, { "used", 0, 0, true, false, false, handle_used_attribute }, { "unused", 0, 0, false, false, false, @@ -4454,6 +4457,25 @@ /* Do nothing else, just set the attribute. We'll get at it later with lookup_attribute. */ } + else + { + warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); + *no_add_attrs = true; + } + + return NULL_TREE; +} + +/* Handle a "leafify" attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_leafify_attribute (tree *node, tree name, + tree args ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED, bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + DECL_UNINLINABLE (*node) = 1; else { warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name)); Index: gcc/cgraphunit.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cgraphunit.c,v retrieving revision 1.37 diff -u -u -r1.37 cgraphunit.c --- gcc/cgraphunit.c 22 Oct 2003 11:58:09 -0000 1.37 +++ gcc/cgraphunit.c 27 Oct 2003 15:29:31 -0000 @@ -1070,6 +1070,25 @@ free (heap_node); } +/* Go down the call tree marking nodes disregarding inlining limits. Called + * for function decls with attribute((leafify)) set. */ + +static void +cgraph_decide_inlining_leafify(struct cgraph_node *node) +{ + struct cgraph_edge *e; + if (node->aux) + return; + for (e = node->callees; e; e = e->next_callee) + { + if (!e->callee->local.inlinable) + continue; + e->callee->local.disregard_inline_limits = 1; + cgraph_decide_inlining_leafify(e->callee); + } + node->aux = node; +} + /* Decide on the inlining. We do so in the topological order to avoid expenses on updating datastructures. */ @@ -1099,6 +1118,20 @@ fprintf (cgraph_dump_file, "\nDeciding on inlining. Starting with %i insns.\n", initial_insns); + + for (node = cgraph_nodes; node; node = node->next) + node->aux = 0; + + /* Traverse all functions looking for attribute((leafify)) functions. + * Recursively mark their callees as disregarding their inline limits. + * FIXME: this does inline (wastly) more than requested. */ + for (i = nnodes - 1; i >= 0; i--) + { + node = order[i]; + if (!node->aux + && lookup_attribute ("leafify", DECL_ATTRIBUTES (node->decl)) != NULL) + cgraph_decide_inlining_leafify(node); + } for (node = cgraph_nodes; node; node = node->next) node->aux = 0; Index: gcc/doc/extend.texi =================================================================== RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v retrieving revision 1.169 diff -u -u -r1.169 extend.texi --- gcc/doc/extend.texi 26 Oct 2003 19:03:42 -0000 1.169 +++ gcc/doc/extend.texi 27 Oct 2003 15:29:40 -0000 @@ -1976,7 +1976,7 @@ attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently defined for functions on all targets: -@code{noreturn}, @code{noinline}, @code{always_inline}, +@code{noreturn}, @code{noinline}, @code{always_inline}, @code{leafify}, @code{pure}, @code{const}, @code{nothrow}, @code{format}, @code{format_arg}, @code{no_instrument_function}, @code{section}, @code{constructor}, @code{destructor}, @code{used}, @@ -2052,6 +2052,14 @@ Generally, functions are not inlined unless optimization is specified. For functions declared inline, this attribute inlines the function even if no optimization level was specified. + +@cindex @code{leafify} function attribute +@item leafify +Generally, inlining into a function is limited. For a function marked with +this attribute, every call inside this function will be inlined, if possible. +This attribute implies that the function itself is not considered for automatic +inlining, even into functions marked @code{leafify}. So this is the same +as marking the function @code{noinline} as well. @cindex @code{pure} function attribute @item pure