Commit bc522472 by Kurt Garloff Committed by Geoffrey Keating

params.def: Introduce parameter max-inline-insns-rtl for a separate limit for the RTL inliner.

2003-03-02  Kurt Garloff  <garloff@suse.de>

	* params.def: Introduce parameter max-inline-insns-rtl for
	a separate limit for the RTL inliner.
	* params.h: Likewise.
	* integrate.c (function_cannot_inline_p): Use it.
	* toplev.c (decode_f_option): Set multiple parameters
	controlling inlining with -finline-limit.
	* params.def: Fix orthographic and typographic errors.
	* doc/invoke.texi: Document parameters controlling inlining
	and the way -finline-limit sets multiple of them.

	* tree.h (struct tree_decl): Introduce inlined_function_flag,
	recording whether the function became eligible for inlining
	by a compiler flag rather than the declaration.
	Provide DID_INLINE_FUNC macro to access it.
	* c-decl.c (grokdeclarator): Set DID_INLINE_FUNC.
	* cp/decl.c (grokfndecl): Likewise.
	* toplev.c (rest_of_compilation): Likewise.
	* cp/optimize (maybe_clone_body): Copy DID_INLINE_FUNC.
	* print-tree.c (print_node): Report it.
	* params.def: Introduce new max-inline-insns-auto limit.
	* params.h: Likewise.
	* tree-inline.c (inlinable_function_p): Apply it to functions
	with DID_INLINE_FUNC set.
	* toplev.c (decode_f_option): Initialize it from -finline-limit
	value.
	* doc/invoke.texi: Document new parameter.

From-SVN: r63688
parent f4ae98be
2003-03-02 Kurt Garloff <garloff@suse.de>
* params.def: Introduce parameter max-inline-insns-rtl for
a separate limit for the RTL inliner.
* params.h: Likewise.
* integrate.c (function_cannot_inline_p): Use it.
* toplev.c (decode_f_option): Set multiple parameters
controlling inlining with -finline-limit.
* params.def: Fix orthographic and typographic errors.
* doc/invoke.texi: Document parameters controlling inlining
and the way -finline-limit sets multiple of them.
* tree.h (struct tree_decl): Introduce inlined_function_flag,
recording whether the function became eligible for inlining
by a compiler flag rather than the declaration.
Provide DID_INLINE_FUNC macro to access it.
* c-decl.c (grokdeclarator): Set DID_INLINE_FUNC.
* cp/decl.c (grokfndecl): Likewise.
* toplev.c (rest_of_compilation): Likewise.
* cp/optimize (maybe_clone_body): Copy DID_INLINE_FUNC.
* print-tree.c (print_node): Report it.
* params.def: Introduce new max-inline-insns-auto limit.
* params.h: Likewise.
* tree-inline.c (inlinable_function_p): Apply it to functions
with DID_INLINE_FUNC set.
* toplev.c (decode_f_option): Initialize it from -finline-limit
value.
* doc/invoke.texi: Document new parameter.
2003-03-02 Geoffrey Keating <geoffk@apple.com> 2003-03-02 Geoffrey Keating <geoffk@apple.com>
* fix-header.c (read_scan_file): Don't reference simplify_path. * fix-header.c (read_scan_file): Don't reference simplify_path.
......
...@@ -4567,6 +4567,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized) ...@@ -4567,6 +4567,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
needed, and let dwarf2 know that the function is inlinable. */ needed, and let dwarf2 know that the function is inlinable. */
else if (flag_inline_trees == 2 && initialized) else if (flag_inline_trees == 2 && initialized)
{ {
if (!DECL_INLINE (decl))
DID_INLINE_FUNC (decl) = 1;
DECL_INLINE (decl) = 1; DECL_INLINE (decl) = 1;
DECL_DECLARED_INLINE_P (decl) = 0; DECL_DECLARED_INLINE_P (decl) = 0;
} }
......
...@@ -8955,13 +8955,19 @@ grokfndecl (tree ctype, ...@@ -8955,13 +8955,19 @@ grokfndecl (tree ctype,
DECL_NOT_REALLY_EXTERN (decl) = 1; DECL_NOT_REALLY_EXTERN (decl) = 1;
} }
DID_INLINE_FUNC (decl) = 0;
/* If the declaration was declared inline, mark it as such. */ /* If the declaration was declared inline, mark it as such. */
if (inlinep) if (inlinep)
DECL_DECLARED_INLINE_P (decl) = 1; DECL_DECLARED_INLINE_P (decl) = 1;
/* We inline functions that are explicitly declared inline, or, when /* We inline functions that are explicitly declared inline, or, when
the user explicitly asks us to, all functions. */ 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; 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; DECL_EXTERNAL (decl) = 1;
if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE)
...@@ -14217,6 +14223,7 @@ start_method (tree declspecs, tree declarator, tree attrlist) ...@@ -14217,6 +14223,7 @@ start_method (tree declspecs, tree declarator, tree attrlist)
DECL_DECLARED_INLINE_P (fndecl) = 1; DECL_DECLARED_INLINE_P (fndecl) = 1;
DID_INLINE_FUNC (fndecl) = 0;
if (flag_default_inline) if (flag_default_inline)
DECL_INLINE (fndecl) = 1; DECL_INLINE (fndecl) = 1;
......
...@@ -159,6 +159,7 @@ maybe_clone_body (tree fn) ...@@ -159,6 +159,7 @@ maybe_clone_body (tree fn)
/* Update CLONE's source position information to match FN's. */ /* Update CLONE's source position information to match FN's. */
DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn); DECL_SOURCE_LOCATION (clone) = DECL_SOURCE_LOCATION (fn);
DECL_INLINE (clone) = DECL_INLINE (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_DECLARED_INLINE_P (clone) = DECL_DECLARED_INLINE_P (fn);
DECL_COMDAT (clone) = DECL_COMDAT (fn); DECL_COMDAT (clone) = DECL_COMDAT (fn);
DECL_WEAK (clone) = DECL_WEAK (fn); DECL_WEAK (clone) = DECL_WEAK (fn);
......
...@@ -3643,6 +3643,28 @@ the compilation faster and less code will be inlined (which presumably ...@@ -3643,6 +3643,28 @@ the compilation faster and less code will be inlined (which presumably
means slower programs). This option is particularly useful for programs that means slower programs). This option is particularly useful for programs that
use inlining heavily such as those based on recursive templates with C++. 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-single-auto
is set to @var{n}/2.
@item min-inline-insns
is set to 130 or @var{n}/4, whichever is smaller.
@item max-inline-insns-rtl
is set to @var{n}.
@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 @emph{Note:} pseudo instruction represents, in this particular context, an
abstract measurement of function's size. In no way, it represents a count 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 of assembly instructions and as such its exact meaning might change from one
...@@ -4466,10 +4488,53 @@ before flushing the current state and starting over. Large functions ...@@ -4466,10 +4488,53 @@ before flushing the current state and starting over. Large functions
with few branches or calls can create excessively large lists which with few branches or calls can create excessively large lists which
needlessly consume memory and resources. 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 300.
@item max-inline-insns @item max-inline-insns
If an function contains more than this many instructions, it The tree inliner does decrease the allowable size for single functions
will not be inlined. This option is precisely equivalent to to be inlined after we already inlined the number of instructions
@option{-finline-limit}. 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-unrolled-insns @item max-unrolled-insns
The maximum number of instructions that a loop should have if that loop The maximum number of instructions that a loop should have if that loop
......
...@@ -159,11 +159,13 @@ function_cannot_inline_p (fndecl) ...@@ -159,11 +159,13 @@ function_cannot_inline_p (fndecl)
tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl))); tree last = tree_last (TYPE_ARG_TYPES (TREE_TYPE (fndecl)));
/* For functions marked as inline increase the maximum size to /* For functions marked as inline increase the maximum size to
MAX_INLINE_INSNS (-finline-limit-<n>). For regular functions MAX_INLINE_INSNS_RTL (--param max-inline-insn-rtl=<n>). For
use the limit given by INTEGRATE_THRESHOLD. */ regular functions use the limit given by INTEGRATE_THRESHOLD.
Note that the RTL inliner is not used by the languages that use
the tree inliner (C, C++). */
int max_insns = (DECL_INLINE (fndecl)) int max_insns = (DECL_INLINE (fndecl))
? (MAX_INLINE_INSNS ? (MAX_INLINE_INSNS_RTL
+ 8 * list_length (DECL_ARGUMENTS (fndecl))) + 8 * list_length (DECL_ARGUMENTS (fndecl)))
: INTEGRATE_THRESHOLD (fndecl); : INTEGRATE_THRESHOLD (fndecl);
......
...@@ -50,7 +50,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -50,7 +50,19 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
gets decreased. */ gets decreased. */
DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
"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 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 300. */
DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO,
"max-inline-insns-auto",
"The maximum number of instructions when automatically inlining",
300) 300)
/* The repeated inlining limit. After this number of instructions /* The repeated inlining limit. After this number of instructions
...@@ -66,12 +78,10 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE, ...@@ -66,12 +78,10 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
Higher values mean that more inlining is done, resulting in Higher values mean that more inlining is done, resulting in
better performance of the code, at the expense of higher better performance of the code, at the expense of higher
compile-time resource (time, memory) requirements and larger compile-time resource (time, memory) requirements and larger
binaries. 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 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) 600)
/* After the repeated inline limit has been exceeded (see /* After the repeated inline limit has been exceeded (see
...@@ -79,7 +89,7 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS, ...@@ -79,7 +89,7 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS,
decrease the size of single functions eligible for inlining. decrease the size of single functions eligible for inlining.
The slope of this linear function is given the negative The slope of this linear function is given the negative
reciprocal value (-1/x) of this parameter. reciprocal value (-1/x) of this parameter.
The default vlue is 32. The default value is 32.
This linear function is used until it falls below a minimum This linear function is used until it falls below a minimum
value specified by the "min-inline-insns" parameter. */ value specified by the "min-inline-insns" parameter. */
DEFPARAM (PARAM_MAX_INLINE_SLOPE, DEFPARAM (PARAM_MAX_INLINE_SLOPE,
...@@ -100,6 +110,16 @@ DEFPARAM (PARAM_MIN_INLINE_INSNS, ...@@ -100,6 +110,16 @@ DEFPARAM (PARAM_MIN_INLINE_INSNS,
"The number of instructions in a single functions still eligible to inlining after a lot recursive inlining", "The number of instructions in a single functions still eligible to inlining after a lot recursive inlining",
130) 130)
/* 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)
/* 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
......
...@@ -92,6 +92,10 @@ typedef enum compiler_param ...@@ -92,6 +92,10 @@ typedef enum compiler_param
PARAM_VALUE (PARAM_MAX_INLINE_SLOPE) PARAM_VALUE (PARAM_MAX_INLINE_SLOPE)
#define MIN_INLINE_INSNS \ #define MIN_INLINE_INSNS \
PARAM_VALUE (PARAM_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_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 \
......
...@@ -330,7 +330,9 @@ print_node (file, prefix, node, indent) ...@@ -330,7 +330,9 @@ print_node (file, prefix, node, indent)
if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node)) if (TREE_CODE (node) == TYPE_DECL && TYPE_DECL_SUPPRESS_DEBUG (node))
fputs (" suppress-debug", file); fputs (" suppress-debug", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node)) if (TREE_CODE (node) == FUNCTION_DECL && DID_INLINE_FUNC (node))
fputs (" autoinline", file);
else if (TREE_CODE (node) == FUNCTION_DECL && DECL_INLINE (node))
fputs (" inline", file); fputs (" inline", file);
if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node)) if (TREE_CODE (node) == FUNCTION_DECL && DECL_BUILT_IN (node))
fputs (" built-in", file); fputs (" built-in", file);
......
...@@ -2481,13 +2481,17 @@ rest_of_compilation (decl) ...@@ -2481,13 +2481,17 @@ rest_of_compilation (decl)
goto exit_rest_of_compilation; goto exit_rest_of_compilation;
} }
} }
else else {
/* ??? Note that this has the effect of making it look /* ??? Note that we used to just make it look like if
like "inline" was specified for a function if we choose the "inline" keyword was specified when we decide
to inline it. This isn't quite right, but it's to inline it (because of -finline-functions).
probably not worth the trouble to fix. */ 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; inlinable = DECL_INLINE (decl) = 1;
} }
}
insns = get_insns (); insns = get_insns ();
...@@ -4085,6 +4089,16 @@ decode_f_option (arg) ...@@ -4085,6 +4089,16 @@ decode_f_option (arg)
read_integral_parameter (option_value, arg - 2, read_integral_parameter (option_value, arg - 2,
MAX_INLINE_INSNS); MAX_INLINE_INSNS);
set_param_value ("max-inline-insns", val); set_param_value ("max-inline-insns", val);
set_param_value ("max-inline-insns-single", val/2);
set_param_value ("max-inline-insns-auto", val/2);
set_param_value ("max-inline-insns-rtl", val);
if (val/4 < MIN_INLINE_INSNS)
{
if (val/4 > 10)
set_param_value ("min-inline-insns", val/4);
else
set_param_value ("min-inline-insns", 10);
}
} }
else if ((option_value = skip_leading_substring (arg, "tls-model="))) else if ((option_value = skip_leading_substring (arg, "tls-model=")))
{ {
......
...@@ -935,6 +935,7 @@ inlinable_function_p (fn, id) ...@@ -935,6 +935,7 @@ inlinable_function_p (fn, id)
{ {
int inlinable; int inlinable;
int currfn_insns; int currfn_insns;
int max_inline_insns_single = MAX_INLINE_INSNS_SINGLE;
/* 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. */
...@@ -944,6 +945,12 @@ inlinable_function_p (fn, id) ...@@ -944,6 +945,12 @@ inlinable_function_p (fn, id)
/* Assume it is not inlinable. */ /* Assume it is not inlinable. */
inlinable = 0; inlinable = 0;
/* We may be 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. */ /* The number of instructions (estimated) of current function. */
currfn_insns = DECL_NUM_STMTS (fn) * INSNS_PER_STMT; currfn_insns = DECL_NUM_STMTS (fn) * INSNS_PER_STMT;
...@@ -962,7 +969,7 @@ inlinable_function_p (fn, id) ...@@ -962,7 +969,7 @@ inlinable_function_p (fn, id)
function to be of MAX_INLINE_INSNS_SINGLE size. Make special function to be of MAX_INLINE_INSNS_SINGLE size. Make special
allowance 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)
&& currfn_insns > MAX_INLINE_INSNS_SINGLE) && currfn_insns > max_inline_insns_single)
; ;
/* We can't inline functions that call __builtin_longjmp at all. /* We can't inline functions that call __builtin_longjmp at all.
The non-local goto machenery really requires the destination The non-local goto machenery really requires the destination
......
...@@ -1626,6 +1626,11 @@ struct tree_type GTY(()) ...@@ -1626,6 +1626,11 @@ struct tree_type GTY(())
where it is called. */ where it is called. */
#define DECL_INLINE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.inline_flag) #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. */ /* In a FUNCTION_DECL, nonzero if the function cannot be inlined. */
#define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable) #define DECL_UNINLINABLE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.uninlinable)
...@@ -1811,7 +1816,8 @@ struct tree_decl GTY(()) ...@@ -1811,7 +1816,8 @@ struct tree_decl GTY(())
unsigned user_align : 1; unsigned user_align : 1;
unsigned uninlinable : 1; unsigned uninlinable : 1;
unsigned thread_local_flag : 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_0 : 1;
unsigned lang_flag_1 : 1; unsigned lang_flag_1 : 1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment