attribute((leafify)) for 3.4
Richard Guenther
rguenth@tat.physik.uni-tuebingen.de
Mon Oct 27 16:50:00 GMT 2003
Hi!
I tried to move attribute((leafify)) from 3.3 to 3.4 (see attached patch).
I do this by marking nodes in the callgraph down from leafify functions as
disregarding their inlining limits (which results in them being treated as
always_inline functions). Unfortunately this doesnt really inline all of
the callees of a leaf function as the patch for 3.3 does.
Still this patch improves performance of generated code by 25% (compared
to the 3.4 value without leafify, 3.3 with leafify improves by 45%).
Any ideas how to improve the patch? Especially how to reduce "false"
forced inlining of nodes into non-leafify functions? I know we're in stage
3, so adding a new attribute is out of question, but I really like to have
this feature locally, and preferrably as good as the 3.3 version.
Thanks for suggestions,
Richard.
--
Richard Guenther <richard dot guenther at uni-tuebingen dot de>
WWW: http://www.tat.physik.uni-tuebingen.de/~rguenth/
-------------- next part --------------
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
More information about the Gcc
mailing list