2002-10-23 Kurt Garloff * tree.h (struct tree_decl): Introduce inlined_function_flag, recording whether the function became eligible for inlining by a compiler flag rather than the declaration. Provide DID_INLINE_FUNC macro to access it. * c-decl.c (grokdeclarator): Set DID_INLINE_FUNC. * cp/decl.c (grokfndecl): Likewise. * toplev.c (rest_of_compilation): Likewise. * cp/optimize (maybe_clone_body): Copy DID_INLINE_FUNC. * print-tree.c (print_node): Report it. * params.def: Introduce new max-inline-insns-auto limit. * params.h: Likewise. * tree-inline.c (inlinable_function_p): Apply it to functions with DID_INLINE_FUNC set. * toplev.c (decode_f_option): Initialize it from -finline-limit value. * doc/invoke.texi: Document new parameter. diff -uNr gcc/gcc/c-decl.c gcc.autolim/gcc/c-decl.c --- gcc/gcc/c-decl.c Mon Feb 10 13:53:59 2003 +++ gcc.autolim/gcc/c-decl.c Fri Feb 28 12:16:05 2003 @@ -4550,6 +4550,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; } diff -uNr gcc/gcc/cp/decl.c gcc.autolim/gcc/cp/decl.c --- gcc/gcc/cp/decl.c Thu Feb 27 20:43:34 2003 +++ gcc.autolim/gcc/cp/decl.c Fri Feb 28 12:16:05 2003 @@ -9328,13 +9328,19 @@ DECL_NOT_REALLY_EXTERN (decl) = 1; } + DID_INLINE_FUNC (decl) = 0; /* If the declaration was declared inline, mark it as such. */ if (inlinep) 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 && !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) @@ -14736,6 +14742,7 @@ DECL_DECLARED_INLINE_P (fndecl) = 1; + DID_INLINE_FUNC (fndecl) = 0; if (flag_default_inline) DECL_INLINE (fndecl) = 1; diff -uNr gcc/gcc/cp/optimize.c gcc.autolim/gcc/cp/optimize.c --- gcc/gcc/cp/optimize.c Sun Oct 20 20:51:51 2002 +++ gcc.autolim/gcc/cp/optimize.c Fri Feb 28 12:16:05 2003 @@ -165,6 +165,7 @@ /* Update CLONE's source position information to match FN's. */ DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (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); diff -uNr gcc/gcc/doc/invoke.texi gcc.autolim/gcc/doc/invoke.texi --- gcc/gcc/doc/invoke.texi Fri Feb 28 12:13:06 2003 +++ gcc.autolim/gcc/doc/invoke.texi Fri Feb 28 12:16:05 2003 @@ -3577,6 +3577,8 @@ is set to @var{n}. @item max-inline-insns-single is set to @var{n}/2. + @item max-inline-insns-single-auto + is set to @var{n}*2/5. @item min-inline-insns is set to 130 or @var{n}/4, whichever is smaller. @item max-inline-insns-rtl @@ -4337,6 +4339,14 @@ inline and methods implemented in a class declaration (C++). The default value is 300. +@item max-inline-insns-auto +When you use @option{-finline-functions} (included in @option{-O3}), +a lot of functions that would otherwise not be considered for inlining +by the compiler will be investigated. To those functions, a different +(more restrictive) limit compared to functions declared inline can +be applied. +The default value is 240. + @item max-inline-insns The tree inliner does decrease the allowable size for single functions to be inlined after we already inlined the number of instructions diff -uNr gcc/gcc/params.def gcc.autolim/gcc/params.def --- gcc/gcc/params.def Fri Feb 28 12:13:06 2003 +++ gcc.autolim/gcc/params.def Fri Feb 28 12:17:30 2003 @@ -53,6 +53,18 @@ "The maximum number of instructions in a single function eligible for inlining", 300) +/* The single function inlining limit for functions that are + inlined by virtue of -finline-functions (-O3). + This limit should be chosen to be below or equal to the limit + that is applied to functions marked inlined (or defined in the + class declaration in C++) given by the "max-inline-insns-single" + parameter. + The default value is 240. */ +DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO, + "max-inline-insns-auto", + "The maximum number of instructions when automatically inlining", + 240) + /* The repeated inlining limit. After this number of instructions (in the internal gcc representation, not real machine instructions) got inlined by repeated inlining, gcc starts to decrease the maximum diff -uNr gcc/gcc/params.h gcc.autolim/gcc/params.h --- gcc/gcc/params.h Fri Feb 28 12:13:06 2003 +++ gcc.autolim/gcc/params.h Fri Feb 28 12:16:05 2003 @@ -92,6 +92,8 @@ PARAM_VALUE (PARAM_MAX_INLINE_SLOPE) #define MIN_INLINE_INSNS \ PARAM_VALUE (PARAM_MIN_INLINE_INSNS) +#define MAX_INLINE_INSNS_AUTO \ + PARAM_VALUE (PARAM_MAX_INLINE_INSNS_AUTO) #define MAX_INLINE_INSNS_RTL \ PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RTL) #define MAX_DELAY_SLOT_INSN_SEARCH \ diff -uNr gcc/gcc/print-tree.c gcc.autolim/gcc/print-tree.c --- gcc/gcc/print-tree.c Wed Oct 16 02:40:27 2002 +++ gcc.autolim/gcc/print-tree.c Fri Feb 28 12:16:05 2003 @@ -328,7 +328,9 @@ if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node)) fputs (" suppress-debug", file); - if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node)) + if (TREE_CODE (node) == FUNCTION_DECL && DID_INLINE_FUNC (node)) + fputs (" autoinline", file); + else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node)) fputs (" inline", file); if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node)) fputs (" built-in", file); diff -uNr gcc/gcc/toplev.c gcc.autolim/gcc/toplev.c --- gcc/gcc/toplev.c Fri Feb 28 12:13:06 2003 +++ gcc.autolim/gcc/toplev.c Fri Feb 28 12:16:05 2003 @@ -2430,12 +2430,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 (); @@ -3949,6 +3953,7 @@ MAX_INLINE_INSNS); set_param_value ("max-inline-insns", val); set_param_value ("max-inline-insns-single", val/2); + set_param_value ("max-inline-insns-auto", val*2/5); set_param_value ("max-inline-insns-rtl", val); if (val/4 < MIN_INLINE_INSNS) { diff -uNr gcc/gcc/tree-inline.c gcc.autolim/gcc/tree-inline.c --- gcc/gcc/tree-inline.c Thu Feb 20 01:51:56 2003 +++ gcc.autolim/gcc/tree-inline.c Fri Feb 28 12:16:05 2003 @@ -930,6 +930,7 @@ { int inlinable; int currfn_insns; + int max_inline_insns_single = MAX_INLINE_INSNS_SINGLE; /* If we've already decided this function shouldn't be inlined, there's no need to check again. */ @@ -939,6 +940,12 @@ /* Assume it is not inlinable. */ inlinable = 0; + /* We may be here either because fn is declared inline or because + we use -finline-functions. For the second case, we are more + restrictive. */ + if (DID_INLINE_FUNC (fn)) + max_inline_insns_single = MAX_INLINE_INSNS_AUTO; + /* The number of instructions (estimated) of current function. */ currfn_insns = DECL_NUM_STMTS (fn) * INSNS_PER_STMT; @@ -957,7 +964,7 @@ 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) + && currfn_insns > max_inline_insns_single) ; /* We can't inline functions that call __builtin_longjmp at all. The non-local goto machenery really requires the destination diff -uNr gcc/gcc/tree.h gcc.autolim/gcc/tree.h --- gcc/gcc/tree.h Thu Jan 9 13:11:38 2003 +++ gcc.autolim/gcc/tree.h Fri Feb 28 12:16:05 2003 @@ -1642,6 +1642,11 @@ 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) @@ -1827,7 +1832,8 @@ unsigned user_align : 1; unsigned uninlinable : 1; unsigned thread_local_flag : 1; - /* Two unused bits. */ + unsigned inlined_function_flag : 1; + /* One unused bit. */ unsigned lang_flag_0 : 1; unsigned lang_flag_1 : 1;