diff options
-rw-r--r-- | gcc/ChangeLog | 26 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 10 | ||||
-rw-r--r-- | gcc/doc/invoke.texi | 19 | ||||
-rw-r--r-- | gcc/params.def | 21 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/winline-6.c | 2 | ||||
-rw-r--r-- | gcc/tree-inline.c | 79 | ||||
-rw-r--r-- | gcc/tree-inline.h | 1 |
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. |