Index: gcc/ChangeLog =================================================================== RCS file: /cvs/gcc/gcc/gcc/ChangeLog,v retrieving revision 1.14277 diff -u -r1.14277 ChangeLog --- gcc/ChangeLog 28 May 2002 07:02:30 -0000 1.14277 +++ gcc/ChangeLog 28 May 2002 13:48:54 -0000 @@ -1,3 +1,35 @@ +2002-05-28 Kurt Garloff + + * tree-inline.c: (inlinable_function_p): Maximum inlinable + size determined by max-inline-insns-auto parameter now. + * integrate.c: (cannot_inline_p): Note that the RTL inliner + is not used if the tree inliner is (C,C++). Use limits + max-inline-insns-rtl and max-inline-insns-rtl-leaf. + * param.def: Add parameters max-inline-insns-auto, + max-inline-insns-rtl, mad-inline-insns-rtl-leaf. + * param.h: Likewise. + * toplev.c: (decode_f_option): Create a set of inlining + parameters from -finline-insns=N option. + * doc/invoke.texi: Add documentation on new parameters + and correct typos. + +2002-05-28 Kurt Garloff + + * toplev.c: (rest_of_compilation): Set current_function_is_leaf + flag for integrate.c. Set DID_INLINE_FUNC flag if we inline + just because of -finline-functions. + * integrate.c: (INTEGRATE_THRESHOLD): Better tune for -Os. + 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-05-28 Richard Henderson * config.gcc: Obsolete mn10200. Index: gcc/c-decl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/c-decl.c,v retrieving revision 1.329 diff -u -r1.329 c-decl.c --- gcc/c-decl.c 25 May 2002 22:01:41 -0000 1.329 +++ gcc/c-decl.c 28 May 2002 13:48:58 -0000 @@ -4948,6 +4948,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; } Index: gcc/integrate.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/integrate.c,v retrieving revision 1.191 diff -u -r1.191 integrate.c --- gcc/integrate.c 30 Apr 2002 20:48:52 -0000 1.191 +++ gcc/integrate.c 28 May 2002 13:49:00 -0000 @@ -59,11 +59,11 @@ This is overridden on RISC machines. */ #ifndef INTEGRATE_THRESHOLD /* Inlining small functions might save more space then not inlining at - all. Assume 1 instruction for the call and 1.5 insns per argument. */ + all. Assume 3 instructions for the call and 4 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)))) \ + : (64 + (8 * list_length (DECL_ARGUMENTS (DECL))))) #endif @@ -163,11 +163,19 @@ tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); /* For functions marked as inline increase the maximum size to - MAX_INLINE_INSNS (-finline-limit-). For regular functions - use the limit given by INTEGRATE_THRESHOLD. */ + MAX_INLINE_INSNS (-finline-limit=). For regular functions + use the limit given by INTEGRATE_THRESHOLD. + Note that we don't differentiate between automatically inlined + functions (DID_INLINE_FUNC set) and functions declared inline + here, as too much inlining at RTL level does not cause less + problems with compile-time resources than tree inlining and no + recursive accounting and limiting is done, so we also don't hurt + runtime performance too much. + Note that the RTL inliner is not used by the languages that use + the tree inliner (C, C++). */ int max_insns = (DECL_INLINE (fndecl)) - ? (MAX_INLINE_INSNS + ? (MAX_INLINE_INSNS_RTL + 8 * list_length (DECL_ARGUMENTS (fndecl))) : INTEGRATE_THRESHOLD (fndecl); @@ -200,6 +208,11 @@ if (current_function_cannot_inline) return current_function_cannot_inline; + + /* There may be a different (higher) limit for leaf functions. */ + if (current_function_is_leaf) + max_insns = MAX_INLINE_INSNS_RTL_LEAF + + 8 * list_length (DECL_ARGUMENTS (fndecl)); /* If its not even close, don't even look. */ if (get_max_uid () > 3 * max_insns) Index: gcc/params.def =================================================================== RCS file: /cvs/gcc/gcc/gcc/params.def,v retrieving revision 1.14 diff -u -r1.14 params.def --- gcc/params.def 15 May 2002 09:00:04 -0000 1.14 +++ gcc/params.def 28 May 2002 13:49:00 -0000 @@ -50,7 +50,7 @@ gets decreased. */ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, "max-inline-insns-single", - "The maximum number of instructions in a single function eliglible for inlining", + "The maximum number of instructions in a single function eligible for inlining", 300) /* The repeated inlining limit. After this number of instructions @@ -66,12 +66,10 @@ Higher values mean that more inlining is done, resulting in better performance of the code, at the expense of higher compile-time resource (time, memory) requirements and larger - binaries. - This parameters also controls the maximum size of functions considered - for inlining in the RTL inliner. */ + binaries. */ DEFPARAM (PARAM_MAX_INLINE_INSNS, "max-inline-insns", - "The maximuem number of instructions by repeated inlining before gcc starts to throttle inlining", + "The maximum number of instructions by repeated inlining before gcc starts to throttle inlining", 600) /* After the repeated inline limit has been exceeded (see @@ -100,6 +98,40 @@ "The number of instructions in a single functions still eligible to inlining after a lot recursive inlining", 130) +/* 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 200. */ +DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO, + "max-inline-insns-auto", + "The maximum number of instructions when automatically inlining", + 200) + +/* For languages that (still) use the RTL inliner, we can specify + limits for the RTL inliner separately. + The parameter here defines the maximum number of RTL instructions + a function may have to be eligible for inlining in the RTL inliner. + The default value is 600. */ +DEFPARAM (PARAM_MAX_INLINE_INSNS_RTL, + "max-inline-insns-rtl", + "The maximum number of instructions for the RTL inliner", + 600) + +/* In the RTL inliner, we may give a bonus to leaf functions. Unlike + the tree inliner, there is no accounting for recursive inlining + done, so using very large limits in the RTL inliner may result in + excessive compilation time resource requirements. + For leaf functions, this can't happen, so you may want to specify + a larger limit. + The default value is 900. */ +DEFPARAM (PARAM_MAX_INLINE_INSNS_RTL_LEAF, + "max-inline-insns-rtl-leaf", + "The maximum number of instructions for leaf functions in the RTL inliner", + 900) + /* The maximum number of instructions to consider when looking for an instruction to fill a delay slot. If more than this arbitrary number of instructions is searched, the time savings from filling Index: gcc/params.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/params.h,v retrieving revision 1.14 diff -u -r1.14 params.h --- gcc/params.h 20 May 2002 18:06:53 -0000 1.14 +++ gcc/params.h 28 May 2002 13:49:00 -0000 @@ -92,6 +92,12 @@ 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_INLINE_INSNS_RTL_LEAF \ + PARAM_VALUE (PARAM_MAX_INLINE_INSNS_RTL_LEAF) #define MAX_DELAY_SLOT_INSN_SEARCH \ PARAM_VALUE (PARAM_MAX_DELAY_SLOT_INSN_SEARCH) #define MAX_DELAY_SLOT_LIVE_SEARCH \ Index: gcc/print-tree.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/print-tree.c,v retrieving revision 1.58 diff -u -r1.58 print-tree.c --- gcc/print-tree.c 22 May 2002 01:11:16 -0000 1.58 +++ gcc/print-tree.c 28 May 2002 13:49:01 -0000 @@ -331,6 +331,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)) Index: gcc/toplev.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/toplev.c,v retrieving revision 1.637 diff -u -r1.637 toplev.c --- gcc/toplev.c 25 May 2002 18:02:14 -0000 1.637 +++ gcc/toplev.c 28 May 2002 13:49:04 -0000 @@ -2382,6 +2382,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) @@ -2398,12 +2399,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 (); @@ -3854,6 +3859,17 @@ read_integral_parameter (option_value, arg - 2, 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/3); + set_param_value ("max-inline-insns-rtl", val); + set_param_value ("max-inline-insns-rtl-leaf", (val*3)/2); + if ((val/2 - MIN_INLINE_INSNS) < 20) + { + if (val/2 > 20) + set_param_value ("min-inline-insns", val/2 - 20); + else + set_param_value ("min-inline-insns", 10); + } } else if ((option_value = skip_leading_substring (arg, "tls-model="))) { Index: gcc/tree-inline.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree-inline.c,v retrieving revision 1.23 diff -u -r1.23 tree-inline.c --- gcc/tree-inline.c 18 May 2002 15:16:25 -0000 1.23 +++ gcc/tree-inline.c 28 May 2002 13:49:05 -0000 @@ -669,6 +669,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. */ @@ -677,8 +678,14 @@ /* Assume it is not inlinable. */ inlinable = 0; - - /* The number of instructions (estimated) of current function. */ + + /* We may 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; /* If we're not inlining things, then nothing is inlinable. */ @@ -696,7 +703,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) ; /* All is well. We can inline this function. Traditionally, GCC has refused to inline functions using alloca, or functions whose Index: gcc/tree.h =================================================================== RCS file: /cvs/gcc/gcc/gcc/tree.h,v retrieving revision 1.337 diff -u -r1.337 tree.h --- gcc/tree.h 22 May 2002 01:11:17 -0000 1.337 +++ gcc/tree.h 28 May 2002 13:49:07 -0000 @@ -1612,6 +1612,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) @@ -1798,7 +1802,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; Index: gcc/cp/decl.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v retrieving revision 1.910 diff -u -r1.910 decl.c --- gcc/cp/decl.c 23 May 2002 05:14:02 -0000 1.910 +++ gcc/cp/decl.c 28 May 2002 13:49:22 -0000 @@ -9021,13 +9021,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) @@ -14460,6 +14466,7 @@ DECL_DECLARED_INLINE_P (fndecl) = 1; + DID_INLINE_FUNC (fndecl) = 0; if (flag_default_inline) DECL_INLINE (fndecl) = 1; Index: gcc/cp/optimize.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/optimize.c,v retrieving revision 1.81 diff -u -r1.81 optimize.c --- gcc/cp/optimize.c 16 Dec 2001 16:07:00 -0000 1.81 +++ gcc/cp/optimize.c 28 May 2002 13:49:22 -0000 @@ -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); Index: gcc/doc/invoke.texi =================================================================== RCS file: /cvs/gcc/gcc/gcc/doc/invoke.texi,v retrieving revision 1.148 diff -u -r1.148 invoke.texi --- gcc/doc/invoke.texi 23 May 2002 15:48:00 -0000 1.148 +++ gcc/doc/invoke.texi 28 May 2002 13:49:30 -0000 @@ -3339,6 +3339,28 @@ means slower programs). This option is particularly useful for programs that use inlining heavily such as those based on recursive templates with C++. +Inlining is actually controlled by a number of parameters, which may be +specified individually by using @option{--param @var{name}=@var{value}}. +The @option{-finline-limit=@var{n}} option sets some of these parameters +as follows: + +@table @gcctabopt + @item max-inline-insns + is set to @var{n}. + @item max-inline-insns-single + is set to @var{n}/2. + @item max-inline-insns-auto + is set to @var{n}/3. + @item max-inline-insns-rtl + is set to @var{n}. + @item max-inline-insns-rtl-leaf + is set to @var{n}*3/2. +@end table + +Using @option{-finline-limit=600} thus results in the default settings +for these parameters. See below for a documentation of the individual +parameters controlling inlining. + @emph{Note:} pseudo instruction represents, in this particular context, an abstract measurement of function's size. In no way, it represents a count of assembly instructions and as such its exact meaning might change from one @@ -3924,10 +3946,60 @@ with few branches or calls can create excessively large lists which needlessly consume memory and resources. +@item max-inline-insns-single +Several parameters control the tree inliner used in gcc. +This number sets the maximum number of instructions (counted in gcc's +internal representation) in a single function that the tree inliner +will consider for inlining. This only affects functions declared +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 200. + @item max-inline-insns -If an function contains more than this many instructions, it -will not be inlined. This option is precisely equivalent to -@option{-finline-limit}. +The tree inliner does decrease the allowable size for single functions +to be inlined after we already inlined the number of instructions +given here by repeated inlining. This number should be a factor of +two or more larger than the single function limit. +Higher numbers result in better runtime performance, but incur higher +compile-time resource (CPU time, memory) requirements and result in +larger binaries. Very high values are not advisable, as too large +binaries may adversely affect runtime performance. +The default value is 600. + +@item max-inline-slope +After exceeding the maximum number of inlined instructions by repeated +inlining, a linear function is used to decrease the allowable size +for single functions. The slope of that function is the negative +reciprocal of the number specified here. +The default value is 32. + +@item min-inline-insns +The repeated inlining is throttled more and more by the linear function +after exceeding the limit. To avoid too much throttling, a minimum for +this function is specified here to allow repeated inlining for very small +functions even when a lot of repeated inlining already has been done. +The default value is 130. + +@item max-inline-insns-rtl +For languages that use the RTL inliner (this happens at a later stage +than tree inlining), you can set the maximum allowable size (counted +in RTL instructions) for the RTL inliner with this parameter. +The default value is 600. + +@item max-inline-insns-rtl-leaf +As the RTL inliner does not account for repeated inlining in a call +tree, using very large limits there is not a good idea, as it can lead +to excessive compile time resource requirements. +For leaf functions this problem does not exist, so you may specify a +larger limit here. +The default value is 900. @item max-unrolled-insns The maximum number of instructions that a loop should have if that loop