OSDN Git Service

2008-02-26 Richard Guenther <rguenther@suse.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree.c
index f61e24b..97c90ec 100644 (file)
@@ -110,6 +110,12 @@ static GTY(()) int next_decl_uid;
 /* Unique id for next type created.  */
 static GTY(()) int next_type_uid = 1;
 
+/* Mapping from unique DECL_UID to the decl tree node.  */
+static GTY ((if_marked ("ggc_marked_p"), param_is (union tree_node)))
+     htab_t decl_for_uid_map;
+
+static void insert_decl_to_uid_decl_map (tree);
+
 /* Since we cannot rehash a type after it is in the table, we have to
    keep the hash code.  */
 
@@ -231,6 +237,9 @@ init_ttree (void)
   
   int_cst_node = make_node (INTEGER_CST);
 
+  decl_for_uid_map = htab_create_ggc (4093, uid_decl_map_hash,
+                                     uid_decl_map_eq, NULL);
+
   tree_contains_struct[FUNCTION_DECL][TS_DECL_NON_COMMON] = 1;
   tree_contains_struct[TRANSLATION_UNIT_DECL][TS_DECL_NON_COMMON] = 1;
   tree_contains_struct[TYPE_DECL][TS_DECL_NON_COMMON] = 1;
@@ -601,6 +610,7 @@ make_node_stat (enum tree_code code MEM_STAT_DECL)
        }
       DECL_SOURCE_LOCATION (t) = input_location;
       DECL_UID (t) = next_decl_uid++;
+      insert_decl_to_uid_decl_map (t);
 
       break;
 
@@ -704,6 +714,7 @@ copy_node_stat (tree node MEM_STAT_DECL)
          SET_DECL_RESTRICT_BASE (t, DECL_GET_RESTRICT_BASE (node));
          DECL_BASED_ON_RESTRICT_P (t) = 1;
        }
+      insert_decl_to_uid_decl_map (t);
     }
   else if (TREE_CODE_CLASS (code) == tcc_type)
     {
@@ -3325,6 +3336,86 @@ build_nt_call_list (tree fn, tree arglist)
   return t;
 }
 \f
+/* Return true if the DECL_UID in both trees are equal.  */
+
+int
+uid_decl_map_eq (const void *va, const void *vb)
+{
+  const_tree a = (const_tree) va;
+  const_tree b = (const_tree) vb;
+  return (a->decl_minimal.uid == b->decl_minimal.uid);
+}
+
+/* Hash a tree in a uid_decl_map.  */
+
+unsigned int
+uid_decl_map_hash (const void *item)
+{
+  return ((const_tree)item)->decl_minimal.uid;
+}
+
+/* Insert the declaration NODE into the map mapping its unique uid
+   back to the tree.  */
+
+static void
+insert_decl_to_uid_decl_map (tree node)
+{
+  void **slot;
+  struct tree_decl_minimal key;
+
+  key.uid = DECL_UID (node);
+  slot = htab_find_slot_with_hash (decl_for_uid_map,
+                                  &key, DECL_UID (node), INSERT);
+
+  /* We should never try to re-insert a decl with the same uid.
+     ???  The C++ frontend breaks this invariant.  Hopefully in a
+     non-fatal way, so just overwrite the slot in this case.  */
+#if 0
+  gcc_assert (!*slot);
+#endif
+
+  *(tree *)slot = node;
+}
+
+/* Lookup the declaration tree from its unique DECL_UID UID.  Returns
+   the tree node with DECL_UID UID or NULL, if this node was collected.  */
+
+tree
+lookup_decl_from_uid (int uid)
+{
+  struct tree_decl_minimal key;
+
+  key.uid = uid;
+  return (tree) htab_find_with_hash (decl_for_uid_map, &key, uid);
+}
+
+/* Remove the declaration tree DECL from the global UID to decl map.
+   This needs to be called if you ggc_free a decl tree, otherwise
+   garbage collection will take care of it.  */
+
+void
+remove_decl_from_map (tree decl)
+{
+  struct tree_decl_minimal key;
+
+  key.uid = DECL_UID (decl);
+#if ENABLE_CHECKING
+  gcc_assert (decl == htab_find_with_hash (decl_for_uid_map, &key, key.uid));
+#endif
+  htab_remove_elt_with_hash (decl_for_uid_map, &key, key.uid);
+}
+
+/* Print out the statistics for the decl_for_uid_map hash table.  */
+
+static void
+print_decl_for_uid_map_statistics (void)
+{
+  fprintf (stderr, "DECL_FOR_UID_MAP hash: size %ld, %ld elements, %f collisions\n",
+          (long) htab_size (decl_for_uid_map),
+          (long) htab_elements (decl_for_uid_map),
+          htab_collisions (decl_for_uid_map));
+}
+
 /* Create a DECL_... node of code CODE, name NAME and data type TYPE.
    We do NOT enter this node in any sort of symbol table.
 
@@ -3701,8 +3792,9 @@ build_type_attribute_qual_variant (tree ttype, tree attribute, int quals)
          hashcode = type_hash_list (TYPE_ARG_TYPES (ntype), hashcode);
          break;
        case ARRAY_TYPE:
-         hashcode = iterative_hash_object (TYPE_HASH (TYPE_DOMAIN (ntype)),
-                                           hashcode);
+         if (TYPE_DOMAIN (ntype))
+           hashcode = iterative_hash_object (TYPE_HASH (TYPE_DOMAIN (ntype)),
+                                             hashcode);
          break;
        case INTEGER_TYPE:
          hashcode = iterative_hash_object
@@ -6653,6 +6745,7 @@ dump_tree_statistics (void)
   print_debug_expr_statistics ();
   print_value_expr_statistics ();
   print_restrict_base_statistics ();
+  print_decl_for_uid_map_statistics ();
   lang_hooks.print_statistics ();
 }
 \f