mirror of git://gcc.gnu.org/git/gcc.git
cgraphunit.c (cgraph_estimate_size_after_inlining): Compute call cost based on argument sizes.
* cgraphunit.c (cgraph_estimate_size_after_inlining): Compute call cost based on argument sizes. (cgraph_mark_inline_edge): Avoid inline unit from shringking by inlining. * params.def: (max-inline-inssn-single): Set to 450. (max-inline-insns-auto): Set to 90. (max-inline-insns-recursive): Set to 450 (max-inline-insns-recursive-auto): Set to 450. (large-function-insns): Set to 2700. (inline-call-cost): New parameter. * tree-inline.c (estimate_move_cost): New function. (estimate_num_insns_1): Compute move sizes costs by estimate_move_cost for non-gimple-regs, set cost to 0 for gimple-regs. Compute call size based on arguments. * tree-inline.h (estimate_move_cost): Declare. * invoke.texi: (max-inline-inssn-single): Change default to 450. (max-inline-insns-auto): Change default to 90. (max-inline-insns-recursive): Change default to 450 (max-inline-insns-recursive-auto): Change default to 450. (large-function-insns): Change default to 2700. (inline-call-cost): Document new parameter. * gcc.dg/winline-6.c: Modify so inlined function have nonzero cost. Co-Authored-By: Jan Hubicka <jh@suse.cz> From-SVN: r96892
This commit is contained in:
parent
b360e19350
commit
e5c4f28a6c
|
|
@ -1,3 +1,29 @@
|
||||||
|
2005-03-22 Richard Guenther <rguenth@tat.physik.uni-tuebingen.de>
|
||||||
|
Jan Hubicka <jh@suse.cz>
|
||||||
|
Steven Bosscher <stevenb@suse.de
|
||||||
|
|
||||||
|
* cgraphunit.c (cgraph_estimate_size_after_inlining): Compute
|
||||||
|
call cost based on argument sizes.
|
||||||
|
(cgraph_mark_inline_edge): Avoid inline unit from shringking by
|
||||||
|
inlining.
|
||||||
|
* params.def: (max-inline-inssn-single): Set to 450.
|
||||||
|
(max-inline-insns-auto): Set to 90.
|
||||||
|
(max-inline-insns-recursive): Set to 450
|
||||||
|
(max-inline-insns-recursive-auto): Set to 450.
|
||||||
|
(large-function-insns): Set to 2700.
|
||||||
|
(inline-call-cost): New parameter.
|
||||||
|
* tree-inline.c (estimate_move_cost): New function.
|
||||||
|
(estimate_num_insns_1): Compute move sizes costs by estimate_move_cost
|
||||||
|
for non-gimple-regs, set cost to 0 for gimple-regs. Compute call size
|
||||||
|
based on arguments.
|
||||||
|
* tree-inline.h (estimate_move_cost): Declare.
|
||||||
|
* invoke.texi: (max-inline-inssn-single): Change default to 450.
|
||||||
|
(max-inline-insns-auto): Change default to 90.
|
||||||
|
(max-inline-insns-recursive): Change default to 450
|
||||||
|
(max-inline-insns-recursive-auto): Change default to 450.
|
||||||
|
(large-function-insns): Change default to 2700.
|
||||||
|
(inline-call-cost): Document new parameter.
|
||||||
|
|
||||||
2005-03-22 Richard Sandiford <rsandifo@redhat.com>
|
2005-03-22 Richard Sandiford <rsandifo@redhat.com>
|
||||||
|
|
||||||
* config/i860/i860.h (target_flags, TARGET_XP, TARGET_SWITCHES)
|
* config/i860/i860.h (target_flags, TARGET_XP, TARGET_SWITCHES)
|
||||||
|
|
|
||||||
|
|
@ -1030,7 +1030,12 @@ static int
|
||||||
cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
|
cgraph_estimate_size_after_inlining (int times, struct cgraph_node *to,
|
||||||
struct cgraph_node *what)
|
struct cgraph_node *what)
|
||||||
{
|
{
|
||||||
return (what->global.insns - INSNS_PER_CALL) * times + to->global.insns;
|
tree fndecl = what->decl;
|
||||||
|
tree arg;
|
||||||
|
int call_insns = PARAM_VALUE (PARAM_INLINE_CALL_COST);
|
||||||
|
for (arg = DECL_ARGUMENTS (fndecl); arg; arg = TREE_CHAIN (arg))
|
||||||
|
call_insns += estimate_move_cost (TREE_TYPE (arg));
|
||||||
|
return (what->global.insns - call_insns) * times + to->global.insns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Estimate the growth caused by inlining NODE into all callees. */
|
/* Estimate the growth caused by inlining NODE into all callees. */
|
||||||
|
|
@ -1124,7 +1129,8 @@ cgraph_mark_inline_edge (struct cgraph_edge *e)
|
||||||
to->global.insns = new_insns;
|
to->global.insns = new_insns;
|
||||||
}
|
}
|
||||||
gcc_assert (what->global.inlined_to == to);
|
gcc_assert (what->global.inlined_to == to);
|
||||||
overall_insns += new_insns - old_insns;
|
if (new_insns > old_insns)
|
||||||
|
overall_insns += new_insns - old_insns;
|
||||||
ncalls_inlined++;
|
ncalls_inlined++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5518,7 +5518,7 @@ This number sets the maximum number of instructions (counted in GCC's
|
||||||
internal representation) in a single function that the tree inliner
|
internal representation) in a single function that the tree inliner
|
||||||
will consider for inlining. This only affects functions declared
|
will consider for inlining. This only affects functions declared
|
||||||
inline and methods implemented in a class declaration (C++).
|
inline and methods implemented in a class declaration (C++).
|
||||||
The default value is 500.
|
The default value is 450.
|
||||||
|
|
||||||
@item max-inline-insns-auto
|
@item max-inline-insns-auto
|
||||||
When you use @option{-finline-functions} (included in @option{-O3}),
|
When you use @option{-finline-functions} (included in @option{-O3}),
|
||||||
|
|
@ -5526,7 +5526,7 @@ a lot of functions that would otherwise not be considered for inlining
|
||||||
by the compiler will be investigated. To those functions, a different
|
by the compiler will be investigated. To those functions, a different
|
||||||
(more restrictive) limit compared to functions declared inline can
|
(more restrictive) limit compared to functions declared inline can
|
||||||
be applied.
|
be applied.
|
||||||
The default value is 120.
|
The default value is 90.
|
||||||
|
|
||||||
@item large-function-insns
|
@item large-function-insns
|
||||||
The limit specifying really large functions. For functions larger than this
|
The limit specifying really large functions. For functions larger than this
|
||||||
|
|
@ -5535,7 +5535,7 @@ limit after inlining inlining is constrained by
|
||||||
to avoid extreme compilation time caused by non-linear algorithms used by the
|
to avoid extreme compilation time caused by non-linear algorithms used by the
|
||||||
backend.
|
backend.
|
||||||
This parameter is ignored when @option{-funit-at-a-time} is not used.
|
This parameter is ignored when @option{-funit-at-a-time} is not used.
|
||||||
The default value is 3000.
|
The default value is 2700.
|
||||||
|
|
||||||
@item large-function-growth
|
@item large-function-growth
|
||||||
Specifies maximal growth of large function caused by inlining in percents.
|
Specifies maximal growth of large function caused by inlining in percents.
|
||||||
|
|
@ -5558,7 +5558,7 @@ For functions declared inline @option{--param max-inline-insns-recursive} is
|
||||||
taken into acount. For function not declared inline, recursive inlining
|
taken into acount. For function not declared inline, recursive inlining
|
||||||
happens only when @option{-finline-functions} (included in @option{-O3}) is
|
happens only when @option{-finline-functions} (included in @option{-O3}) is
|
||||||
enabled and @option{--param max-inline-insns-recursive-auto} is used. The
|
enabled and @option{--param max-inline-insns-recursive-auto} is used. The
|
||||||
default value is 500.
|
default value is 450.
|
||||||
|
|
||||||
@item max-inline-recursive-depth
|
@item max-inline-recursive-depth
|
||||||
@itemx max-inline-recursive-depth-auto
|
@itemx max-inline-recursive-depth-auto
|
||||||
|
|
@ -5568,7 +5568,16 @@ For functions declared inline @option{--param max-inline-recursive-depth} is
|
||||||
taken into acount. For function not declared inline, recursive inlining
|
taken into acount. For function not declared inline, recursive inlining
|
||||||
happens only when @option{-finline-functions} (included in @option{-O3}) is
|
happens only when @option{-finline-functions} (included in @option{-O3}) is
|
||||||
enabled and @option{--param max-inline-recursive-depth-auto} is used. The
|
enabled and @option{--param max-inline-recursive-depth-auto} is used. The
|
||||||
default value is 500.
|
default value is 450.
|
||||||
|
|
||||||
|
@item inline-call-cost
|
||||||
|
Specify cost of call instruction relative to simple arithmetics operations
|
||||||
|
(having cost of 1). Increasing this cost disqualify inlinining of non-leaf
|
||||||
|
functions and at same time increase size of leaf function that is believed to
|
||||||
|
reduce function size by being inlined. In effect it increase amount of
|
||||||
|
inlining for code having large abstraction penalty (many functions that just
|
||||||
|
pass the argumetns to other functions) and decrease inlining for code with low
|
||||||
|
abstraction penalty. Default value is 16.
|
||||||
|
|
||||||
@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
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,9 @@ DEFPARAM (PARAM_SRA_FIELD_STRUCTURE_RATIO,
|
||||||
of a function counted in internal gcc instructions (not in
|
of a function counted in internal gcc instructions (not in
|
||||||
real machine instructions) that is eligible for inlining
|
real machine instructions) that is eligible for inlining
|
||||||
by the tree inliner.
|
by the tree inliner.
|
||||||
The default value is 500.
|
The default value is 450.
|
||||||
Only functions marked inline (or methods defined in the class
|
Only functions marked inline (or methods defined in the class
|
||||||
definition for C++) are affected by this, unless you set the
|
definition for C++) are affected by this.
|
||||||
-finline-functions (included in -O3) compiler option.
|
|
||||||
There are more restrictions to inlining: If inlined functions
|
There are more restrictions to inlining: If inlined functions
|
||||||
call other functions, the already inlined instructions are
|
call other functions, the already inlined instructions are
|
||||||
counted and once the recursive inline limit (see
|
counted and once the recursive inline limit (see
|
||||||
|
|
@ -70,7 +69,7 @@ DEFPARAM (PARAM_SRA_FIELD_STRUCTURE_RATIO,
|
||||||
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 eligible for inlining",
|
"The maximum number of instructions in a single function eligible for inlining",
|
||||||
500, 0, 0)
|
450, 0, 0)
|
||||||
|
|
||||||
/* The single function inlining limit for functions that are
|
/* The single function inlining limit for functions that are
|
||||||
inlined by virtue of -finline-functions (-O3).
|
inlined by virtue of -finline-functions (-O3).
|
||||||
|
|
@ -78,21 +77,21 @@ DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
|
||||||
that is applied to functions marked inlined (or defined in the
|
that is applied to functions marked inlined (or defined in the
|
||||||
class declaration in C++) given by the "max-inline-insns-single"
|
class declaration in C++) given by the "max-inline-insns-single"
|
||||||
parameter.
|
parameter.
|
||||||
The default value is 150. */
|
The default value is 90. */
|
||||||
DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO,
|
DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO,
|
||||||
"max-inline-insns-auto",
|
"max-inline-insns-auto",
|
||||||
"The maximum number of instructions when automatically inlining",
|
"The maximum number of instructions when automatically inlining",
|
||||||
120, 0, 0)
|
90, 0, 0)
|
||||||
|
|
||||||
DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE,
|
DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE,
|
||||||
"max-inline-insns-recursive",
|
"max-inline-insns-recursive",
|
||||||
"The maximum number of instructions inline function can grow to via recursive inlining",
|
"The maximum number of instructions inline function can grow to via recursive inlining",
|
||||||
500, 0, 0)
|
450, 0, 0)
|
||||||
|
|
||||||
DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO,
|
DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE_AUTO,
|
||||||
"max-inline-insns-recursive-auto",
|
"max-inline-insns-recursive-auto",
|
||||||
"The maximum number of instructions non-inline function can grow to via recursive inlining",
|
"The maximum number of instructions non-inline function can grow to via recursive inlining",
|
||||||
500, 0, 0)
|
450, 0, 0)
|
||||||
|
|
||||||
DEFPARAM (PARAM_MAX_INLINE_RECURSIVE_DEPTH,
|
DEFPARAM (PARAM_MAX_INLINE_RECURSIVE_DEPTH,
|
||||||
"max-inline-recursive-depth",
|
"max-inline-recursive-depth",
|
||||||
|
|
@ -148,7 +147,7 @@ DEFPARAM(PARAM_MAX_PENDING_LIST_LENGTH,
|
||||||
DEFPARAM(PARAM_LARGE_FUNCTION_INSNS,
|
DEFPARAM(PARAM_LARGE_FUNCTION_INSNS,
|
||||||
"large-function-insns",
|
"large-function-insns",
|
||||||
"The size of function body to be considered large",
|
"The size of function body to be considered large",
|
||||||
3000, 0, 0)
|
2700, 0, 0)
|
||||||
DEFPARAM(PARAM_LARGE_FUNCTION_GROWTH,
|
DEFPARAM(PARAM_LARGE_FUNCTION_GROWTH,
|
||||||
"large-function-growth",
|
"large-function-growth",
|
||||||
"Maximal growth due to inlining of large function (in percent)",
|
"Maximal growth due to inlining of large function (in percent)",
|
||||||
|
|
@ -157,6 +156,10 @@ DEFPARAM(PARAM_INLINE_UNIT_GROWTH,
|
||||||
"inline-unit-growth",
|
"inline-unit-growth",
|
||||||
"how much can given compilation unit grow because of the inlining (in percent)",
|
"how much can given compilation unit grow because of the inlining (in percent)",
|
||||||
50, 0, 0)
|
50, 0, 0)
|
||||||
|
DEFPARAM(PARAM_INLINE_CALL_COST,
|
||||||
|
"inline-call-cost",
|
||||||
|
"expense of call operation relative to ordinary aritmetic operations",
|
||||||
|
16, 0, 0)
|
||||||
|
|
||||||
/* The GCSE optimization will be disabled if it would require
|
/* The GCSE optimization will be disabled if it would require
|
||||||
significantly more memory than this value. */
|
significantly more memory than this value. */
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,9 @@
|
||||||
|
2005-03-22 Richard Guenther <rguenth@tat.physik.uni-tuebingen.de>
|
||||||
|
Jan Hubicka <jh@suse.cz>
|
||||||
|
Steven Bosscher <stevenb@suse.de
|
||||||
|
|
||||||
|
* gcc.dg/winline-6.c: Modify so inlined function have nonzero cost.
|
||||||
|
|
||||||
2005-03-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
2005-03-22 Volker Reichelt <reichelt@igpm.rwth-aachen.de>
|
||||||
|
|
||||||
PR c++/19980
|
PR c++/19980
|
||||||
|
|
|
||||||
|
|
@ -17,5 +17,5 @@ inline int q(void)
|
||||||
}
|
}
|
||||||
inline int t (void)
|
inline int t (void)
|
||||||
{
|
{
|
||||||
return q (); /* { dg-warning "called from here" } */
|
return q () + 1; /* { dg-warning "called from here" } */
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1164,6 +1164,23 @@ inlinable_function_p (tree fn)
|
||||||
return inlinable;
|
return inlinable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Estimate the cost of a memory move. Use machine dependent
|
||||||
|
word size and take possible memcpy call into account. */
|
||||||
|
|
||||||
|
int
|
||||||
|
estimate_move_cost (tree type)
|
||||||
|
{
|
||||||
|
HOST_WIDE_INT size;
|
||||||
|
|
||||||
|
size = int_size_in_bytes (type);
|
||||||
|
|
||||||
|
if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO)
|
||||||
|
/* Cost of a memcpy call, 3 arguments and the call. */
|
||||||
|
return 4;
|
||||||
|
else
|
||||||
|
return ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
|
||||||
|
}
|
||||||
|
|
||||||
/* Used by estimate_num_insns. Estimate number of instructions seen
|
/* Used by estimate_num_insns. Estimate number of instructions seen
|
||||||
by given statement. */
|
by given statement. */
|
||||||
|
|
||||||
|
|
@ -1242,28 +1259,50 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
|
||||||
*walk_subtrees = 0;
|
*walk_subtrees = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Recognize assignments of large structures and constructors of
|
/* Try to estimate the cost of assignments. We have three cases to
|
||||||
big arrays. */
|
deal with:
|
||||||
|
1) Simple assignments to registers;
|
||||||
|
2) Stores to things that must live in memory. This includes
|
||||||
|
"normal" stores to scalars, but also assignments of large
|
||||||
|
structures, or constructors of big arrays;
|
||||||
|
3) TARGET_EXPRs.
|
||||||
|
|
||||||
|
Let us look at the first two cases, assuming we have "a = b + C":
|
||||||
|
<modify_expr <var_decl "a"> <plus_expr <var_decl "b"> <constant C>>
|
||||||
|
If "a" is a GIMPLE register, the assignment to it is free on almost
|
||||||
|
any target, because "a" usually ends up in a real register. Hence
|
||||||
|
the only cost of this expression comes from the PLUS_EXPR, and we
|
||||||
|
can ignore the MODIFY_EXPR.
|
||||||
|
If "a" is not a GIMPLE register, the assignment to "a" will most
|
||||||
|
likely be a real store, so the cost of the MODIFY_EXPR is the cost
|
||||||
|
of moving something into "a", which we compute using the function
|
||||||
|
estimate_move_cost.
|
||||||
|
|
||||||
|
The third case deals with TARGET_EXPRs, for which the semantics are
|
||||||
|
that a temporary is assigned, unless the TARGET_EXPR itself is being
|
||||||
|
assigned to something else. In the latter case we do not need the
|
||||||
|
temporary. E.g. in <modify_expr <var_decl "a"> <target_expr>>, the
|
||||||
|
MODIFY_EXPR is free. */
|
||||||
case INIT_EXPR:
|
case INIT_EXPR:
|
||||||
case MODIFY_EXPR:
|
case MODIFY_EXPR:
|
||||||
x = TREE_OPERAND (x, 0);
|
/* Is the right and side a TARGET_EXPR? */
|
||||||
/* FALLTHRU */
|
if (TREE_CODE (TREE_OPERAND (x, 1)) == TARGET_EXPR)
|
||||||
|
break;
|
||||||
|
/* ... fall through ... */
|
||||||
|
|
||||||
case TARGET_EXPR:
|
case TARGET_EXPR:
|
||||||
|
x = TREE_OPERAND (x, 0);
|
||||||
|
/* Is this an assignments to a register? */
|
||||||
|
if (is_gimple_reg (x))
|
||||||
|
break;
|
||||||
|
/* Otherwise it's a store, so fall through to compute the move cost. */
|
||||||
|
|
||||||
case CONSTRUCTOR:
|
case CONSTRUCTOR:
|
||||||
{
|
*count += estimate_move_cost (TREE_TYPE (x));
|
||||||
HOST_WIDE_INT size;
|
|
||||||
|
|
||||||
size = int_size_in_bytes (TREE_TYPE (x));
|
|
||||||
|
|
||||||
if (size < 0 || size > MOVE_MAX_PIECES * MOVE_RATIO)
|
|
||||||
*count += 10;
|
|
||||||
else
|
|
||||||
*count += ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Assign cost of 1 to usual operations.
|
/* Assign cost of 1 to usual operations.
|
||||||
??? We may consider mapping RTL costs to this. */
|
??? We may consider mapping RTL costs to this. */
|
||||||
case COND_EXPR:
|
case COND_EXPR:
|
||||||
|
|
||||||
case PLUS_EXPR:
|
case PLUS_EXPR:
|
||||||
|
|
@ -1350,6 +1389,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
|
||||||
case CALL_EXPR:
|
case CALL_EXPR:
|
||||||
{
|
{
|
||||||
tree decl = get_callee_fndecl (x);
|
tree decl = get_callee_fndecl (x);
|
||||||
|
tree arg;
|
||||||
|
|
||||||
if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
|
if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
|
||||||
switch (DECL_FUNCTION_CODE (decl))
|
switch (DECL_FUNCTION_CODE (decl))
|
||||||
|
|
@ -1362,7 +1402,12 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
*count += 10;
|
|
||||||
|
arg = TREE_OPERAND (x, 1);
|
||||||
|
for (arg = TREE_OPERAND (x, 1); arg; arg = TREE_CHAIN (arg))
|
||||||
|
*count += estimate_move_cost (TREE_TYPE (TREE_VALUE (arg)));
|
||||||
|
|
||||||
|
*count += PARAM_VALUE (PARAM_INLINE_CALL_COST);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ bool tree_inlinable_function_p (tree);
|
||||||
tree copy_tree_r (tree *, int *, void *);
|
tree copy_tree_r (tree *, int *, void *);
|
||||||
void clone_body (tree, tree, void *);
|
void clone_body (tree, tree, void *);
|
||||||
tree save_body (tree, tree *, tree *);
|
tree save_body (tree, tree *, tree *);
|
||||||
|
int estimate_move_cost (tree type);
|
||||||
int estimate_num_insns (tree expr);
|
int estimate_num_insns (tree expr);
|
||||||
|
|
||||||
/* 0 if we should not perform inlining.
|
/* 0 if we should not perform inlining.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue