This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

__attribute__((leafify)) for mainline


Hi!

Here is the __attribute__((inline_everything)) patch renamed to leafify
and adapted to mainline.

Richard.

Index: gcc/c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.416
diff -u -u -r1.416 c-common.c
--- gcc/c-common.c	17 May 2003 20:29:28 -0000	1.416
+++ gcc/c-common.c	19 May 2003 18:57:20 -0000
@@ -745,6 +745,8 @@
 						 bool *));
 static tree handle_always_inline_attribute PARAMS ((tree *, tree, tree, int,
 						    bool *));
+static tree handle_leafify_attribute PARAMS ((tree *, tree, tree, int,
+						        bool *));
 static tree handle_used_attribute	PARAMS ((tree *, tree, tree, int,
 						 bool *));
 static tree handle_unused_attribute	PARAMS ((tree *, tree, tree, int,
@@ -820,6 +822,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,
@@ -4935,6 +4939,28 @@
       /* 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 (node, name, args, flags, no_add_attrs)
+     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/tree-inline.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v
retrieving revision 1.58
diff -u -u -r1.58 tree-inline.c
--- gcc/tree-inline.c	3 May 2003 13:28:33 -0000	1.58
+++ gcc/tree-inline.c	19 May 2003 18:57:20 -0000
@@ -54,6 +54,7 @@
    candidates.  */

 int flag_inline_trees = 0;
+int leafify = 0;

 /* To Do:

@@ -951,7 +952,9 @@

   /* If we've already decided this function shouldn't be inlined,
      there's no need to check again.  */
-  if (DECL_UNINLINABLE (fn))
+  if ((! leafify
+       || lookup_attribute ("noinline", DECL_ATTRIBUTES (fn)) != NULL)
+      && DECL_UNINLINABLE (fn))
     return 0;

   /* Assume it is not inlinable.  */
@@ -975,7 +978,7 @@
      front-end that must set DECL_INLINE in this case, because
      dwarf2out loses if a function is inlined that doesn't have
      DECL_INLINE set.  */
-  else if (! DECL_INLINE (fn) && !nolimit)
+  else if (! leafify && ! DECL_INLINE (fn) && ! nolimit)
     ;
 #ifdef INLINER_FOR_JAVA
   /* Synchronized methods can't be inlined.  This is a bug.  */
@@ -985,7 +988,7 @@
   /* We can't inline functions that are too big.  Only allow a single
      function to be of MAX_INLINE_INSNS_SINGLE size.  Make special
      allowance for extern inline functions, though.  */
-  else if (!nolimit
+  else if (! leafify && ! nolimit
 	   && ! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
 	   && currfn_insns > max_inline_insns_single)
     ;
@@ -1012,26 +1015,25 @@
     inlinable = 1;

   /* Squirrel away the result so that we don't have to check again.  */
-  DECL_UNINLINABLE (fn) = ! inlinable;
+  if (! leafify)
+    DECL_UNINLINABLE (fn) = ! inlinable;
+
+  /* Early exit.  */
+  if (! inlinable)
+    return 0;

   /* In case we don't disregard the inlining limits and we basically
      can inline this function, investigate further.  */
-  if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
-      && inlinable && !nolimit)
+  if (! leafify && ! nolimit
+      && ! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn))
     {
       int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT
 		     + currfn_insns;
-      /* In the extreme case that we have exceeded the recursive inlining
-         limit by a huge factor (128), we just say no. Should not happen
-         in real life.  */
-      if (sum_insns > MAX_INLINE_INSNS * 128)
-	 inlinable = 0;
-      /* If we did not hit the extreme limit, we use a linear function
-         with slope -1/MAX_INLINE_SLOPE to exceedingly decrease the
-         allowable size. We always allow a size of MIN_INLINE_INSNS
-         though.  */
-      else if ((sum_insns > MAX_INLINE_INSNS)
-	       && (currfn_insns > MIN_INLINE_INSNS))
+      /* We use a linear function with slope -1/MAX_INLINE_SLOPE to
+         exceedingly decrease the allowable size.
+         We always allow a size of MIN_INLINE_INSNS though.  */
+      if ((sum_insns > MAX_INLINE_INSNS)
+	  && (currfn_insns > MIN_INLINE_INSNS))
 	{
 	  int max_curr = MAX_INLINE_INSNS_SINGLE
 			- (sum_insns - MAX_INLINE_INSNS) / MAX_INLINE_SLOPE;
@@ -1040,16 +1042,16 @@
 	}
     }

-  if (inlinable && (*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn))
-    inlinable = 0;
+  /* Check again.  */
+  if (! inlinable)
+    return 0;
+
+  if ((*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn))
+    return 0;

   /* If we don't have the function body available, we can't inline
      it.  */
   if (! DECL_SAVED_TREE (fn))
-    inlinable = 0;
-
-  /* Check again, language hooks may have modified it.  */
-  if (! inlinable || DECL_UNINLINABLE (fn))
     return 0;

   /* Don't do recursive inlining, either.  We don't record this in
@@ -1183,7 +1185,7 @@
        || !cgraph_global_info (fn)->inline_once)
       && !inlinable_function_p (fn, id, 0))
     {
-      if (warn_inline && DECL_INLINE (fn))
+      if (warn_inline && (DECL_INLINE (fn) || leafify))
 	{
 	  warning_with_decl (fn, "inlining failed in call to `%s'");
 	  warning ("called from here");
@@ -1493,11 +1495,17 @@
      real inlining is represented in ID.FNS.  */
   id.first_inlined_fn = VARRAY_ACTIVE_SIZE (id.fns);

+  if (lookup_attribute ("leafify", DECL_ATTRIBUTES (fn)) != NULL)
+    leafify++;
+
   /* Replace all calls to inline functions with the bodies of those
      functions.  */
   id.tree_pruner = htab_create (37, htab_hash_pointer,
 				htab_eq_pointer, NULL);
   expand_calls_inline (&DECL_SAVED_TREE (fn), &id);
+
+  if (lookup_attribute ("leafify", DECL_ATTRIBUTES (fn)) != NULL)
+    leafify--;

   /* Clean up.  */
   htab_delete (id.tree_pruner);
Index: gcc/tree-inline.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/tree-inline.h,v
retrieving revision 1.6
diff -u -u -r1.6 tree-inline.h
--- gcc/tree-inline.h	13 Mar 2003 03:51:01 -0000	1.6
+++ gcc/tree-inline.h	19 May 2003 18:57:20 -0000
@@ -38,5 +38,6 @@
    candidates.  */

 extern int flag_inline_trees;
+extern int leafify;

 #endif /* GCC_TREE_INLINE_H */
Index: gcc/doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.138
diff -u -u -r1.138 extend.texi
--- gcc/doc/extend.texi	5 May 2003 23:12:37 -0000	1.138
+++ gcc/doc/extend.texi	19 May 2003 18:57:22 -0000
@@ -1955,7 +1955,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},
@@ -2027,6 +2027,15 @@
 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 but into functions marked @code{leafify}. To avoid even
+the latter you need to mark the function with the @code{noinline} attribute,
+so the function will never be inlined.

 @cindex @code{pure} function attribute
 @item pure


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]