diff options
author | Richard Guenther <rguenth@tat.physik.uni-tuebingen.de> | 2005-03-22 20:53:40 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2005-03-22 20:53:40 +0000 |
commit | e5c4f28a6c44485134c426d5ad4ba3f90cc26a41 (patch) | |
tree | e6caff86555ce9f9639013c3cd82b4c469828776 /gcc/tree-inline.c | |
parent | b360e193505ff0cd9ee72bdb8e232654e625731b (diff) | |
download | gcc-e5c4f28a6c44485134c426d5ad4ba3f90cc26a41.zip gcc-e5c4f28a6c44485134c426d5ad4ba3f90cc26a41.tar.gz gcc-e5c4f28a6c44485134c426d5ad4ba3f90cc26a41.tar.bz2 |
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
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r-- | gcc/tree-inline.c | 79 |
1 files changed, 62 insertions, 17 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index c20c074..6f46eed 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: |