aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2011-06-10 16:57:05 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2011-06-10 14:57:05 +0000
commit749f25d8a774f7786bd0258d79ee10a309df8dfb (patch)
treefb7d5174686aae02adc1c28679cbb08b775dee5e
parent9c8cf7b70ca74485589349143ba966b8d5251215 (diff)
downloadgcc-749f25d8a774f7786bd0258d79ee10a309df8dfb.zip
gcc-749f25d8a774f7786bd0258d79ee10a309df8dfb.tar.gz
gcc-749f25d8a774f7786bd0258d79ee10a309df8dfb.tar.bz2
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
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/ipa-cp.c66
-rw-r--r--gcc/ipa-prop.c11
3 files changed, 55 insertions, 35 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index aeab479..398a2d9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+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>
* doc/sourcebuild.texi (Effective-Target Keywords, pie): Document it.
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 992f185..94aab5f 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))
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 7e74ac8..6450e81 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -93,7 +93,7 @@ ipa_init_func_list (void)
wl = NULL;
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);
/* Unreachable nodes should have been eliminated before ipcp and
@@ -1096,6 +1096,7 @@ ipa_compute_jump_functions (struct cgraph_node *node,
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
functions unless they may become known during lto/whopr. */
if (!cs->callee->analyzed && !flag_lto)
@@ -1103,11 +1104,11 @@ ipa_compute_jump_functions (struct cgraph_node *node,
ipa_count_arguments (cs);
/* If the descriptor of the callee is not initialized yet, we have to do
it now. */
- if (cs->callee->analyzed)
- ipa_initialize_node_params (cs->callee);
+ if (callee->analyzed)
+ ipa_initialize_node_params (callee);
if (ipa_get_cs_argument_count (IPA_EDGE_REF (cs))
- != ipa_get_param_count (IPA_NODE_REF (cs->callee)))
- ipa_set_called_with_variable_arg (IPA_NODE_REF (cs->callee));
+ != ipa_get_param_count (IPA_NODE_REF (callee)))
+ ipa_set_called_with_variable_arg (IPA_NODE_REF (callee));
ipa_compute_jump_functions_for_edge (parms_info, cs);
}