mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-20 14:49:34 +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>
|
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>
|
||||||
|
@ -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
|
||||||
|
@ -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 \
|
||||||
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user