OSDN Git Service

* bt-load.c: Fix comment typos.
[pf3gnuchains/gcc-fork.git] / gcc / cgraph.c
index b5753a1..36d9814 100644 (file)
@@ -24,7 +24,6 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "tree-inline.h"
 #include "langhooks.h"
 #include "hashtab.h"
 #include "toplev.h"
@@ -34,16 +33,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "target.h"
 #include "cgraph.h"
 #include "varray.h"
+#include "output.h"
 
-/* The known declarations must not get garbage collected.  Callgraph
-   datastructures should not get saved via PCH code since this would
-   make it difficult to extend into intra-module optimizer later.  So
-   we store only the references into the array to prevent gabrage
-   collector from deleting live data.  */
-static GTY(()) varray_type known_fns;
 
 /* Hash table used to convert declarations into nodes.  */
-static htab_t cgraph_hash = 0;
+static GTY((param_is (struct cgraph_node))) htab_t cgraph_hash;
 
 /* The linked list of cgraph nodes.  */
 struct cgraph_node *cgraph_nodes;
@@ -57,6 +51,18 @@ int cgraph_n_nodes;
 /* Set when whole unit has been analyzed so we can access global info.  */
 bool cgraph_global_info_ready = false;
 
+/* Hash table used to convert declarations into nodes.  */
+static GTY((param_is (struct cgraph_varpool_node))) htab_t cgraph_varpool_hash;
+
+/* Queue of cgraph nodes scheduled to be lowered and output.  */
+struct cgraph_varpool_node *cgraph_varpool_nodes_queue;
+
+/* Number of nodes in existence.  */
+int cgraph_varpool_n_nodes;
+
+/* The linked list of cgraph varpool nodes.  */
+static GTY(())  struct cgraph_varpool_node *cgraph_varpool_nodes;
+
 static struct cgraph_edge *create_edge PARAMS ((struct cgraph_node *,
                                                struct cgraph_node *));
 static void cgraph_remove_edge PARAMS ((struct cgraph_node *, struct cgraph_node *));
@@ -69,9 +75,9 @@ static hashval_t
 hash_node (p)
      const void *p;
 {
-  return (hashval_t)
-    htab_hash_pointer (DECL_ASSEMBLER_NAME
-                      (((struct cgraph_node *) p)->decl));
+  return ((hashval_t)
+         IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
+                                (((struct cgraph_node *) p)->decl)));
 }
 
 /* Returns nonzero if P1 and P2 are equal.  */
@@ -97,20 +103,15 @@ cgraph_node (decl)
     abort ();
 
   if (!cgraph_hash)
-    {
-      cgraph_hash = htab_create (10, hash_node, eq_node, NULL);
-      VARRAY_TREE_INIT (known_fns, 32, "known_fns");
-    }
+    cgraph_hash = htab_create_ggc (10, hash_node, eq_node, NULL);
 
-  slot =
-    (struct cgraph_node **) htab_find_slot_with_hash (cgraph_hash,
-                                                     DECL_ASSEMBLER_NAME (decl),
-                                                     htab_hash_pointer
-                                                     (DECL_ASSEMBLER_NAME
-                                                      (decl)), 1);
+  slot = (struct cgraph_node **)
+    htab_find_slot_with_hash (cgraph_hash, DECL_ASSEMBLER_NAME (decl),
+                             IDENTIFIER_HASH_VALUE
+                               (DECL_ASSEMBLER_NAME (decl)), 1);
   if (*slot)
     return *slot;
-  node = xcalloc (sizeof (*node), 1);
+  node = ggc_alloc_cleared (sizeof (*node));
   node->decl = decl;
   node->next = cgraph_nodes;
   if (cgraph_nodes)
@@ -125,7 +126,6 @@ cgraph_node (decl)
       node->next_nested = node->origin->nested;
       node->origin->nested = node;
     }
-  VARRAY_PUSH_TREE (known_fns, decl);
   return node;
 }
 
@@ -140,14 +140,11 @@ cgraph_node_for_identifier (id)
     abort ();
 
   if (!cgraph_hash)
-    {
-      cgraph_hash = htab_create (10, hash_node, eq_node, NULL);
-      VARRAY_TREE_INIT (known_fns, 32, "known_fns");
-    }
+    return NULL;
 
-  slot =
-    (struct cgraph_node **) htab_find_slot_with_hash (cgraph_hash, id,
-                                                     htab_hash_pointer (id), 0);
+  slot = (struct cgraph_node **)
+    htab_find_slot_with_hash (cgraph_hash, id,
+                             IDENTIFIER_HASH_VALUE (id), 0);
   if (!slot)
     return NULL;
   return *slot;
@@ -159,7 +156,7 @@ static struct cgraph_edge *
 create_edge (caller, callee)
      struct cgraph_node *caller, *callee;
 {
-  struct cgraph_edge *edge = xmalloc (sizeof (struct cgraph_edge));
+  struct cgraph_edge *edge = ggc_alloc (sizeof (struct cgraph_edge));
 
   edge->caller = caller;
   edge->callee = callee;
@@ -238,7 +235,7 @@ cgraph_mark_needed_node (node, needed)
       node->reachable = 1;
       if (DECL_SAVED_TREE (node->decl))
        {
-         node->aux = cgraph_nodes_queue;
+         node->next_needed = cgraph_nodes_queue;
          cgraph_nodes_queue = node;
         }
     }
@@ -356,4 +353,132 @@ dump_cgraph (f)
     }
 }
 
+/* Returns a hash code for P.  */
+
+static hashval_t
+cgraph_varpool_hash_node (const PTR p)
+{
+  return ((hashval_t)
+         IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME
+                                (((struct cgraph_varpool_node *) p)->decl)));
+}
+
+/* Returns nonzero if P1 and P2 are equal.  */
+
+static int
+eq_cgraph_varpool_node (const PTR p1, const PTR p2)
+{
+  return ((DECL_ASSEMBLER_NAME (((struct cgraph_varpool_node *) p1)->decl)) ==
+         (tree) p2);
+}
+
+/* Return cgraph_varpool node assigned to DECL.  Create new one when needed.  */
+struct cgraph_varpool_node *
+cgraph_varpool_node (tree decl)
+{
+  struct cgraph_varpool_node *node;
+  struct cgraph_varpool_node **slot;
+
+  if (!DECL_P (decl) || TREE_CODE (decl) == FUNCTION_DECL)
+    abort ();
+
+  if (!cgraph_varpool_hash)
+    cgraph_varpool_hash = htab_create_ggc (10, cgraph_varpool_hash_node,
+                                          eq_cgraph_varpool_node, NULL);
+
+
+  slot = (struct cgraph_varpool_node **)
+    htab_find_slot_with_hash (cgraph_varpool_hash, DECL_ASSEMBLER_NAME (decl),
+                             IDENTIFIER_HASH_VALUE (DECL_ASSEMBLER_NAME (decl)),
+                             1);
+  if (*slot)
+    return *slot;
+  node = ggc_alloc_cleared (sizeof (*node));
+  node->decl = decl;
+  cgraph_varpool_n_nodes++;
+  cgraph_varpool_nodes = node;
+  *slot = node;
+  return node;
+}
+
+/* Try to find existing function for identifier ID.  */
+struct cgraph_varpool_node *
+cgraph_varpool_node_for_identifier (tree id)
+{
+  struct cgraph_varpool_node **slot;
+
+  if (TREE_CODE (id) != IDENTIFIER_NODE)
+    abort ();
+
+  if (!cgraph_varpool_hash)
+    return NULL;
+
+  slot = (struct cgraph_varpool_node **)
+    htab_find_slot_with_hash (cgraph_varpool_hash, id,
+                             IDENTIFIER_HASH_VALUE (id), 0);
+  if (!slot)
+    return NULL;
+  return *slot;
+}
+
+/* Notify finalize_compilation_unit that given node is reachable
+   or needed.  */
+void
+cgraph_varpool_mark_needed_node (struct cgraph_varpool_node *node)
+{
+  if (!node->needed && node->finalized)
+    {
+      node->next_needed = cgraph_varpool_nodes_queue;
+      cgraph_varpool_nodes_queue = node;
+    }
+  node->needed = 1;
+}
+
+void
+cgraph_varpool_finalize_decl (tree decl)
+{
+  struct cgraph_varpool_node *node = cgraph_varpool_node (decl);
+
+  if (node->needed && !node->finalized)
+    {
+      node->next_needed = cgraph_varpool_nodes_queue;
+      cgraph_varpool_nodes_queue = node;
+    }
+  node->finalized = true;
+
+  if (/* Externally visible variables must be output.  The exception are
+        COMDAT functions that must be output only when they are needed.  */
+      (TREE_PUBLIC (decl) && !DECL_COMDAT (decl))
+      /* Function whose name is output to the assembler file must be produced.
+        It is possible to assemble the name later after finalizing the function
+        and the fact is noticed in assemble_name then.  */
+      || (DECL_ASSEMBLER_NAME_SET_P (decl)
+         && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))))
+    {
+      cgraph_varpool_mark_needed_node (node);
+    }
+}
+
+bool
+cgraph_varpool_assemble_pending_decls ()
+{
+  bool changed = false;
+
+  while (cgraph_varpool_nodes_queue)
+    {
+      tree decl = cgraph_varpool_nodes_queue->decl;
+      struct cgraph_varpool_node *node = cgraph_varpool_nodes_queue;
+
+      cgraph_varpool_nodes_queue = cgraph_varpool_nodes_queue->next_needed;
+      if (!TREE_ASM_WRITTEN (decl))
+       {
+         assemble_variable (decl, 0, 1, 0);
+         changed = true;
+       }
+      node->next_needed = NULL;
+    }
+  return changed;
+}
+
+
 #include "gt-cgraph.h"