Commit 749f25d8 by Jan Hubicka Committed by Jan Hubicka

ipa-cp.c (ipcp_versionable_function_p): Aliases are not versionable.

	* ipa-cp.c (ipcp_versionable_function_p): Aliases are not versionable.
	(ipcp_cloning_candidate_p): Aliases are not clonning candidates.
	(ipcp_initialize_node_lattices): We don't propagate through an aliases.
	(ipcp_propagate_stage): Skip aliases when propagating.
	(ipcp_need_redirect_p): Skip aliases.
	(ipcp_insert_stage): Use FOR_EACH_FUNCTION_WITH_GIMPLE_BODY and
	collect_callers_of_node.
	* ipa-prop.c (ipa_init_func_list): Do not analyze datastructures
	for aliases.
	(ipa_compute_jump_functions): Look through aliases.

From-SVN: r174911
parent 9c8cf7b7
2011-06-10 Jan Hubicka <jh@suse.cz>
* ipa-cp.c (ipcp_versionable_function_p): Aliases are not versionable.
(ipcp_cloning_candidate_p): Aliases are not clonning candidates.
(ipcp_initialize_node_lattices): We don't propagate through an aliases.
(ipcp_propagate_stage): Skip aliases when propagating.
(ipcp_need_redirect_p): Skip aliases.
(ipcp_insert_stage): Use FOR_EACH_FUNCTION_WITH_GIMPLE_BODY and
collect_callers_of_node.
* ipa-prop.c (ipa_init_func_list): Do not analyze datastructures
for aliases.
(ipa_compute_jump_functions): Look through aliases.
2011-06-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> 2011-06-10 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* doc/sourcebuild.texi (Effective-Target Keywords, pie): Document it. * doc/sourcebuild.texi (Effective-Target Keywords, pie): Document it.
......
...@@ -350,6 +350,10 @@ ipcp_versionable_function_p (struct cgraph_node *node) ...@@ -350,6 +350,10 @@ ipcp_versionable_function_p (struct cgraph_node *node)
{ {
struct cgraph_edge *edge; struct cgraph_edge *edge;
/* We always version the actual function and redirect through the aliases. */
if (node->alias)
return false;
/* There are a number of generic reasons functions cannot be versioned. We /* There are a number of generic reasons functions cannot be versioned. We
also cannot remove parameters if there are type attributes such as fnspec also cannot remove parameters if there are type attributes such as fnspec
present. */ present. */
...@@ -358,7 +362,8 @@ ipcp_versionable_function_p (struct cgraph_node *node) ...@@ -358,7 +362,8 @@ ipcp_versionable_function_p (struct cgraph_node *node)
return false; return false;
/* Removing arguments doesn't work if the function takes varargs /* Removing arguments doesn't work if the function takes varargs
or use __builtin_apply_args. */ or use __builtin_apply_args.
FIXME: handle this together with can_change_signature flag. */
for (edge = node->callees; edge; edge = edge->next_callee) for (edge = node->callees; edge; edge = edge->next_callee)
{ {
tree t = edge->callee->decl; tree t = edge->callee->decl;
...@@ -380,6 +385,10 @@ ipcp_cloning_candidate_p (struct cgraph_node *node) ...@@ -380,6 +385,10 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
gcov_type direct_call_sum = 0; gcov_type direct_call_sum = 0;
struct cgraph_edge *e; struct cgraph_edge *e;
/* We look through aliases, so we clone the aliased function instead. */
if (node->alias)
return false;
/* We never clone functions that are not visible from outside. /* We never clone functions that are not visible from outside.
FIXME: in future we should clone such functions when they are called with FIXME: in future we should clone such functions when they are called with
different constants, but current ipcp implementation is not good on this. different constants, but current ipcp implementation is not good on this.
...@@ -498,7 +507,7 @@ ipcp_initialize_node_lattices (struct cgraph_node *node) ...@@ -498,7 +507,7 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
struct ipa_node_params *info = IPA_NODE_REF (node); struct ipa_node_params *info = IPA_NODE_REF (node);
enum ipa_lattice_type type; enum ipa_lattice_type type;
if (ipa_is_called_with_var_arguments (info)) if (ipa_is_called_with_var_arguments (info) || node->alias)
type = IPA_BOTTOM; type = IPA_BOTTOM;
else if (node->local.local) else if (node->local.local)
type = IPA_TOP; type = IPA_TOP;
...@@ -759,7 +768,8 @@ ipcp_propagate_stage (void) ...@@ -759,7 +768,8 @@ ipcp_propagate_stage (void)
for (cs = node->callees; cs; cs = cs->next_callee) for (cs = node->callees; cs; cs = cs->next_callee)
{ {
struct ipa_node_params *callee_info = IPA_NODE_REF (cs->callee); struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee, NULL);
struct ipa_node_params *callee_info = IPA_NODE_REF (callee);
struct ipa_edge_args *args = IPA_EDGE_REF (cs); struct ipa_edge_args *args = IPA_EDGE_REF (cs);
if (ipa_is_called_with_var_arguments (callee_info) if (ipa_is_called_with_var_arguments (callee_info)
...@@ -778,11 +788,11 @@ ipcp_propagate_stage (void) ...@@ -778,11 +788,11 @@ ipcp_propagate_stage (void)
{ {
dest_lat->type = new_lat.type; dest_lat->type = new_lat.type;
dest_lat->constant = new_lat.constant; dest_lat->constant = new_lat.constant;
ipa_push_func_to_list (&wl, cs->callee); ipa_push_func_to_list (&wl, callee);
} }
if (ipcp_propagate_types (info, callee_info, jump_func, i)) if (ipcp_propagate_types (info, callee_info, jump_func, i))
ipa_push_func_to_list (&wl, cs->callee); ipa_push_func_to_list (&wl, callee);
} }
} }
} }
...@@ -818,7 +828,7 @@ ipcp_iterate_stage (void) ...@@ -818,7 +828,7 @@ ipcp_iterate_stage (void)
/* Some lattices have changed from IPA_TOP to IPA_BOTTOM. /* Some lattices have changed from IPA_TOP to IPA_BOTTOM.
This change should be propagated. */ This change should be propagated. */
{ {
gcc_assert (n_cloning_candidates); /*gcc_assert (n_cloning_candidates);*/
ipcp_propagate_stage (); ipcp_propagate_stage ();
} }
if (dump_file) if (dump_file)
...@@ -946,7 +956,8 @@ ipcp_need_redirect_p (struct cgraph_edge *cs) ...@@ -946,7 +956,8 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
{ {
struct ipa_node_params *orig_callee_info; struct ipa_node_params *orig_callee_info;
int i, count; int i, count;
struct cgraph_node *node = cs->callee, *orig; struct cgraph_node *node = cgraph_function_or_thunk_node (cs->callee, NULL);
struct cgraph_node *orig;
if (!n_cloning_candidates) if (!n_cloning_candidates)
return false; return false;
...@@ -1293,7 +1304,7 @@ ipcp_insert_stage (void) ...@@ -1293,7 +1304,7 @@ ipcp_insert_stage (void)
int i; int i;
VEC (cgraph_edge_p, heap) * redirect_callers; VEC (cgraph_edge_p, heap) * redirect_callers;
VEC (ipa_replace_map_p,gc)* replace_trees; VEC (ipa_replace_map_p,gc)* replace_trees;
int node_callers, count; int count;
tree parm_tree; tree parm_tree;
struct ipa_replace_map *replace_param; struct ipa_replace_map *replace_param;
fibheap_t heap; fibheap_t heap;
...@@ -1307,8 +1318,7 @@ ipcp_insert_stage (void) ...@@ -1307,8 +1318,7 @@ ipcp_insert_stage (void)
dead_nodes = BITMAP_ALLOC (NULL); dead_nodes = BITMAP_ALLOC (NULL);
for (node = cgraph_nodes; node; node = node->next) FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
if (node->analyzed)
{ {
if (node->count > max_count) if (node->count > max_count)
max_count = node->count; max_count = node->count;
...@@ -1413,14 +1423,7 @@ ipcp_insert_stage (void) ...@@ -1413,14 +1423,7 @@ ipcp_insert_stage (void)
if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node)) if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node))
bitmap_set_bit (dead_nodes, node->uid); bitmap_set_bit (dead_nodes, node->uid);
/* Compute how many callers node has. */ redirect_callers = collect_callers_of_node (node);
node_callers = 0;
for (cs = node->callers; cs != NULL; cs = cs->next_caller)
node_callers++;
redirect_callers = VEC_alloc (cgraph_edge_p, heap, node_callers);
for (cs = node->callers; cs != NULL; cs = cs->next_caller)
if (!cs->indirect_inlining_edge)
VEC_quick_push (cgraph_edge_p, redirect_callers, cs);
/* Redirecting all the callers of the node to the /* Redirecting all the callers of the node to the
new versioned node. */ new versioned node. */
...@@ -1452,12 +1455,15 @@ ipcp_insert_stage (void) ...@@ -1452,12 +1455,15 @@ ipcp_insert_stage (void)
dump_function_to_file (node1->decl, dump_file, dump_flags); dump_function_to_file (node1->decl, dump_file, dump_flags);
for (cs = node->callees; cs; cs = cs->next_callee) for (cs = node->callees; cs; cs = cs->next_callee)
if (cs->callee->aux)
{ {
fibheap_delete_node (heap, (fibnode_t) cs->callee->aux); struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee, NULL);
cs->callee->aux = fibheap_insert (heap, if (callee->aux)
ipcp_estimate_cloning_cost (cs->callee), {
cs->callee); fibheap_delete_node (heap, (fibnode_t) callee->aux);
callee->aux = fibheap_insert (heap,
ipcp_estimate_cloning_cost (callee),
callee);
}
} }
} }
......
...@@ -93,7 +93,7 @@ ipa_init_func_list (void) ...@@ -93,7 +93,7 @@ ipa_init_func_list (void)
wl = NULL; wl = NULL;
for (node = cgraph_nodes; node; node = node->next) for (node = cgraph_nodes; node; node = node->next)
if (node->analyzed) if (node->analyzed && !node->alias)
{ {
struct ipa_node_params *info = IPA_NODE_REF (node); struct ipa_node_params *info = IPA_NODE_REF (node);
/* Unreachable nodes should have been eliminated before ipcp and /* Unreachable nodes should have been eliminated before ipcp and
...@@ -1096,6 +1096,7 @@ ipa_compute_jump_functions (struct cgraph_node *node, ...@@ -1096,6 +1096,7 @@ ipa_compute_jump_functions (struct cgraph_node *node,
for (cs = node->callees; cs; cs = cs->next_callee) for (cs = node->callees; cs; cs = cs->next_callee)
{ {
struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee, NULL);
/* We do not need to bother analyzing calls to unknown /* We do not need to bother analyzing calls to unknown
functions unless they may become known during lto/whopr. */ functions unless they may become known during lto/whopr. */
if (!cs->callee->analyzed && !flag_lto) if (!cs->callee->analyzed && !flag_lto)
...@@ -1103,11 +1104,11 @@ ipa_compute_jump_functions (struct cgraph_node *node, ...@@ -1103,11 +1104,11 @@ ipa_compute_jump_functions (struct cgraph_node *node,
ipa_count_arguments (cs); ipa_count_arguments (cs);
/* If the descriptor of the callee is not initialized yet, we have to do /* If the descriptor of the callee is not initialized yet, we have to do
it now. */ it now. */
if (cs->callee->analyzed) if (callee->analyzed)
ipa_initialize_node_params (cs->callee); ipa_initialize_node_params (callee);
if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs)) if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
!= ipa_get_param_count (IPA_NODE_REF (cs->callee))) != ipa_get_param_count (IPA_NODE_REF (callee)))
ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee)); ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
ipa_compute_jump_functions_for_edge (parms_info, cs); ipa_compute_jump_functions_for_edge (parms_info, cs);
} }
......
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