OSDN Git Service

* cgraph.h (varpool_node_name): Declare.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Nov 2009 16:21:59 +0000 (16:21 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 12 Nov 2009 16:21:59 +0000 (16:21 +0000)
* cgraphunit.c (process_function_and_variable_attributes): Set force_output
flag on used variables.
* ipa.c (function_and_variable_visibility): Dump externally visible and needed
variables.
* varpool.c (varpool_node_name): Export.
(decide_is_variable_needed): Check COMDAT for externally visible vars;
ignore needed flag.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@154121 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphunit.c
gcc/ipa.c
gcc/varpool.c

index 0fe06ac..d616cb7 100644 (file)
@@ -1,3 +1,14 @@
+2009-11-12 Jan Hubicka  <jh@suse.cz>
+
+       * cgraph.h (varpool_node_name): Declare.
+       * cgraphunit.c (process_function_and_variable_attributes): Set force_output
+       flag on used variables.
+       * ipa.c (function_and_variable_visibility): Dump externally visible and needed
+       variables.
+       * varpool.c (varpool_node_name): Export.
+       (decide_is_variable_needed): Check COMDAT for externally visible vars;
+       ignore needed flag.
+
 2009-11-12 Uros Bizjak <ubizjak@gmail.com>
 
        PR middle-end/41930
index 016ce9d..46fee67 100644 (file)
@@ -531,6 +531,7 @@ bool varpool_assemble_decl (struct varpool_node *node);
 bool varpool_analyze_pending_decls (void);
 void varpool_remove_unreferenced_decls (void);
 void varpool_empty_needed_queue (void);
+const char * varpool_node_name (struct varpool_node *node);
 
 /* Walk all reachable static variables.  */
 #define FOR_EACH_STATIC_VARIABLE(node) \
index 7105e59..377e435 100644 (file)
@@ -884,6 +884,7 @@ process_function_and_variable_attributes (struct cgraph_node *first,
       if (lookup_attribute ("used", DECL_ATTRIBUTES (decl)))
        {
          mark_decl_referenced (decl);
+         vnode->force_output = true;
          if (vnode->finalized)
            varpool_mark_needed_node (vnode);
        }
index 4297ea2..bf8faa9 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -292,7 +292,8 @@ function_and_variable_visibility (bool whole_program)
 
   for (node = cgraph_nodes; node; node = node->next)
     {
-      gcc_assert (!DECL_WEAK (node->decl) || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
+      gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl))
+                 || TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl));
       if (cgraph_externally_visible_p (node, whole_program))
         {
          gcc_assert (!node->global.inlined_to);
@@ -317,7 +318,7 @@ function_and_variable_visibility (bool whole_program)
     {
       if (!vnode->finalized)
         continue;
-      gcc_assert ((!DECL_WEAK (vnode->decl) || DECL_COMMON (vnode->decl))
+      gcc_assert ((!DECL_WEAK (vnode->decl) && !DECL_COMMON (vnode->decl) && !DECL_COMDAT (vnode->decl))
                  || TREE_PUBLIC (vnode->decl) || DECL_EXTERNAL (node->decl));
       if (vnode->needed
          && (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))
@@ -352,6 +353,11 @@ function_and_variable_visibility (bool whole_program)
        if (node->local.externally_visible)
          fprintf (dump_file, " %s", cgraph_node_name (node));
       fprintf (dump_file, "\n\n");
+      fprintf (dump_file, "\nMarking externally visible variables:");
+      for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
+       if (vnode->externally_visible)
+         fprintf (dump_file, " %s", varpool_node_name (vnode));
+      fprintf (dump_file, "\n\n");
     }
   cgraph_function_flags_ready = true;
   return 0;
@@ -410,6 +416,14 @@ whole_program_function_and_variable_visibility (void)
   for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
     if (vnode->externally_visible && !DECL_COMDAT (vnode->decl))
       varpool_mark_needed_node (vnode);
+  if (dump_file)
+    {
+      fprintf (dump_file, "\nNeeded variables:");
+      for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
+       if (vnode->needed)
+         fprintf (dump_file, " %s", varpool_node_name (vnode));
+      fprintf (dump_file, "\n\n");
+    }
   return 0;
 }
 
index 8815efd..90a9ace 100644 (file)
@@ -80,7 +80,7 @@ static GTY(()) struct varpool_node *varpool_first_unanalyzed_node;
 static GTY(()) struct varpool_node *varpool_assembled_nodes_queue;
 
 /* Return name of the node used in debug output.  */
-static const char *
+const char *
 varpool_node_name (struct varpool_node *node)
 {
   return lang_hooks.decl_printable_name (node->decl, 2);
@@ -229,7 +229,8 @@ bool
 decide_is_variable_needed (struct varpool_node *node, tree decl)
 {
   /* If the user told us it is used, then it must be so.  */
-  if (node->externally_visible || node->force_output)
+  if ((node->externally_visible && !DECL_COMDAT (decl))
+      || node->force_output)
     return true;
 
   /* ??? If the assembler name is set by hand, it is possible to assemble
@@ -239,11 +240,6 @@ decide_is_variable_needed (struct varpool_node *node, tree decl)
       && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
     return true;
 
-  /* If we decided it was needed before, but at the time we didn't have
-     the definition available, then it's still needed.  */
-  if (node->needed)
-    return true;
-
   /* Externally visible variables must be output.  The exception is
      COMDAT variables that must be output only when they are needed.  */
   if (TREE_PUBLIC (decl)