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