]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
tree.h (mark_tree_hashtable): New function.
authorMark Mitchell <mark@codesourcery.com>
Mon, 27 Nov 2000 07:09:20 +0000 (07:09 +0000)
committerMark Mitchell <mmitchel@gcc.gnu.org>
Mon, 27 Nov 2000 07:09:20 +0000 (07:09 +0000)
* tree.h (mark_tree_hashtable): New function.
* tree.c (mark_tree_hashtable_entry): New function.
(mark_tree_hashtable): Likewise.

* tree.c (struct list_hash): Remove.
(list_hash_table): Make it be an htab.
(struct list_proxy): New type.
(list_hash_eq): New function.
(list_hash_pieces): Renamed from ...
(list_hash): ... this.
(list_hash_lookup): Remove.
(list_hash_add): Remove.
(hash_tree_cons): Use the generic hashtable.
(mark_list_hash): Remove.
(init_tree): Create the hashtable.

From-SVN: r37783

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/tree.c
gcc/tree.c
gcc/tree.h

index e20b02795cd2e3cbe7fd46ebaa2b6238c0346941..099d51c890fe5c17ac9a40d427535c2bd12f4edd 100644 (file)
@@ -1,3 +1,9 @@
+2000-11-26  Mark Mitchell  <mark@codesourcery.com>
+
+       * tree.h (mark_tree_hashtable): New function.
+       * tree.c (mark_tree_hashtable_entry): New function.
+       (mark_tree_hashtable): Likewise.
+
 2000-11-27  Michael Meissner  <meissner@redhat.com>
 
        * d30v-protos.h (srelational_si_operator): Correctly spell
index 1cc9c5f343007482a2da0ef62218505594e179ae..7b36db17751cf532e6f259d77e982c6687786003 100644 (file)
@@ -1,3 +1,17 @@
+2000-11-26  Mark Mitchell  <mark@codesourcery.com>
+
+       * tree.c (struct list_hash): Remove.
+       (list_hash_table): Make it be an htab.
+       (struct list_proxy): New type.
+       (list_hash_eq): New function.
+       (list_hash_pieces): Renamed from ...
+       (list_hash): ... this.
+       (list_hash_lookup): Remove.
+       (list_hash_add): Remove.
+       (hash_tree_cons): Use the generic hashtable.
+       (mark_list_hash): Remove.
+       (init_tree): Create the hashtable.
+
 2000-11-25  Joseph S. Myers  <jsm28@cam.ac.uk>
 
        * method.c (build_mangled_C9x_name): Rename to
index 2768ef8afd46b8eb5ab2fb2488d2b348022fa025..517a5cc3e04d1d45f8e7754c395069cae4bea7f5 100644 (file)
@@ -35,13 +35,12 @@ Boston, MA 02111-1307, USA.  */
 static tree bot_manip PARAMS ((tree *, int *, void *));
 static tree bot_replace PARAMS ((tree *, int *, void *));
 static tree build_cplus_array_type_1 PARAMS ((tree, tree));
-static void list_hash_add PARAMS ((int, tree));
-static int list_hash PARAMS ((tree, tree, tree));
-static tree list_hash_lookup PARAMS ((int, tree, tree, tree));
+static int list_hash_eq PARAMS ((const void *, const void *));
+static hashval_t list_hash_pieces PARAMS ((tree, tree, tree));
+static hashval_t list_hash PARAMS ((const void *));
 static cp_lvalue_kind lvalue_p_1 PARAMS ((tree, int));
 static tree no_linkage_helper PARAMS ((tree *, int *, void *));
 static tree build_srcloc PARAMS ((const char *, int));
-static void mark_list_hash PARAMS ((void *));
 static tree mark_local_for_remap_r PARAMS ((tree *, int *, void *));
 static tree cp_unsave_r PARAMS ((tree *, int *, void *));
 static void cp_unsave PARAMS ((tree *));
@@ -695,38 +694,52 @@ unshare_base_binfos (binfo)
 /* Hashing of lists so that we don't make duplicates.
    The entry point is `list_hash_canon'.  */
 
-/* Each hash table slot is a bucket containing a chain
-   of these structures.  */
-
-struct list_hash
-{
-  struct list_hash *next;      /* Next structure in the bucket.  */
-  int hashcode;                        /* Hash code of this list.  */
-  tree list;                   /* The list recorded here.  */
-};
-
 /* Now here is the hash table.  When recording a list, it is added
    to the slot whose index is the hash code mod the table size.
    Note that the hash table is used for several kinds of lists.
    While all these live in the same table, they are completely independent,
    and the hash code is computed differently for each of these.  */
 
-#define TYPE_HASH_SIZE 59
-static struct list_hash *list_hash_table[TYPE_HASH_SIZE];
+static htab_t list_hash_table;
+
+struct list_proxy 
+{
+  tree purpose;
+  tree value;
+  tree chain;
+};
+
+/* Compare ENTRY (an entry in the hash table) with DATA (a list_proxy
+   for a node we are thinking about adding).  */
+
+static int
+list_hash_eq (entry, data)
+     const void *entry;
+     const void *data;
+{
+  tree t = (tree) entry;
+  struct list_proxy *proxy = (struct list_proxy *) data;
+
+  return (TREE_VALUE (t) == proxy->value
+         && TREE_PURPOSE (t) == proxy->purpose
+         && TREE_CHAIN (t) == proxy->chain);
+}
 
 /* Compute a hash code for a list (chain of TREE_LIST nodes
    with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the
    TREE_COMMON slots), by adding the hash codes of the individual entries.  */
 
-static int
-list_hash (purpose, value, chain)
-     tree purpose, value, chain;
+static hashval_t
+list_hash_pieces (purpose, value, chain)
+     tree purpose;
+     tree value;
+     tree chain;
 {
-  register int hashcode = 0;
-
+  hashval_t hashcode = 0;
+  
   if (chain)
     hashcode += TYPE_HASH (chain);
-
+  
   if (value)
     hashcode += TYPE_HASH (value);
   else
@@ -738,72 +751,44 @@ list_hash (purpose, value, chain)
   return hashcode;
 }
 
-/* Look in the type hash table for a type isomorphic to TYPE.
-   If one is found, return it.  Otherwise return 0.  */
+/* Hash an already existing TREE_LIST.  */
 
-static tree
-list_hash_lookup (hashcode, purpose, value, chain)
-     int hashcode;
-     tree purpose, value, chain;
+static hashval_t
+list_hash (p)
+     const void *p;
 {
-  register struct list_hash *h;
-
-  for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next)
-    if (h->hashcode == hashcode
-       && TREE_PURPOSE (h->list) == purpose
-       && TREE_VALUE (h->list) == value
-       && TREE_CHAIN (h->list) == chain)
-      return h->list;
-  return 0;
-}
-
-/* Add an entry to the list-hash-table
-   for a list TYPE whose hash code is HASHCODE.  */
-
-static void
-list_hash_add (hashcode, list)
-     int hashcode;
-     tree list;
-{
-  register struct list_hash *h;
-
-  h = (struct list_hash *) obstack_alloc (&permanent_obstack, sizeof (struct list_hash));
-  h->hashcode = hashcode;
-  h->list = list;
-  h->next = list_hash_table[hashcode % TYPE_HASH_SIZE];
-  list_hash_table[hashcode % TYPE_HASH_SIZE] = h;
+  tree t = (tree) p;
+  return list_hash_pieces (TREE_PURPOSE (t), 
+                          TREE_VALUE (t), 
+                          TREE_CHAIN (t));
 }
 
 /* Given list components PURPOSE, VALUE, AND CHAIN, return the canonical
    object for an identical list if one already exists.  Otherwise, build a
    new one, and record it as the canonical object.  */
 
-/* Set to 1 to debug without canonicalization.  Never set by program.  */
-
-static int debug_no_list_hash = 0;
-
 tree
 hash_tree_cons (purpose, value, chain)
      tree purpose, value, chain;
 {
-  tree t;
   int hashcode = 0;
-
-  if (! debug_no_list_hash)
-    {
-      hashcode = list_hash (purpose, value, chain);
-      t = list_hash_lookup (hashcode, purpose, value, chain);
-      if (t)
-       return t;
-    }
-
-  t = tree_cons (purpose, value, chain);
-
-  /* If this is a new list, record it for later reuse.  */
-  if (! debug_no_list_hash)
-    list_hash_add (hashcode, t);
-
-  return t;
+  PTR* slot;
+  struct list_proxy proxy;
+
+  /* Hash the list node.  */
+  hashcode = list_hash_pieces (purpose, value, chain);
+  /* Create a proxy for the TREE_LIST we would like to create.  We
+     don't actually create it so as to avoid creating garbage.  */
+  proxy.purpose = purpose;
+  proxy.value = value;
+  proxy.chain = chain;
+  /* See if it is already in the table.  */
+  slot = htab_find_slot_with_hash (list_hash_table, &proxy, hashcode,
+                                  INSERT);
+  /* If not, create a new node.  */
+  if (!*slot)
+    *slot = (PTR) tree_cons (purpose, value, chain);
+  return *slot;
 }
 
 /* Constructor for hashed lists.  */
@@ -2382,18 +2367,6 @@ make_ptrmem_cst (type, member)
   return ptrmem_cst;
 }
 
-/* Mark ARG (which is really a list_hash_table **) for GC.  */
-
-static void
-mark_list_hash (arg)
-     void *arg;
-{
-  struct list_hash *lh;
-
-  for (lh = * ((struct list_hash **) arg); lh; lh = lh->next)
-    ggc_mark_tree (lh->list);
-}
-
 /* Initialize tree.c.  */
 
 void
@@ -2402,10 +2375,10 @@ init_tree ()
   make_lang_type_fn = cp_make_lang_type;
   lang_unsave = cp_unsave;
   lang_statement_code_p = cp_statement_code_p;
-  ggc_add_root (list_hash_table, 
-               ARRAY_SIZE (list_hash_table),
-               sizeof (struct list_hash *),
-               mark_list_hash);
+  list_hash_table = htab_create (31, list_hash, list_hash_eq, NULL);
+  ggc_add_root (&list_hash_table, 1, 
+               sizeof (list_hash_table),
+               mark_tree_hashtable);
 }
 
 /* The SAVE_EXPR pointed to by TP is being copied.  If ST contains
index dcacdaf1d397943f0100c18ed766a7abe7f9a1b6..acc744619b3a625d28379ac0768940477acbd0a2 100644 (file)
@@ -170,6 +170,7 @@ static unsigned int type_hash_hash PARAMS ((const void*));
 static void print_type_hash_statistics PARAMS((void));
 static int mark_hash_entry PARAMS((void **, void *));
 static void finish_vector_type PARAMS((tree));
+static int mark_tree_hashtable_entry PARAMS((void **, void *));
 
 /* If non-null, these are language-specific helper functions for
    unsave_expr_now.  If present, LANG_UNSAVE is called before its
@@ -3184,6 +3185,29 @@ mark_type_hash (arg)
   htab_traverse (t, mark_hash_entry, 0);
 }
 
+/* Mark the hashtable slot pointed to by ENTRY (which is really a
+   `tree**') for GC.  */
+
+static int
+mark_tree_hashtable_entry (entry, data)
+     void **entry;
+     void *data ATTRIBUTE_UNUSED;
+{
+  ggc_mark_tree ((tree) *entry);
+  return 1;
+}
+
+/* Mark ARG (which is really a htab_t whose slots are trees) for 
+   GC.  */
+
+void
+mark_tree_hashtable (arg)
+     void *arg;
+{
+  htab_t t = *(htab_t *) arg;
+  htab_traverse (t, mark_tree_hashtable_entry, 0);
+}
+
 static void
 print_type_hash_statistics ()
 {
index 1cf49f1f8729212e137e2048b5eac7284f7fd5cc..822ecf3d88b4cc8a5e3d3f978ef7e94d42091028 100644 (file)
@@ -2666,6 +2666,7 @@ extern void gcc_obstack_init              PARAMS ((struct obstack *));
 extern void init_obstacks              PARAMS ((void));
 extern void build_common_tree_nodes    PARAMS ((int));
 extern void build_common_tree_nodes_2  PARAMS ((int));
+extern void mark_tree_hashtable         PARAMS ((void *));
 
 /* In function.c */
 extern void setjmp_protect_args                PARAMS ((void));