OSDN Git Service

2010-07-04 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / ipa.c
index 319a3f1..05e1642 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -284,16 +284,19 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
             reachable too, unless they are direct calls to extern inline functions
             we decided to not inline.  */
          if (node->reachable)
-           for (e = node->callees; e; e = e->next_callee)
-             if (!e->callee->reachable
-                 && node->analyzed
-                 && (!e->inline_failed || !e->callee->analyzed
-                     || (!DECL_EXTERNAL (e->callee->decl))
-                     || before_inlining_p))
-               {
-                 e->callee->reachable = true;
-                 enqueue_cgraph_node (e->callee, &first);
-               }
+           {
+             for (e = node->callees; e; e = e->next_callee)
+               if (!e->callee->reachable
+                   && node->analyzed
+                   && (!e->inline_failed || !e->callee->analyzed
+                       || (!DECL_EXTERNAL (e->callee->decl))
+                       || before_inlining_p))
+                 {
+                   e->callee->reachable = true;
+                   enqueue_cgraph_node (e->callee, &first);
+                 }
+             process_references (&node->ref_list, &first, &first_varpool, before_inlining_p);
+           }
 
          /* If any function in a comdat group is reachable, force
             all other functions in the same comdat group to be
@@ -316,7 +319,8 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
             function is clone of real clone, we must keep it around in order to
             make materialize_clones produce function body with the changes
             applied.  */
-         while (node->clone_of && !node->clone_of->aux && !gimple_has_body_p (node->decl))
+         while (node->clone_of && !node->clone_of->aux
+                && !gimple_has_body_p (node->decl))
            {
              bool noninline = node->clone_of->decl != node->decl;
              node = node->clone_of;
@@ -326,7 +330,6 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
                  break;
                }
            }
-         process_references (&node->ref_list, &first, &first_varpool, before_inlining_p);
        }
       if (first_varpool != (struct varpool_node *) (void *) 1)
        {
@@ -367,6 +370,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
       if (node->aux && !node->reachable)
         {
          cgraph_node_remove_callees (node);
+         ipa_remove_all_references (&node->ref_list);
          node->analyzed = false;
          node->local.inlinable = false;
        }
@@ -508,8 +512,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
 
    FIXME: This can not be done in between gimplify and omp_expand since
    readonly flag plays role on what is shared and what is not.  Currently we do
-   this transformation as part of ipa-reference pass, but it would make sense
-   to do it before early optimizations.  */
+   this transformation as part of whole program visibility and re-do at
+   ipa-reference pass (to take into account clonning), but it would
+   make sense to do it before early optimizations.  */
 
 void
 ipa_discover_readonly_nonaddressable_vars (void)
@@ -571,6 +576,8 @@ cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program)
     return false;
   if (!whole_program)
     return true;
+  if (node->local.used_from_object_file)
+    return true;
   if (DECL_PRESERVE_P (node->decl))
     return true;
   /* COMDAT functions must be shared only if they have address taken,
@@ -724,6 +731,7 @@ function_and_variable_visibility (bool whole_program)
                 we start reordering datastructures.  */
              || DECL_COMDAT (vnode->decl)
              || DECL_WEAK (vnode->decl)
+              || vnode->used_from_object_file
              || lookup_attribute ("externally_visible",
                                   DECL_ATTRIBUTES (vnode->decl))))
        vnode->externally_visible = true;
@@ -821,6 +829,8 @@ whole_program_function_and_variable_visibility (void)
          fprintf (dump_file, " %s", varpool_node_name (vnode));
       fprintf (dump_file, "\n\n");
     }
+  if (optimize)
+    ipa_discover_readonly_nonaddressable_vars ();
   return 0;
 }
 
@@ -880,7 +890,7 @@ cgraph_node_set_new (void)
 {
   cgraph_node_set new_node_set;
 
-  new_node_set = GGC_NEW (struct cgraph_node_set_def);
+  new_node_set = ggc_alloc_cgraph_node_set_def ();
   new_node_set->hashtab = htab_create_ggc (10,
                                           hash_cgraph_node_set_element,
                                           eq_cgraph_node_set_element,
@@ -911,8 +921,7 @@ cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
     }
 
   /* Insert node into hash table.  */
-  element =
-    (cgraph_node_set_element) GGC_NEW (struct cgraph_node_set_element_def);
+  element = ggc_alloc_cgraph_node_set_element_def ();
   element->node = node;
   element->index = VEC_length (cgraph_node_ptr, set->nodes);
   *slot = element;
@@ -998,13 +1007,14 @@ dump_cgraph_node_set (FILE *f, cgraph_node_set set)
   for (iter = csi_start (set); !csi_end_p (iter); csi_next (&iter))
     {
       struct cgraph_node *node = csi_node (iter);
-      dump_cgraph_node (f, node);
+      fprintf (f, " %s/%i", cgraph_node_name (node), node->uid);
     }
+  fprintf (f, "\n");
 }
 
 /* Dump content of SET to stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_cgraph_node_set (cgraph_node_set set)
 {
   dump_cgraph_node_set (stderr, set);
@@ -1037,7 +1047,7 @@ varpool_node_set_new (void)
 {
   varpool_node_set new_node_set;
 
-  new_node_set = GGC_NEW (struct varpool_node_set_def);
+  new_node_set = ggc_alloc_varpool_node_set_def ();
   new_node_set->hashtab = htab_create_ggc (10,
                                           hash_varpool_node_set_element,
                                           eq_varpool_node_set_element,
@@ -1068,8 +1078,7 @@ varpool_node_set_add (varpool_node_set set, struct varpool_node *node)
     }
 
   /* Insert node into hash table.  */
-  element =
-    (varpool_node_set_element) GGC_NEW (struct varpool_node_set_element_def);
+  element = ggc_alloc_varpool_node_set_element_def ();
   element->node = node;
   element->index = VEC_length (varpool_node_ptr, set->nodes);
   *slot = element;
@@ -1155,13 +1164,14 @@ dump_varpool_node_set (FILE *f, varpool_node_set set)
   for (iter = vsi_start (set); !vsi_end_p (iter); vsi_next (&iter))
     {
       struct varpool_node *node = vsi_node (iter);
-      dump_varpool_node (f, node);
+      fprintf (f, " %s", varpool_node_name (node));
     }
+  fprintf (f, "\n");
 }
 
 /* Dump content of SET to stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_varpool_node_set (varpool_node_set set)
 {
   dump_varpool_node_set (stderr, set);