--- gcc/tree.h.orig Tue Apr 23 20:53:14 2002 +++ gcc/tree.h Wed Apr 24 11:20:33 2002 @@ -1611,6 +1611,10 @@ where it is called. */ #define DECL_INLINE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inline_flag) +/* Nonzero in a FUNCTION_DECL means this function has been found inlinable + only by virtue of -finline-functions */ +#define DID_INLINE_FUNC(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inlined_function_flag) + /* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */ #define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable) @@ -1792,7 +1796,8 @@ unsigned non_addressable : 1; unsigned user_align : 1; unsigned uninlinable : 1; - /* Three unused bits. */ + unsigned inlined_function_flag : 1; + /* Two unused bits. */ unsigned lang_flag_0 : 1; unsigned lang_flag_1 : 1; --- gcc/tree-inline.c.orig Wed Apr 24 11:43:12 2002 +++ gcc/tree-inline.c Wed Apr 24 11:38:12 2002 @@ -668,12 +668,19 @@ inline_data *id; { int inlinable; + int max_inline_insns = MAX_INLINE_INSNS; /* If we've already decided this function shouldn't be inlined, there's no need to check again. */ if (DECL_UNINLINABLE (fn)) return 0; + /* We may here either because fn is declared inline or because + we use -finline-functions. For the second case, we are more + restricitve. */ + if (DID_INLINE_FUNC (fn)) + max_inline_insns /= 2; + /* Assume it is not inlinable. */ inlinable = 0; @@ -692,7 +699,7 @@ function to eat up half of our budget. Make special allowance for extern inline functions, though. */ else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn) - && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 2) + && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > max_inline_insns / 2) ; /* All is well. We can inline this function. Traditionally, GCC has refused to inline functions using alloca, or functions whose @@ -724,7 +731,7 @@ && DECL_NUM_STMTS (fn) > 13) { /* Use a linear function with a slope of -0.03125 we could also use an int approx. of sqrt or similar things */ - signed int max_curr = MAX_INLINE_INSNS/2 + signed int max_curr = max_inline_insns/2 - (( DECL_NUM_STMTS (fn) + (id ? id->inlined_stmts : 0)) * INSNS_PER_STMT - MAX_INLINE_INSNS) / 32; --- gcc/toplev.c.orig Tue Apr 23 20:53:12 2002 +++ gcc/toplev.c Wed Apr 24 11:26:16 2002 @@ -2400,6 +2400,7 @@ || flag_inline_functions) { timevar_push (TV_INTEGRATION); + current_function_is_leaf = leaf_function_p (); lose = function_cannot_inline_p (decl); timevar_pop (TV_INTEGRATION); if (lose || ! optimize) @@ -2416,12 +2417,16 @@ goto exit_rest_of_compilation; } } - else - /* ??? Note that this has the effect of making it look - like "inline" was specified for a function if we choose - to inline it. This isn't quite right, but it's - probably not worth the trouble to fix. */ + else { + /* ??? Note that we used to just make it look like if + the "inline" keyword was specified when we decide + to inline it (because of -finline-functions). + garloff@suse.de, 2002-04-24: Add another flag to + actually record this piece of information. */ + if (! DECL_INLINE (decl)) + DID_INLINE_FUNC (decl) = 1; inlinable = DECL_INLINE (decl) = 1; + } } insns = get_insns (); --- gcc/integrate.c.orig Tue Apr 16 15:34:20 2002 +++ gcc/integrate.c Wed Apr 24 11:29:25 2002 @@ -61,8 +61,8 @@ all. Assume 1 instruction for the call and 1.5 insns per argument. */ #define INTEGRATE_THRESHOLD(DECL) \ (optimize_size \ - ? (1 + (3 * list_length (DECL_ARGUMENTS (DECL))) / 2) \ - : (8 * (8 + list_length (DECL_ARGUMENTS (DECL))))) + ? ( 3 + (4 * list_length (DECL_ARGUMENTS (DECL))) / 2) \ + : (64 + (8 * list_length (DECL_ARGUMENTS (DECL))))) #endif @@ -173,7 +173,7 @@ MAX_INLINE_INSNS (-finline-limit-). For regular functions use the limit given by INTEGRATE_THRESHOLD. */ - int max_insns = (DECL_INLINE (fndecl)) + int max_insns = (DECL_INLINE (fndecl) && !(DID_INLINE_FUNC (fndecl))) ? (MAX_INLINE_INSNS + 8 * list_length (DECL_ARGUMENTS (fndecl))) : INTEGRATE_THRESHOLD (fndecl); @@ -208,6 +208,9 @@ if (current_function_cannot_inline) return current_function_cannot_inline; + if (current_function_is_leaf) + max_insns = (max_insns * 3) / 2; + /* If its not even close, don't even look. */ if (get_max_uid () > 3 * max_insns) return N_("function too large to be inline"); --- gcc/c-decl.c.orig Tue Apr 16 15:33:21 2002 +++ gcc/c-decl.c Wed Apr 24 11:45:47 2002 @@ -5151,6 +5151,8 @@ needed, and let dwarf2 know that the function is inlinable. */ else if (flag_inline_trees == 2 && initialized) { + if (!DECL_INLINE (decl)) + DID_INLINE_FUNC (decl) = 1; DECL_INLINE (decl) = 1; DECL_DECLARED_INLINE_P (decl) = 0; } --- gcc/cp/decl.c.orig Tue Apr 16 15:42:59 2002 +++ gcc/cp/decl.c Wed Apr 24 11:32:12 2002 @@ -9019,8 +9019,13 @@ DECL_DECLARED_INLINE_P (decl) = 1; /* We inline functions that are explicitly declared inline, or, when the user explicitly asks us to, all functions. */ - if (DECL_DECLARED_INLINE_P (decl) || flag_inline_trees == 2) + if (DECL_DECLARED_INLINE_P (decl)) DECL_INLINE (decl) = 1; + if (flag_inline_trees == 2) { + if (!DECL_INLINE (decl)) + DID_INLINE_FUNC (decl) = 1; + DECL_INLINE (decl) = 1; + } DECL_EXTERNAL (decl) = 1; if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) --- gcc/cp/optimize.c.orig Sun Dec 16 17:07:00 2001 +++ gcc/cp/optimize.c Wed Apr 24 11:39:24 2002 @@ -167,6 +167,7 @@ DECL_SOURCE_FILE (clone) = DECL_SOURCE_FILE (fn); DECL_SOURCE_LINE (clone) = DECL_SOURCE_LINE (fn); DECL_INLINE (clone) = DECL_INLINE (fn); + DID_INLINE_FUNC (clone) = DID_INLINE_FUNC (fn); DECL_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn); DECL_COMDAT (clone) = DECL_COMDAT (fn); DECL_WEAK (clone) = DECL_WEAK (fn); --- gcc/ChangeLog.orig Tue Apr 23 22:55:36 2002 +++ gcc/ChangeLog Wed Apr 24 12:07:23 2002 @@ -1,3 +1,22 @@ +2002-04-24 Kurt Garloff + + * toplev.c: (rest_of_compilation): Set current_function_is_leaf + flag for integrate.c. Set DID_INLINE_FUNC flag is we inline + just because of -finline-functions. + * integrate.c: (INTEGRATE_THRESHOLD): Better tune for -Os. + Don't use high MAX_INLINE_INSNS threshold for functions + inlined by -finline-functions. Give leaf functions an + inlining bonus. + * tree.h: (struct tree_decl): New flag inlined_function_flag + for functions inlined by -finline-functions. DID_INLINE_FUNC + accessor. + * tree-inline.c: (inlinable_function_p): Only allow half the + size for functions inlinable because of -finline-functions. + * c-decl.c: (grokdeclarator): Set DID_INLINE_FUNC flag. + * cp/decl.c: (grokfndecl): Likewise + * cp/optimize: (maybe_clone_body): Copy DID_INLINE_FUNC for + clones. + 2002-04-23 Kurt Garloff * tree-inline.c: Improve heuristics by using a smoother --- gcc/print-tree.c.orig Wed Apr 24 12:23:18 2002 +++ gcc/print-tree.c Wed Apr 24 12:12:55 2002 @@ -342,6 +342,8 @@ if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node)) fputs (" inline", file); + if (TREE_CODE (node) == FUNCTION_DECL && DID_INLINE_FUNC (node)) + fputs ("(opt)", file); if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node)) fputs (" built-in", file); if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN_NONANSI (node))