mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-24 16:59:28 +08:00
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:
parent
c3a6afe78d
commit
a62271540b
@ -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>
|
||||
|
||||
* c-parse.in (malloced_yyss, malloced_yyvs): New.
|
||||
@ -50,7 +59,7 @@
|
||||
|
||||
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>
|
||||
Richard Henderson <rth@redhat.com>
|
||||
|
@ -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
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user