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
8 changed files with 130 additions and 34 deletions
|
@ -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>
|
||||
|
||||
* 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,
|
||||
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. */
|
||||
|
@ -1124,7 +1129,8 @@ cgraph_mark_inline_edge (struct cgraph_edge *e)
|
|||
to->global.insns = new_insns;
|
||||
}
|
||||
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++;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
will consider for inlining. This only affects functions declared
|
||||
inline and methods implemented in a class declaration (C++).
|
||||
The default value is 500.
|
||||
The default value is 450.
|
||||
|
||||
@item max-inline-insns-auto
|
||||
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
|
||||
(more restrictive) limit compared to functions declared inline can
|
||||
be applied.
|
||||
The default value is 120.
|
||||
The default value is 90.
|
||||
|
||||
@item large-function-insns
|
||||
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
|
||||
backend.
|
||||
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
|
||||
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
|
||||
happens only when @option{-finline-functions} (included in @option{-O3}) is
|
||||
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
|
||||
@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
|
||||
happens only when @option{-finline-functions} (included in @option{-O3}) is
|
||||
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
|
||||
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
|
||||
real machine instructions) that is eligible for inlining
|
||||
by the tree inliner.
|
||||
The default value is 500.
|
||||
The default value is 450.
|
||||
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.
|
||||
definition for C++) are affected by this.
|
||||
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
|
||||
|
@ -70,7 +69,7 @@ DEFPARAM (PARAM_SRA_FIELD_STRUCTURE_RATIO,
|
|||
DEFPARAM (PARAM_MAX_INLINE_INSNS_SINGLE,
|
||||
"max-inline-insns-single",
|
||||
"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
|
||||
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
|
||||
class declaration in C++) given by the "max-inline-insns-single"
|
||||
parameter.
|
||||
The default value is 150. */
|
||||
The default value is 90. */
|
||||
DEFPARAM (PARAM_MAX_INLINE_INSNS_AUTO,
|
||||
"max-inline-insns-auto",
|
||||
"The maximum number of instructions when automatically inlining",
|
||||
120, 0, 0)
|
||||
90, 0, 0)
|
||||
|
||||
DEFPARAM (PARAM_MAX_INLINE_INSNS_RECURSIVE,
|
||||
"max-inline-insns-recursive",
|
||||
"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,
|
||||
"max-inline-insns-recursive-auto",
|
||||
"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,
|
||||
"max-inline-recursive-depth",
|
||||
|
@ -148,7 +147,7 @@ DEFPARAM(PARAM_MAX_PENDING_LIST_LENGTH,
|
|||
DEFPARAM(PARAM_LARGE_FUNCTION_INSNS,
|
||||
"large-function-insns",
|
||||
"The size of function body to be considered large",
|
||||
3000, 0, 0)
|
||||
2700, 0, 0)
|
||||
DEFPARAM(PARAM_LARGE_FUNCTION_GROWTH,
|
||||
"large-function-growth",
|
||||
"Maximal growth due to inlining of large function (in percent)",
|
||||
|
@ -157,6 +156,10 @@ DEFPARAM(PARAM_INLINE_UNIT_GROWTH,
|
|||
"inline-unit-growth",
|
||||
"how much can given compilation unit grow because of the inlining (in percent)",
|
||||
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
|
||||
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>
|
||||
|
||||
PR c++/19980
|
||||
|
|
|
@ -17,5 +17,5 @@ inline int q(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;
|
||||
}
|
||||
|
||||
/* 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
|
||||
by given statement. */
|
||||
|
||||
|
@ -1242,28 +1259,50 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
|
|||
*walk_subtrees = 0;
|
||||
return NULL;
|
||||
|
||||
/* Recognize assignments of large structures and constructors of
|
||||
big arrays. */
|
||||
/* Try to estimate the cost of assignments. We have three cases to
|
||||
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 MODIFY_EXPR:
|
||||
x = TREE_OPERAND (x, 0);
|
||||
/* FALLTHRU */
|
||||
/* Is the right and side a TARGET_EXPR? */
|
||||
if (TREE_CODE (TREE_OPERAND (x, 1)) == TARGET_EXPR)
|
||||
break;
|
||||
/* ... fall through ... */
|
||||
|
||||
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:
|
||||
{
|
||||
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);
|
||||
}
|
||||
*count += estimate_move_cost (TREE_TYPE (x));
|
||||
break;
|
||||
|
||||
/* Assign cost of 1 to usual operations.
|
||||
??? We may consider mapping RTL costs to this. */
|
||||
/* Assign cost of 1 to usual operations.
|
||||
??? We may consider mapping RTL costs to this. */
|
||||
case COND_EXPR:
|
||||
|
||||
case PLUS_EXPR:
|
||||
|
@ -1350,6 +1389,7 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
|
|||
case CALL_EXPR:
|
||||
{
|
||||
tree decl = get_callee_fndecl (x);
|
||||
tree arg;
|
||||
|
||||
if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
|
||||
switch (DECL_FUNCTION_CODE (decl))
|
||||
|
@ -1362,7 +1402,12 @@ estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
|
|||
default:
|
||||
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;
|
||||
}
|
||||
default:
|
||||
|
|
|
@ -29,6 +29,7 @@ bool tree_inlinable_function_p (tree);
|
|||
tree copy_tree_r (tree *, int *, void *);
|
||||
void clone_body (tree, tree, void *);
|
||||
tree save_body (tree, tree *, tree *);
|
||||
int estimate_move_cost (tree type);
|
||||
int estimate_num_insns (tree expr);
|
||||
|
||||
/* 0 if we should not perform inlining.
|
||||
|
|
Loading…
Add table
Reference in a new issue