summaryrefslogtreecommitdiff
path: root/gcc/tree-inline.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2009-05-12 14:05:28 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2009-05-12 14:05:28 +0000
commit94e6e3591e3deb7f88b040a7f39d7acdb39e6c20 (patch)
tree63fd58b98168fb3c755ec6145a978b20b41a8e2a /gcc/tree-inline.c
parentd6b07704ce320035dcb03a7f7eda260a67b5d506 (diff)
downloadgcc-94e6e3591e3deb7f88b040a7f39d7acdb39e6c20.tar.gz
* gcc.dg/tree-ssa/loop-36.c: Reduce amount of iterations to 2 so unrolling
still happens. * gcc.dg/ipa/ipacost-1.c: Prevent inlining * gcc.dg/ipa/ipacost-2.c: Likewise. * gcc.dg/vect/slp-3.c: Loop is no longer unrolled. * tree-inline.c (estimate_operator_cost): Add operands; when division happens by constant, it is cheap. (estimate_num_insns): Loads and stores are not having cost of 0; EH magic stuff is cheap; when computing runtime cost of switch, use log2 base of amount of its cases; builtin_expect has cost of 0; compute cost for moving return value of call. (init_inline_once): Initialize time_based flags. * tree-inline.h (eni_weights_d): Add time_based flag. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@147436 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-inline.c')
-rw-r--r--gcc/tree-inline.c44
1 files changed, 37 insertions, 7 deletions
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 752766b6c7b..78cb716d7ad 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -2783,7 +2783,8 @@ estimate_move_cost (tree type)
/* Returns cost of operation CODE, according to WEIGHTS */
static int
-estimate_operator_cost (enum tree_code code, eni_weights *weights)
+estimate_operator_cost (enum tree_code code, eni_weights *weights,
+ tree op1 ATTRIBUTE_UNUSED, tree op2)
{
switch (code)
{
@@ -2893,7 +2894,9 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights)
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
case RDIV_EXPR:
- return weights->div_mod_cost;
+ if (TREE_CODE (op2) != INTEGER_CST)
+ return weights->div_mod_cost;
+ return 1;
default:
/* We expect a copy assignment with no operator. */
@@ -2930,6 +2933,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
unsigned cost, i;
enum gimple_code code = gimple_code (stmt);
tree lhs;
+ tree rhs;
switch (code)
{
@@ -2953,16 +2957,35 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
of moving something into "a", which we compute using the function
estimate_move_cost. */
lhs = gimple_assign_lhs (stmt);
+ rhs = gimple_assign_rhs1 (stmt);
+
+ /* EH magic stuff is most probably going to be optimized out.
+ We rarely really need to save EH info for unwinding
+ nested exceptions. */
+ if (TREE_CODE (lhs) == FILTER_EXPR
+ || TREE_CODE (lhs) == EXC_PTR_EXPR
+ || TREE_CODE (rhs) == FILTER_EXPR
+ || TREE_CODE (rhs) == EXC_PTR_EXPR)
+ return 0;
if (is_gimple_reg (lhs))
cost = 0;
else
cost = estimate_move_cost (TREE_TYPE (lhs));
- cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights);
+ if (!is_gimple_reg (rhs) && !is_gimple_min_invariant (rhs))
+ cost += estimate_move_cost (TREE_TYPE (rhs));
+
+ cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights,
+ gimple_assign_rhs1 (stmt),
+ get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
+ == GIMPLE_BINARY_RHS
+ ? gimple_assign_rhs2 (stmt) : NULL);
break;
case GIMPLE_COND:
- cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights);
+ cost = 1 + estimate_operator_cost (gimple_cond_code (stmt), weights,
+ gimple_op (stmt, 0),
+ gimple_op (stmt, 1));
break;
case GIMPLE_SWITCH:
@@ -2971,7 +2994,10 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
TODO: once the switch expansion logic is sufficiently separated, we can
do better job on estimating cost of the switch. */
- cost = gimple_switch_num_labels (stmt) * 2;
+ if (weights->time_based)
+ cost = floor_log2 (gimple_switch_num_labels (stmt)) * 2;
+ else
+ cost = gimple_switch_num_labels (stmt) * 2;
break;
case GIMPLE_CALL:
@@ -2994,8 +3020,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
case BUILT_IN_CONSTANT_P:
return 0;
case BUILT_IN_EXPECT:
- cost = 0;
- break;
+ return 0;
/* Prefetch instruction is not expensive. */
case BUILT_IN_PREFETCH:
@@ -3009,6 +3034,8 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
if (decl)
funtype = TREE_TYPE (decl);
+ if (!VOID_TYPE_P (TREE_TYPE (funtype)))
+ cost += estimate_move_cost (TREE_TYPE (funtype));
/* Our cost must be kept in sync with
cgraph_estimate_size_after_inlining that does use function
declaration to figure out the arguments. */
@@ -3133,11 +3160,13 @@ init_inline_once (void)
eni_inlining_weights.target_builtin_call_cost = 1;
eni_inlining_weights.div_mod_cost = 10;
eni_inlining_weights.omp_cost = 40;
+ eni_inlining_weights.time_based = true;
eni_size_weights.call_cost = 1;
eni_size_weights.target_builtin_call_cost = 1;
eni_size_weights.div_mod_cost = 1;
eni_size_weights.omp_cost = 40;
+ eni_size_weights.time_based = false;
/* Estimating time for call is difficult, since we have no idea what the
called function does. In the current uses of eni_time_weights,
@@ -3147,6 +3176,7 @@ init_inline_once (void)
eni_time_weights.target_builtin_call_cost = 10;
eni_time_weights.div_mod_cost = 10;
eni_time_weights.omp_cost = 40;
+ eni_time_weights.time_based = true;
}
/* Estimate the number of instructions in a gimple_seq. */