This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
__attribute__((leafify)) for mainline
- From: Richard Guenther <rguenth at tat dot physik dot uni-tuebingen dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 19 May 2003 21:04:06 +0200 (CEST)
- Subject: __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