aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-cp.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2011-06-10 14:57:05 +0000
committerJan Hubicka <jh@suse.cz>2011-06-10 14:57:05 +0000
commitf18d008afda96af649888d2c1f9897b3ac044040 (patch)
treefb7d5174686aae02adc1c28679cbb08b775dee5e /gcc/ipa-cp.c
parent4d18634503392bbb74361e5b13aebe3f2aaf72eb (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@174911 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-cp.c')
-rw-r--r--gcc/ipa-cp.c66
1 files changed, 36 insertions, 30 deletions
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 992f1858983..94aab5f5f76 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -350,6 +350,10 @@ ipcp_versionable_function_p (struct cgraph_node *node)
{
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
also cannot remove parameters if there are type attributes such as fnspec
present. */
@@ -358,7 +362,8 @@ ipcp_versionable_function_p (struct cgraph_node *node)
return false;
/* 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)
{
tree t = edge->callee->decl;
@@ -380,6 +385,10 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
gcov_type direct_call_sum = 0;
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.
FIXME: in future we should clone such functions when they are called with
different constants, but current ipcp implementation is not good on this.
@@ -498,7 +507,7 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
struct ipa_node_params *info = IPA_NODE_REF (node);
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;
else if (node->local.local)
type = IPA_TOP;
@@ -759,7 +768,8 @@ ipcp_propagate_stage (void)
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);
if (ipa_is_called_with_var_arguments (callee_info)
@@ -778,11 +788,11 @@ ipcp_propagate_stage (void)
{
dest_lat->type = new_lat.type;
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))
- ipa_push_func_to_list (&wl, cs->callee);
+ ipa_push_func_to_list (&wl, callee);
}
}
}
@@ -818,7 +828,7 @@ ipcp_iterate_stage (void)
/* Some lattices have changed from IPA_TOP to IPA_BOTTOM.
This change should be propagated. */
{
- gcc_assert (n_cloning_candidates);
+ /*gcc_assert (n_cloning_candidates);*/
ipcp_propagate_stage ();
}
if (dump_file)
@@ -946,7 +956,8 @@ ipcp_need_redirect_p (struct cgraph_edge *cs)
{
struct ipa_node_params *orig_callee_info;
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)
return false;
@@ -1293,7 +1304,7 @@ ipcp_insert_stage (void)
int i;
VEC (cgraph_edge_p, heap) * redirect_callers;
VEC (ipa_replace_map_p,gc)* replace_trees;
- int node_callers, count;
+ int count;
tree parm_tree;
struct ipa_replace_map *replace_param;
fibheap_t heap;
@@ -1307,13 +1318,12 @@ ipcp_insert_stage (void)
dead_nodes = BITMAP_ALLOC (NULL);
- for (node = cgraph_nodes; node; node = node->next)
- if (node->analyzed)
- {
- if (node->count > max_count)
- max_count = node->count;
- overall_size += inline_summary (node)->self_size;
- }
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
+ {
+ if (node->count > max_count)
+ max_count = node->count;
+ overall_size += inline_summary (node)->self_size;
+ }
max_new_size = overall_size;
if (max_new_size < PARAM_VALUE (PARAM_LARGE_UNIT_INSNS))
@@ -1413,14 +1423,7 @@ ipcp_insert_stage (void)
if (!cs && cgraph_will_be_removed_from_program_if_no_direct_calls (node))
bitmap_set_bit (dead_nodes, node->uid);
- /* Compute how many callers node has. */
- 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);
+ redirect_callers = collect_callers_of_node (node);
/* Redirecting all the callers of the node to the
new versioned node. */
@@ -1452,13 +1455,16 @@ ipcp_insert_stage (void)
dump_function_to_file (node1->decl, dump_file, dump_flags);
for (cs = node->callees; cs; cs = cs->next_callee)
- if (cs->callee->aux)
- {
- fibheap_delete_node (heap, (fibnode_t) cs->callee->aux);
- cs->callee->aux = fibheap_insert (heap,
- ipcp_estimate_cloning_cost (cs->callee),
- cs->callee);
- }
+ {
+ struct cgraph_node *callee = cgraph_function_or_thunk_node (cs->callee, NULL);
+ if (callee->aux)
+ {
+ fibheap_delete_node (heap, (fibnode_t) callee->aux);
+ callee->aux = fibheap_insert (heap,
+ ipcp_estimate_cloning_cost (callee),
+ callee);
+ }
+ }
}
while (!fibheap_empty (heap))