tree-inline.c (inlinable_function_p): Improve heuristics by using a smoother function to cut down allowable inlinable...

* 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.

From-SVN: r52832
This commit is contained in:
Kurt Garloff 2002-04-27 11:59:40 -07:00 committed by Richard Henderson
parent c3a6afe78d
commit a62271540b
4 changed files with 110 additions and 20 deletions

View File

@ -1,3 +1,12 @@
2002-04-27 Kurt Garloff <garloff@suse.de>
* 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 <rth@redhat.com> 2002-04-26 Richard Henderson <rth@redhat.com>
* c-parse.in (malloced_yyss, malloced_yyvs): New. * c-parse.in (malloced_yyss, malloced_yyvs): New.
@ -50,7 +59,7 @@
2002-04-26 Richard Henderson <rth@redhat.com> 2002-04-26 Richard Henderson <rth@redhat.com>
* c-parse.in (yyoverflow): Revert. * c-parse.in (yyoverflow): Revert.
2002-04-26 David Edelsohn <edelsohn@gnu.org> 2002-04-26 David Edelsohn <edelsohn@gnu.org>
Richard Henderson <rth@redhat.com> Richard Henderson <rth@redhat.com>

View File

@ -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. */ Be sure to add an entry to invoke.texi summarizing the parameter. */
/* The maximum number of instructions accepted for inlining a /* The single function inlining limit. This is the maximum size
function. Increasing values mean more agressive inlining. of a function counted in internal gcc instructions (not in
This affects currently only functions explicitly marked as real machine instructions) that is eligible for inlining
inline (or methods defined within the class definition for C++). by the tree inliner.
The original default value of 10000 was arbitrary and caused The default value is 300.
significant compile-time performance regressions. */ 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, DEFPARAM (PARAM_MAX_INLINE_INSNS,
"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) 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 /* The maximum number of instructions to consider when looking for an
instruction to fill a delay slot. If more than this arbitrary instruction to fill a delay slot. If more than this arbitrary
number of instructions is searched, the time savings from filling number of instructions is searched, the time savings from filling

View File

@ -84,8 +84,14 @@ typedef enum compiler_param
(compiler_params[(int) ENUM].value) (compiler_params[(int) ENUM].value)
/* Macros for the various parameters. */ /* Macros for the various parameters. */
#define MAX_INLINE_INSNS_SINGLE \
PARAM_VALUE (PARAM_MAX_INLINE_INSNS_SINGLE)
#define MAX_INLINE_INSNS \ #define MAX_INLINE_INSNS \
PARAM_VALUE (PARAM_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 \ #define MAX_DELAY_SLOT_INSN_SEARCH \
PARAM_VALUE (PARAM_MAX_DELAY_SLOT_INSN_SEARCH) PARAM_VALUE (PARAM_MAX_DELAY_SLOT_INSN_SEARCH)
#define MAX_DELAY_SLOT_LIVE_SEARCH \ #define MAX_DELAY_SLOT_LIVE_SEARCH \

View File

@ -668,6 +668,7 @@ inlinable_function_p (fn, id)
inline_data *id; inline_data *id;
{ {
int inlinable; int inlinable;
int currfn_insns;
/* If we've already decided this function shouldn't be inlined, /* If we've already decided this function shouldn't be inlined,
there's no need to check again. */ there's no need to check again. */
@ -676,6 +677,9 @@ inlinable_function_p (fn, id)
/* Assume it is not inlinable. */ /* Assume it is not inlinable. */
inlinable = 0; 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 we're not inlining things, then nothing is inlinable. */
if (! flag_inline_trees) if (! flag_inline_trees)
@ -689,10 +693,10 @@ inlinable_function_p (fn, id)
else if (! DECL_INLINE (fn)) else if (! DECL_INLINE (fn))
; ;
/* We can't inline functions that are too big. Only allow a single /* We can't inline functions that are too big. Only allow a single
function to eat up half of our budget. Make special allowance function to be of MAX_INLINE_INSNS_SINGLE size. Make special
for extern inline functions, though. */ allowance for extern inline functions, though. */
else if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn) 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 /* All is well. We can inline this function. Traditionally, GCC
has refused to inline functions using alloca, or functions whose 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. */ /* Squirrel away the result so that we don't have to check again. */
DECL_UNINLINABLE (fn) = ! inlinable; DECL_UNINLINABLE (fn) = ! inlinable;
/* Even if this function is not itself too big to inline, it might /* In case we don't disregard the inlining limits and we basically
be that we've done so much inlining already that we don't want to can inline this function, investigate further. */
risk too much inlining any more and thus halve the acceptable
size. */
if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn) if (! (*lang_hooks.tree_inlining.disregard_inline_limits) (fn)
&& ((DECL_NUM_STMTS (fn) + (id ? id->inlined_stmts : 0)) * INSNS_PER_STMT && inlinable)
> MAX_INLINE_INSNS) {
&& DECL_NUM_STMTS (fn) * INSNS_PER_STMT > MAX_INLINE_INSNS / 4) int sum_insns = (id ? id->inlined_stmts : 0) * INSNS_PER_STMT
inlinable = 0; + 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)) if (inlinable && (*lang_hooks.tree_inlining.cannot_inline_tree_fn) (&fn))
inlinable = 0; inlinable = 0;
@ -968,7 +988,8 @@ expand_call_inline (tp, walk_subtrees, data)
/* Our function now has more statements than it did before. */ /* Our function now has more statements than it did before. */
DECL_NUM_STMTS (VARRAY_TREE (id->fns, 0)) += DECL_NUM_STMTS (fn); 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. */ /* Recurse into the body of the just inlined function. */
expand_calls_inline (inlined_body, id); expand_calls_inline (inlined_body, id);