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]

[RFA] __attribute__((inline_everything)) [take 3]


Now the implementation is complete and has proved itself useful (for me).
Apart from the naming of the attribute (flat, flatten_callees, ?) I like
to know if such an attribute would be considered by one of the
maintainers. Patch is again against 3.3 branch.

Thanks,

Richard.

Changelog:
2003-05-15  Richard Guenther <richard.guenther@uni-tuebingen.de>
	* c-common.c (handle_inline_everything_attribute): New.
	tree-inline.c (optimize_inline_calls): Set inline_everything
        if function is marked __attribute__((inline_everything)).
        (inlinable_function_p): Honour inline_everything.
	tree-inline.h: Declare inline_everything flag.
	c-objc-common.c (c_cannot_inline_tree_fn): Honour
	inline_everything.
	cp/tree.c (cp_cannot_inline_tree_fn): Likewise.
	doc/extend.texi: Document inline_everything function attribute.

Patch:

Index: gcc/c-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-common.c,v
retrieving revision 1.393.2.3
diff -u -u -r1.393.2.3 c-common.c
--- gcc/c-common.c	9 Mar 2003 19:31:11 -0000	1.393.2.3
+++ gcc/c-common.c	14 May 2003 21:16:54 -0000
@@ -725,6 +725,8 @@
 						 bool *));
 static tree handle_always_inline_attribute PARAMS ((tree *, tree, tree, int,
 						    bool *));
+static tree handle_inline_everything_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,
@@ -812,6 +814,8 @@
 			      handle_noinline_attribute },
   { "always_inline",          0, 0, true,  false, false,
 			      handle_always_inline_attribute },
+  { "inline_everything",      0, 0, true,  false, false,
+			      handle_inline_everything_attribute },
   { "used",                   0, 0, true,  false, false,
 			      handle_used_attribute },
   { "unused",                 0, 0, false, false, false,
@@ -5387,6 +5391,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 "inline_everything" attribute; arguments as in
+   struct attribute_spec.handler.  */
+
+static tree
+handle_inline_everything_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.38.2.8
diff -u -u -r1.38.2.8 tree-inline.c
--- gcc/tree-inline.c	2 May 2003 19:52:01 -0000	1.38.2.8
+++ gcc/tree-inline.c	14 May 2003 21:16:56 -0000
@@ -51,6 +51,7 @@
    candidates.  */

 int flag_inline_trees = 0;
+int inline_everything = 0;

 /* To Do:

@@ -938,7 +939,9 @@

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

   /* Assume it is not inlinable.  */
@@ -962,7 +965,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))
+  else if (! inline_everything && ! DECL_INLINE (fn))
     ;
 #ifdef INLINER_FOR_JAVA
   /* Synchronized methods can't be inlined.  This is a bug.  */
@@ -972,8 +975,9 @@
   /* 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 (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
-	   && currfn_insns > max_inline_insns_single)
+  else if (! inline_everything
+	   && currfn_insns > max_inline_insns_single
+           && ! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn))
     ;
   /* We can't inline functions that call __builtin_longjmp at all.
      The non-local goto machenery really requires the destination
@@ -998,12 +1002,18 @@
     inlinable = 1;

   /* Squirrel away the result so that we don't have to check again.  */
-  DECL_UNINLINABLE (fn) = ! inlinable;
+  if (! inline_everything)
+    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)
+  if (! inline_everything
+      && inlinable
+      && ! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn))
     {
       int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT
 		     + currfn_insns;
@@ -1011,7 +1021,7 @@
          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;
+        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
@@ -1026,16 +1036,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
@@ -1171,7 +1181,7 @@
      inlining.  */
   if (!inlinable_function_p (fn, id))
     {
-      if (warn_inline && DECL_INLINE (fn))
+      if (warn_inline && (DECL_INLINE (fn) || inline_everything))
 	{
 	  warning_with_decl (fn, "inlining failed in call to `%s'");
 	  warning ("called from here");
@@ -1468,11 +1478,17 @@
      real inlining is represented in ID.FNS.  */
   id.first_inlined_fn = VARRAY_ACTIVE_SIZE (id.fns);

+  if (lookup_attribute ("inline_everything", DECL_ATTRIBUTES (fn)) != NULL)
+    inline_everything++;
+
   /* 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 ("inline_everything", DECL_ATTRIBUTES (fn)) != NULL)
+    inline_everything--;

   /* 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.4
diff -u -u -r1.4 tree-inline.h
--- gcc/tree-inline.h	31 May 2002 22:15:38 -0000	1.4
+++ gcc/tree-inline.h	14 May 2003 21:16:56 -0000
@@ -38,5 +38,6 @@
    candidates.  */

 extern int flag_inline_trees;
+extern int inline_everything;

 #endif /* GCC_TREE_INLINE_H */
Index: gcc/c-objc-common.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/c-objc-common.c,v
retrieving revision 1.18.4.1
diff -u -u -r1.18.4.1 c-objc-common.c
--- gcc/c-objc-common.c	2 May 2003 19:52:02 -0000	1.18.4.1
+++ gcc/c-objc-common.c	14 May 2003 21:16:57 -0000
@@ -164,6 +164,7 @@
   tree t;

   if (flag_really_no_inline
+      && ! inline_everything
       && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
     return 1;

Index: gcc/cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.307.2.3
diff -u -u -r1.307.2.3 tree.c
--- gcc/cp/tree.c	15 Apr 2003 00:35:53 -0000	1.307.2.3
+++ gcc/cp/tree.c	14 May 2003 21:16:59 -0000
@@ -2239,6 +2239,7 @@
   tree fn = *fnp;

   if (flag_really_no_inline
+      && ! inline_everything
       && lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
     return 1;

Index: gcc/doc/extend.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/extend.texi,v
retrieving revision 1.109.2.13
diff -u -u -r1.109.2.13 extend.texi
--- gcc/doc/extend.texi	30 Apr 2003 14:16:58 -0000	1.109.2.13
+++ gcc/doc/extend.texi	14 May 2003 21:17:16 -0000
@@ -1954,7 +1954,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{inline_everything},
 @code{pure}, @code{const}, @code{nothrow},
 @code{format}, @code{format_arg}, @code{no_instrument_function},
 @code{section}, @code{constructor}, @code{destructor}, @code{used},
@@ -2026,6 +2026,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{inline_everything} function attribute
+@item inline_everything
+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{inline_everything}. 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]