Commit d2d668fb by Maxim Kuvyrkov Committed by Maxim Kuvyrkov

ipa-cp.c (ipa_value_from_jfunc): Make global.

	* ipa-cp.c (ipa_value_from_jfunc): Make global.
	(ipa_cst_from_jfunc): Remove, use ipa_value_from_jfunc instead.
	(get_indirect_edge_target): Rename, make global.
	(devirtualization_time_bonus, estimate_local_effects,)
	(ipcp_discover_new_direct_edges): Update.
	* ipa-inline-analysis.c (evaluate_conditions_for_edge):
	Generalize to also handle types.  Rename to ...
	(evaluate_properties_for_edge): Use instead of
	evaluate_conditions_for_edge.
	(estimate_edge_devirt_benefit): New function.
	(estimate_calls_size_and_time): Use it.
	(estimate_node_size_and_time, estimate_ipcp_clone_size_and_time,)
	(inline_merge_summary):	Update.
	(do_estimate_edge_time, do_estimate_edge_growth): Update.  Calculate
	parameter information at the call site and pass it on to subroutines.
	* tree-inline.c (estimate_num_insns): Distinguish between direct and
	indirect calls.
	(init_inline_once): Set size and time costs or indirect calls.
	* tree-inline.h (eni_weights): Add indirect_call_cost.

From-SVN: r181377
parent e3790e8a
2011-11-15 Maxim Kuvyrkov <maxim@codesourcery.com>
* ipa-cp.c (ipa_value_from_jfunc): Make global.
(ipa_cst_from_jfunc): Remove, use ipa_value_from_jfunc instead.
(get_indirect_edge_target): Rename, make global.
(devirtualization_time_bonus, estimate_local_effects,)
(ipcp_discover_new_direct_edges): Update.
* ipa-inline-analysis.c (evaluate_conditions_for_edge):
Generalize to also handle types. Rename to ...
(evaluate_properties_for_edge): Use instead of
evaluate_conditions_for_edge.
(estimate_edge_devirt_benefit): New function.
(estimate_calls_size_and_time): Use it.
(estimate_node_size_and_time, estimate_ipcp_clone_size_and_time,)
(inline_merge_summary): Update.
(do_estimate_edge_time, do_estimate_edge_growth): Update. Calculate
parameter information at the call site and pass it on to subroutines.
* tree-inline.c (estimate_num_insns): Distinguish between direct and
indirect calls.
(init_inline_once): Set size and time costs or indirect calls.
* tree-inline.h (eni_weights): Add indirect_call_cost.
2011-11-15 Tom de Vries <tom@codesourcery.com> 2011-11-15 Tom de Vries <tom@codesourcery.com>
PR tree-optimization/51005 PR tree-optimization/51005
...@@ -693,7 +693,7 @@ ipa_value_from_known_type_jfunc (struct ipa_jump_func *jfunc) ...@@ -693,7 +693,7 @@ ipa_value_from_known_type_jfunc (struct ipa_jump_func *jfunc)
describes the caller node so that pass-through jump functions can be describes the caller node so that pass-through jump functions can be
evaluated. */ evaluated. */
static tree tree
ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
{ {
if (jfunc->type == IPA_JF_CONST) if (jfunc->type == IPA_JF_CONST)
...@@ -753,21 +753,6 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) ...@@ -753,21 +753,6 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
return NULL_TREE; return NULL_TREE;
} }
/* Determine whether JFUNC evaluates to a constant and if so, return it.
Otherwise return NULL. INFO describes the caller node so that pass-through
jump functions can be evaluated. */
tree
ipa_cst_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc)
{
tree res = ipa_value_from_jfunc (info, jfunc);
if (res && TREE_CODE (res) == TREE_BINFO)
return NULL_TREE;
else
return res;
}
/* If checking is enabled, verify that no lattice is in the TOP state, i.e. not /* If checking is enabled, verify that no lattice is in the TOP state, i.e. not
bottom, not containing a variable component and without any known value at bottom, not containing a variable component and without any known value at
...@@ -1112,10 +1097,10 @@ propagate_constants_accross_call (struct cgraph_edge *cs) ...@@ -1112,10 +1097,10 @@ propagate_constants_accross_call (struct cgraph_edge *cs)
(which can contain both constants and binfos) or KNOWN_BINFOS (which can be (which can contain both constants and binfos) or KNOWN_BINFOS (which can be
NULL) return the destination. */ NULL) return the destination. */
static tree tree
get_indirect_edge_target (struct cgraph_edge *ie, ipa_get_indirect_edge_target (struct cgraph_edge *ie,
VEC (tree, heap) *known_vals, VEC (tree, heap) *known_vals,
VEC (tree, heap) *known_binfos) VEC (tree, heap) *known_binfos)
{ {
int param_index = ie->indirect_info->param_index; int param_index = ie->indirect_info->param_index;
HOST_WIDE_INT token, anc_offset; HOST_WIDE_INT token, anc_offset;
...@@ -1185,7 +1170,7 @@ devirtualization_time_bonus (struct cgraph_node *node, ...@@ -1185,7 +1170,7 @@ devirtualization_time_bonus (struct cgraph_node *node,
struct inline_summary *isummary; struct inline_summary *isummary;
tree target; tree target;
target = get_indirect_edge_target (ie, known_csts, known_binfos); target = ipa_get_indirect_edge_target (ie, known_csts, known_binfos);
if (!target) if (!target)
continue; continue;
...@@ -1344,7 +1329,8 @@ estimate_local_effects (struct cgraph_node *node) ...@@ -1344,7 +1329,8 @@ estimate_local_effects (struct cgraph_node *node)
init_caller_stats (&stats); init_caller_stats (&stats);
cgraph_for_node_and_aliases (node, gather_caller_stats, &stats, false); cgraph_for_node_and_aliases (node, gather_caller_stats, &stats, false);
estimate_ipcp_clone_size_and_time (node, known_csts, &size, &time); estimate_ipcp_clone_size_and_time (node, known_csts, known_binfos,
&size, &time);
time -= devirtualization_time_bonus (node, known_csts, known_binfos); time -= devirtualization_time_bonus (node, known_csts, known_binfos);
time -= removable_params_cost; time -= removable_params_cost;
size -= stats.n_calls * removable_params_cost; size -= stats.n_calls * removable_params_cost;
...@@ -1415,7 +1401,8 @@ estimate_local_effects (struct cgraph_node *node) ...@@ -1415,7 +1401,8 @@ estimate_local_effects (struct cgraph_node *node)
else else
continue; continue;
estimate_ipcp_clone_size_and_time (node, known_csts, &size, &time); estimate_ipcp_clone_size_and_time (node, known_csts, known_binfos,
&size, &time);
time_benefit = base_time - time time_benefit = base_time - time
+ devirtualization_time_bonus (node, known_csts, known_binfos) + devirtualization_time_bonus (node, known_csts, known_binfos)
+ removable_params_cost + emc; + removable_params_cost + emc;
...@@ -1673,7 +1660,7 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node, ...@@ -1673,7 +1660,7 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
tree target; tree target;
next_ie = ie->next_callee; next_ie = ie->next_callee;
target = get_indirect_edge_target (ie, known_vals, NULL); target = ipa_get_indirect_edge_target (ie, known_vals, NULL);
if (target) if (target)
ipa_make_edge_direct_to_target (ie, target); ipa_make_edge_direct_to_target (ie, target);
} }
......
...@@ -169,6 +169,7 @@ int estimate_time_after_inlining (struct cgraph_node *, struct cgraph_edge *); ...@@ -169,6 +169,7 @@ int estimate_time_after_inlining (struct cgraph_node *, struct cgraph_edge *);
int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *); int estimate_size_after_inlining (struct cgraph_node *, struct cgraph_edge *);
void estimate_ipcp_clone_size_and_time (struct cgraph_node *, void estimate_ipcp_clone_size_and_time (struct cgraph_node *,
VEC (tree, heap) *known_vals, VEC (tree, heap) *known_vals,
VEC (tree, heap) *known_binfos,
int *, int *); int *, int *);
int do_estimate_growth (struct cgraph_node *); int do_estimate_growth (struct cgraph_node *);
void inline_merge_summary (struct cgraph_edge *edge); void inline_merge_summary (struct cgraph_edge *edge);
......
...@@ -346,6 +346,9 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs, ...@@ -346,6 +346,9 @@ bool ipa_propagate_indirect_call_infos (struct cgraph_edge *cs,
VEC (cgraph_edge_p, heap) **new_edges); VEC (cgraph_edge_p, heap) **new_edges);
/* Indirect edge and binfo processing. */ /* Indirect edge and binfo processing. */
tree ipa_get_indirect_edge_target (struct cgraph_edge *ie,
VEC (tree, heap) *known_csts,
VEC (tree, heap) *known_binfs);
struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree); struct cgraph_edge *ipa_make_edge_direct_to_target (struct cgraph_edge *, tree);
/* Functions related to both. */ /* Functions related to both. */
...@@ -437,8 +440,8 @@ void ipa_prop_write_jump_functions (cgraph_node_set set); ...@@ -437,8 +440,8 @@ void ipa_prop_write_jump_functions (cgraph_node_set set);
void ipa_prop_read_jump_functions (void); void ipa_prop_read_jump_functions (void);
void ipa_update_after_lto_read (void); void ipa_update_after_lto_read (void);
int ipa_get_param_decl_index (struct ipa_node_params *, tree); int ipa_get_param_decl_index (struct ipa_node_params *, tree);
tree ipa_cst_from_jfunc (struct ipa_node_params *info, tree ipa_value_from_jfunc (struct ipa_node_params *info,
struct ipa_jump_func *jfunc); struct ipa_jump_func *jfunc);
/* From tree-sra.c: */ /* From tree-sra.c: */
......
...@@ -3521,7 +3521,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights) ...@@ -3521,7 +3521,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
case GIMPLE_CALL: case GIMPLE_CALL:
{ {
tree decl = gimple_call_fndecl (stmt); tree decl = gimple_call_fndecl (stmt);
struct cgraph_node *node; struct cgraph_node *node = NULL;
/* Do not special case builtins where we see the body. /* Do not special case builtins where we see the body.
This just confuse inliner. */ This just confuse inliner. */
...@@ -3556,7 +3556,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights) ...@@ -3556,7 +3556,7 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
} }
} }
cost = weights->call_cost; cost = node ? weights->call_cost : weights->indirect_call_cost;
if (gimple_call_lhs (stmt)) if (gimple_call_lhs (stmt))
cost += estimate_move_cost (TREE_TYPE (gimple_call_lhs (stmt))); cost += estimate_move_cost (TREE_TYPE (gimple_call_lhs (stmt)));
for (i = 0; i < gimple_call_num_args (stmt); i++) for (i = 0; i < gimple_call_num_args (stmt); i++)
...@@ -3674,6 +3674,7 @@ void ...@@ -3674,6 +3674,7 @@ void
init_inline_once (void) init_inline_once (void)
{ {
eni_size_weights.call_cost = 1; eni_size_weights.call_cost = 1;
eni_size_weights.indirect_call_cost = 3;
eni_size_weights.target_builtin_call_cost = 1; eni_size_weights.target_builtin_call_cost = 1;
eni_size_weights.div_mod_cost = 1; eni_size_weights.div_mod_cost = 1;
eni_size_weights.omp_cost = 40; eni_size_weights.omp_cost = 40;
...@@ -3686,6 +3687,7 @@ init_inline_once (void) ...@@ -3686,6 +3687,7 @@ init_inline_once (void)
underestimating the cost does less harm than overestimating it, so underestimating the cost does less harm than overestimating it, so
we choose a rather small value here. */ we choose a rather small value here. */
eni_time_weights.call_cost = 10; eni_time_weights.call_cost = 10;
eni_time_weights.indirect_call_cost = 15;
eni_time_weights.target_builtin_call_cost = 1; eni_time_weights.target_builtin_call_cost = 1;
eni_time_weights.div_mod_cost = 10; eni_time_weights.div_mod_cost = 10;
eni_time_weights.omp_cost = 40; eni_time_weights.omp_cost = 40;
......
...@@ -135,6 +135,9 @@ typedef struct eni_weights_d ...@@ -135,6 +135,9 @@ typedef struct eni_weights_d
/* Cost per call. */ /* Cost per call. */
unsigned call_cost; unsigned call_cost;
/* Cost per indirect call. */
unsigned indirect_call_cost;
/* Cost per call to a target specific builtin */ /* Cost per call to a target specific builtin */
unsigned target_builtin_call_cost; unsigned target_builtin_call_cost;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment