ipa-cp.c (ipcp_versionable_function_p): Aliases are not versionable.
authorJan Hubicka <jh@suse.cz>
Fri, 10 Jun 2011 14:57:05 +0000 (16:57 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 10 Jun 2011 14:57:05 +0000 (14:57 +0000)
* 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

gcc/ChangeLog
gcc/ipa-cp.c
gcc/ipa-prop.c

index aeab479d8343c4da80090e3e5a6af82cbbe8a570..398a2d99a73a91c2fe9dd59bcde416cc929c6b54 100644 (file)
@@ -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.
index 992f1858983850b8faf6729bd2cd9fadf11b1c14..94aab5f5f76014fd4221eb3cc62bee8c38a6ba6b 100644 (file)
@@ -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))
index 7e74ac8b7d6251cc3eb0fea71153040e0a545b85..6450e81ea4bdcb8bcd96d32e7acc96c5c6e62a0d 100644 (file)
@@ -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);
     }