diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0fd205f5b13..60324ffa73d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2002-04-27 Kurt Garloff + + * tree-inline.c (inlinable_function_p): Improve heuristics + by using a smoother function to cut down allowable inlinable size. + * param.def: Add parameters max-inline-insns-single, + max-inline-slope, min-inline-insns that determine the exact + shape of the above function. + * param.h: Likewise. + 2002-04-26 Richard Henderson * c-parse.in (malloced_yyss, malloced_yyvs): New. @@ -50,7 +59,7 @@ 2002-04-26 Richard Henderson - * c-parse.in (yyoverflow): Revert. + * c-parse.in (yyoverflow): Revert. 2002-04-26 David Edelsohn Richard Henderson diff --git a/gcc/params.def b/gcc/params.def index a064ca28132..2b2cfe67c4d 100644 --- a/gcc/params.def +++ b/gcc/params.def @@ -35,17 +35,71 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA Be sure to add an entry to invoke.texi summarizing the parameter. */ -/* The maximum number of instructions accepted for inlining a - function. Increasing values mean more agressive inlining. - This affects currently only functions explicitly marked as - inline (or methods defined within the class definition for C++). - The original default value of 10000 was arbitrary and caused - significant compile-time performance regressions. */ +/* The single function inlining limit. This is the maximum size + of a function counted in internal gcc instructions (not in + real machine instructions) that is eligible for inlining + by the tree inliner. + The default value is 300. + Only functions marked inline (or methods defined in the class + definition for C++) are affected by this, unless you set the + -finline-functions (included in -O3) compiler option. + There are more restrictions to inlining: If inlined functions + call other functions, the already inlined instructions are + counted and once the recursive inline limit (see + "max-inline-insns" parameter) is exceeded, the acceptable size + gets decreased. */ +DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, + "max-inline-insns-single", + "The maximum number of instructions in a single function eliglible for inlining", + 300) + +/* 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 + number of inlinable instructions in the tree inliner. + This is done by a linear function, see "max-inline-slope" parameter. + It is necessary in order to limit the compile-time resources, that + could otherwise become very high. + It is recommended to set this value to twice the value of the single + function limit (set by the "max-inline-insns-single" parameter) or + higher. The default value is 600. + 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. */ DEFPARAM (PARAM_MAX_INLINE_INSNS, "max-inline-insns", - "The maximum number of instructions in a function that is eligible for inlining", + "The maximuem number of instructions by repeated inlining before gcc starts to throttle inlining", 600) +/* After the repeated inline limit has been exceeded (see + "max-inline-insns" parameter), a linear function is used to + decrease the size of single functions eligible for inlining. + The slope of this linear function is given the negative + reciprocal value (-1/x) of this parameter. + The default vlue is 32. + This linear function is used until it falls below a minimum + value specified by the "min-inline-insns" parameter. */ +DEFPARAM (PARAM_MAX_INLINE_SLOPE, + "max-inline-slope", + "The slope of the linear funtion throttling inlining after the recursive inlining limit has been reached is given by the negative reciprocal value of this parameter", + 32) + +/* When gcc has inlined so many instructions (by repeated + inlining) that the throttling limits the inlining very much, + inlining for very small functions is still desirable to + achieve good runtime performance. The size of single functions + (measured in gcc instructions) which will still be eligible for + inlining then is given by this parameter. It defaults to 130. + Only much later (after exceeding 128 times the recursive limit) + inlining is cut down completely. */ +DEFPARAM (PARAM_MIN_INLINE_INSNS, + "min-inline-insns", + "The number of instructions in a single functions still eligible to inlining after a lot recursive inlining", + 130) + /* 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 diff --git a/gcc/params.h b/gcc/params.h index 36800af2ec4..c4474e418ee 100644 --- a/gcc/params.h +++ b/gcc/params.h @@ -84,8 +84,14 @@ typedef enum compiler_param (compiler_params[(int) ENUM].value) /* Macros for the various parameters. */ +#define MAX_INLINE_INSNS_SINGLE \ + PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE) #define MAX_INLINE_INSNS \ PARAM_VALUE (PARAM_MAX_INLINE_INSNS) +#define MAX_INLINE_SLOPE \ + PARAM_VALUE (PARAM_MAX_INLINE_SLOPE) +#define MIN_INLINE_INSNS \ + PARAM_VALUE (PARAM_MIN_INLINE_INSNS) #define MAX_DELAY_SLOT_INSN_SEARCH \ PARAM_VALUE (PARAM_MAX_DELAY_SLOT_INSN_SEARCH) #define MAX_DELAY_SLOT_LIVE_SEARCH \ diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 759b55e1418..1385e8389be 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -668,6 +668,7 @@ inlinable_function_p (fn, id) inline_data *id; { int inlinable; + int currfn_insns; /* If we've already decided this function shouldn't be inlined, there's no need to check again. */ @@ -676,6 +677,9 @@ inlinable_function_p (fn, id) /* Assume it is not inlinable. */ inlinable = 0; + + /* 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. */ if (! flag_inline_trees) @@ -689,10 +693,10 @@ inlinable_function_p (fn, id) else if (! DECL_INLINE (fn)) ; /* We can't inline functions that are too big. Only allow a single - function to eat up half of our budget. Make special allowance - for extern inline functions, though. */ + 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) - && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 2) + && 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 @@ -704,15 +708,31 @@ inlinable_function_p (fn, id) /* Squirrel away the result so that we don't have to check again. */ DECL_UNINLINABLE (fn) = ! inlinable; - /* Even if this function is not itself too big to inline, it might - be that we've done so much inlining already that we don't want to - risk too much inlining any more and thus halve the acceptable - size. */ + /* 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) - && ((DECL_NUM_STMTS (fn) + (id ? id->inlined_stmts : 0)) * INSNS_PER_STMT - > MAX_INLINE_INSNS) - && DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 4) - inlinable = 0; + && inlinable) + { + 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)) + { + int max_curr = MAX_INLINE_INSNS_SINGLE + - (sum_insns - MAX_INLINE_INSNS) / MAX_INLINE_SLOPE; + if (currfn_insns > max_curr) + inlinable = 0; + } + } if (inlinable && (*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn)) inlinable = 0; @@ -968,7 +988,8 @@ expand_call_inline (tp, walk_subtrees, data) /* Our function now has more statements than it did before. */ DECL_NUM_STMTS (VARRAY_TREE (id->fns, 0)) += DECL_NUM_STMTS (fn); - id->inlined_stmts += DECL_NUM_STMTS (fn); + /* For accounting, subtract one for the saved call/ret. */ + id->inlined_stmts += DECL_NUM_STMTS (fn) - 1; /* Recurse into the body of the just inlined function. */ expand_calls_inline (inlined_body, id);