summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog26
-rw-r--r--gcc/cgraphunit.c10
-rw-r--r--gcc/doc/invoke.texi19
-rw-r--r--gcc/params.def21
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/gcc.dg/winline-6.c2
-rw-r--r--gcc/tree-inline.c79
-rw-r--r--gcc/tree-inline.h1
8 files changed, 130 insertions, 34 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3a92893b1ba..a48a35e5a2e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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)
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index db0aaaf2ada..6e864d5e243 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -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++;
}
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2e08c4f3cdb..bd9f4302de7 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -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
diff --git a/gcc/params.def b/gcc/params.def
index c424ad59f10..64cb88040e6 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 51f81b9f551..6ea0ee910a5 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/winline-6.c b/gcc/testsuite/gcc.dg/winline-6.c
index 7ce7481a3ef..dd8d3a81b08 100644
--- a/gcc/testsuite/gcc.dg/winline-6.c
+++ b/gcc/testsuite/gcc.dg/winline-6.c
@@ -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" } */
}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index c20c0744c70..6f46eed8c36 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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:
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index a8e9de6c4c8..467f6bb929f 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -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.