2012-08-17 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Aug 2012 08:03:54 +0000 (08:03 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 17 Aug 2012 08:03:54 +0000 (08:03 +0000)
* hash-table.h (class hash_table): Use a descriptor template
argument instead of decomposed element type and support
functions.
(struct pointer_hash): New generic typed pointer-hash.
(struct typed_free_remove, struct typed_noop_remove): Generic
hash_table support pieces.
* coverage.c (struct counts_entry): Add hash_table support
members.
* tree-ssa-ccp.c (gimple_htab): Use pointer_hash.
* tree-ssa-coalesce.c (struct ssa_name_var_hash): New generic
SSA name by SSA_NAME_VAR hash.
(coalesce_ssa_name): Use it.
* tree-ssa-pre.c (struct pre_expr_d): Add hash_table support.
(expression_to_id): Adjust.
(struct expr_pred_trans_d): Add hash_table support.
(phi_translate_table): Adjust.
(phi_trans_lookup): Likewise.
(phi_trans_add): Likewise.
(do_regular_insertion): Likewise.
* tree-ssa-tail-merge.c (struct same_succ_def): Add hash_table
support.
(same_succ_htab): Adjust.
(find_same_succ_bb): Likewise.
(find_same_succ): Likewise.
(update_worklist): Likewise.
* tree-ssa-threadupdate.c (struct redirection_data): Add hash_table
support.
(redirection_data): Adjust.

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

gcc/ChangeLog
gcc/coverage.c
gcc/hash-table.h
gcc/tree-ssa-ccp.c
gcc/tree-ssa-coalesce.c
gcc/tree-ssa-pre.c
gcc/tree-ssa-tail-merge.c
gcc/tree-ssa-threadupdate.c

index effbb41..ebc1002 100644 (file)
@@ -1,5 +1,36 @@
 2012-08-17  Richard Guenther  <rguenther@suse.de>
 
+       * hash-table.h (class hash_table): Use a descriptor template
+       argument instead of decomposed element type and support
+       functions.
+       (struct pointer_hash): New generic typed pointer-hash.
+       (struct typed_free_remove, struct typed_noop_remove): Generic
+       hash_table support pieces.
+       * coverage.c (struct counts_entry): Add hash_table support
+       members.
+       * tree-ssa-ccp.c (gimple_htab): Use pointer_hash.
+       * tree-ssa-coalesce.c (struct ssa_name_var_hash): New generic
+       SSA name by SSA_NAME_VAR hash.
+       (coalesce_ssa_name): Use it.
+       * tree-ssa-pre.c (struct pre_expr_d): Add hash_table support.
+       (expression_to_id): Adjust.
+       (struct expr_pred_trans_d): Add hash_table support.
+       (phi_translate_table): Adjust.
+       (phi_trans_lookup): Likewise.
+       (phi_trans_add): Likewise.
+       (do_regular_insertion): Likewise.
+       * tree-ssa-tail-merge.c (struct same_succ_def): Add hash_table
+       support.
+       (same_succ_htab): Adjust.
+       (find_same_succ_bb): Likewise.
+       (find_same_succ): Likewise.
+       (update_worklist): Likewise.
+       * tree-ssa-threadupdate.c (struct redirection_data): Add hash_table
+       support.
+       (redirection_data): Adjust.
+
+2012-08-17  Richard Guenther  <rguenther@suse.de>
+
        * params.def (integer-share-limit): Decrease from 256 to 251,
        add rationale.
 
index 3fea525..b4d22df 100644 (file)
@@ -77,6 +77,12 @@ typedef struct counts_entry
   unsigned cfg_checksum;
   gcov_type *counts;
   struct gcov_ctr_summary summary;
+
+  /* hash_table support.  */
+  typedef counts_entry T;
+  static inline hashval_t hash (const counts_entry *);
+  static int equal (const counts_entry *, const counts_entry *);
+  static void remove (counts_entry *);
 } counts_entry_t;
 
 static GTY(()) struct coverage_data *functions_head = 0;
@@ -144,29 +150,27 @@ get_gcov_unsigned_t (void)
 }
 \f
 inline hashval_t
-coverage_counts_entry_hash (const counts_entry_t *entry)
+counts_entry::hash (const counts_entry_t *entry)
 {
   return entry->ident * GCOV_COUNTERS + entry->ctr;
 }
 
 inline int
-coverage_counts_entry_eq (const counts_entry_t *entry1,
-                          const counts_entry_t *entry2)
+counts_entry::equal (const counts_entry_t *entry1,
+                    const counts_entry_t *entry2)
 {
   return entry1->ident == entry2->ident && entry1->ctr == entry2->ctr;
 }
 
 inline void
-coverage_counts_entry_del (counts_entry_t *entry)
+counts_entry::remove (counts_entry_t *entry)
 {
   free (entry->counts);
   free (entry);
 }
 
 /* Hash table of count data.  */
-static hash_table <counts_entry_t, coverage_counts_entry_hash,
-                  coverage_counts_entry_eq, coverage_counts_entry_del>
-                 counts_hash;
+static hash_table <counts_entry> counts_hash;
 
 /* Read in the counts file, if available.  */
 
index 2c483e2..91231a2 100644 (file)
@@ -83,45 +83,52 @@ xcallocator <Type>::data_free (Type *memory)
 }
 
 
-/* A common function for hashing a CANDIDATE typed pointer.  */
+/* Remove method dispatching to free.  */
 
 template <typename Element>
-inline hashval_t
-typed_pointer_hash (const Element *candidate)
+struct typed_free_remove
 {
-  /* This is a really poor hash function, but it is what the current code uses,
-     so I am reusing it to avoid an additional axis in testing.  */
-  return (hashval_t) ((intptr_t)candidate >> 3);
-}
-
+  static inline void remove (Element *p) { free (p); }
+};
 
-/* A common function for comparing an EXISTING and CANDIDATE typed pointers
-   for equality. */
+/* No-op remove method.  */
 
 template <typename Element>
-inline int
-typed_pointer_equal (const Element *existing, const Element * candidate)
+struct typed_noop_remove
 {
-  return existing == candidate;
-}
+  static inline void remove (Element *) {}
+};
 
 
-/* A common function for doing nothing on removing a RETIRED slot.  */
+/* Pointer hash with a no-op remove method.  */
 
 template <typename Element>
-inline void
-typed_null_remove (Element *retired ATTRIBUTE_UNUSED)
+struct pointer_hash : typed_noop_remove <Element>
 {
-}
+  typedef Element T;
 
+  static inline hashval_t
+  hash (const T *);
 
-/* A common function for using free on removing a RETIRED slot.  */
+  static inline int
+  equal (const T *existing, const T * candidate);
+};
 
 template <typename Element>
-inline void
-typed_free_remove (Element *retired)
+inline hashval_t
+pointer_hash<Element>::hash (const T *candidate)
+{
+  /* This is a really poor hash function, but it is what the current code uses,
+     so I am reusing it to avoid an additional axis in testing.  */
+  return (hashval_t) ((intptr_t)candidate >> 3);
+}
+
+template <typename Element>
+inline int
+pointer_hash<Element>::equal (const T *existing,
+                             const T *candidate)
 {
-  free (retired);
+  return existing == candidate;
 }
 
 
@@ -147,11 +154,11 @@ extern hashval_t hash_table_mod2 (hashval_t hash, unsigned int index);
 
 /* Internal implementation type.  */
 
-template <typename Element>
+template <typename T>
 struct hash_table_control
 {
   /* Table itself.  */
-  Element **entries;
+  T **entries;
 
   /* Current size (in entries) of the hash table.  */
   size_t size;
@@ -180,15 +187,15 @@ struct hash_table_control
 
    The table stores elements of type Element.
 
-   It hashes elements with the Hash function.
+   It hashes elements with the hash function.
      The table currently works with relatively weak hash functions.
      Use typed_pointer_hash <Element> when hashing pointers instead of objects.
 
-   It compares elements with the Equal function.
+   It compares elements with the equal function.
      Two elements with the same hash may not be equal.
      Use typed_pointer_equal <Element> when hashing pointers instead of objects.
 
-   It removes elements with the Remove function.
+   It removes elements with the remove function.
      This feature is useful for freeing memory.
      Use typed_null_remove <Element> when not freeing objects.
      Use typed_free_remove <Element> when doing a simple object free.
@@ -198,59 +205,53 @@ struct hash_table_control
 
 */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator = xcallocator>
 class hash_table
 {
+public:
+  typedef typename Descr::T T;
 
 private:
+  hash_table_control <T> *htab;
 
-  hash_table_control <Element> *htab;
-
-  Element **find_empty_slot_for_expand (hashval_t hash);
+  T **find_empty_slot_for_expand (hashval_t hash);
   void expand ();
 
 public:
-
   hash_table ();
   void create (size_t initial_slots);
   bool is_created ();
   void dispose ();
-  Element *find (Element *comparable);
-  Element *find_with_hash (Element *comparable, hashval_t hash);
-  Element **find_slot (Element *comparable, enum insert_option insert);
-  Element **find_slot_with_hash (Element *comparable, hashval_t hash,
-                                enum insert_option insert);
+  T *find (T *comparable);
+  T *find_with_hash (T *comparable, hashval_t hash);
+  T **find_slot (T *comparable, enum insert_option insert);
+  T **find_slot_with_hash (T *comparable, hashval_t hash,
+                                  enum insert_option insert);
   void empty ();
-  void clear_slot (Element **slot);
-  void remove_elt (Element *comparable);
-  void remove_elt_with_hash (Element *comparable, hashval_t hash);
+  void clear_slot (T **slot);
+  void remove_elt (T *comparable);
+  void remove_elt_with_hash (T *comparable, hashval_t hash);
   size_t size();
   size_t elements();
   double collisions();
 
   template <typename Argument,
-           int (*Callback) (Element **slot, Argument argument)>
+           int (*Callback) (T **slot, Argument argument)>
   void traverse_noresize (Argument argument);
 
   template <typename Argument,
-           int (*Callback) (Element **slot, Argument argument)>
+           int (*Callback) (T **slot, Argument argument)>
   void traverse (Argument argument);
 };
 
 
 /* Construct the hash table.  The only useful operation next is create.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 inline
-hash_table <Element, Hash, Equal, Remove, Allocator>::hash_table ()
+hash_table <Descr, Allocator>::hash_table ()
 : htab (NULL)
 {
 }
@@ -258,13 +259,10 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::hash_table ()
 
 /* See if the table has been created, as opposed to constructed.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 inline bool
-hash_table <Element, Hash, Equal, Remove, Allocator>::is_created ()
+hash_table <Descr, Allocator>::is_created ()
 {
   return htab != NULL;
 }
@@ -272,57 +270,45 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::is_created ()
 
 /* Like find_with_hash, but compute the hash value from the element.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
-inline Element *
-hash_table <Element, Hash, Equal, Remove, Allocator>::find (Element *comparable)
+inline typename Descr::T *
+hash_table <Descr, Allocator>::find (T *comparable)
 {
-  return find_with_hash (comparable, Hash (comparable));
+  return find_with_hash (comparable, Descr::hash (comparable));
 }
 
 
 /* Like find_slot_with_hash, but compute the hash value from the element.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
-inline Element **
-hash_table <Element, Hash, Equal, Remove, Allocator>
-::find_slot (Element *comparable, enum insert_option insert)
+inline typename Descr::T **
+hash_table <Descr, Allocator>
+::find_slot (T *comparable, enum insert_option insert)
 {
-  return find_slot_with_hash (comparable, Hash (comparable), insert);
+  return find_slot_with_hash (comparable, Descr::hash (comparable), insert);
 }
 
 
 /* Like remove_elt_with_hash, but compute the hash value from the element.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 inline void
-hash_table <Element, Hash, Equal, Remove, Allocator>
-::remove_elt (Element *comparable)
+hash_table <Descr, Allocator>
+::remove_elt (T *comparable)
 {
-  remove_elt_with_hash (comparable, Hash (comparable));
+  remove_elt_with_hash (comparable, Descr::hash (comparable));
 }
 
 
 /* Return the current size of this hash table.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 inline size_t
-hash_table <Element, Hash, Equal, Remove, Allocator>::size()
+hash_table <Descr, Allocator>::size()
 {
   return htab->size;
 }
@@ -330,13 +316,10 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::size()
 
 /* Return the current number of elements in this hash table. */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 inline size_t
-hash_table <Element, Hash, Equal, Remove, Allocator>::elements()
+hash_table <Descr, Allocator>::elements()
 {
   return htab->n_elements - htab->n_deleted;
 }
@@ -345,13 +328,10 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::elements()
   /* Return the fraction of fixed collisions during all work with given
      hash table. */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 inline double
-hash_table <Element, Hash, Equal, Remove, Allocator>::collisions()
+hash_table <Descr, Allocator>::collisions()
 {
   if (htab->searches == 0)
     return 0.0;
@@ -362,22 +342,19 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::collisions()
 
 /* Create a hash table with at least the given number of INITIAL_SLOTS.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 void
-hash_table <Element, Hash, Equal, Remove, Allocator>::create (size_t size)
+hash_table <Descr, Allocator>::create (size_t size)
 {
   unsigned int size_prime_index;
 
   size_prime_index = hash_table_higher_prime_index (size);
   size = prime_tab[size_prime_index].prime;
 
-  htab = Allocator <hash_table_control <Element> > ::control_alloc (1);
+  htab = Allocator <hash_table_control <T> > ::control_alloc (1);
   gcc_assert (htab != NULL);
-  htab->entries = Allocator <Element*> ::data_alloc (size);
+  htab->entries = Allocator <T*> ::data_alloc (size);
   gcc_assert (htab->entries != NULL);
   htab->size = size;
   htab->size_prime_index = size_prime_index;
@@ -387,46 +364,40 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::create (size_t size)
 /* Dispose of a hash table.  Free all memory and return this hash table to
    the non-created state.  Naturally the hash table must already exist.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 void
-hash_table <Element, Hash, Equal, Remove, Allocator>::dispose ()
+hash_table <Descr, Allocator>::dispose ()
 {
   size_t size = htab->size;
-  Element **entries = htab->entries;
+  T **entries = htab->entries;
 
   for (int i = size - 1; i >= 0; i--)
     if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY)
-      Remove (entries[i]);
+      Descr::remove (entries[i]);
 
-  Allocator <Element *> ::data_free (entries);
-  Allocator <hash_table_control <Element> > ::control_free (htab);
+  Allocator <T *> ::data_free (entries);
+  Allocator <hash_table_control <T> > ::control_free (htab);
   htab = NULL;
 }
 
 
 /* Similar to find_slot, but without several unwanted side effects:
-    - Does not call Equal when it finds an existing entry.
+    - Does not call equal when it finds an existing entry.
     - Does not change the count of elements/searches/collisions in the
       hash table.
    This function also assumes there are no deleted entries in the table.
    HASH is the hash value for the element to be inserted.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
-Element **
-hash_table <Element, Hash, Equal, Remove, Allocator>
+typename Descr::T **
+hash_table <Descr, Allocator>
 ::find_empty_slot_for_expand (hashval_t hash)
 {
   hashval_t index = hash_table_mod1 (hash, htab->size_prime_index);
   size_t size = htab->size;
-  Element **slot = htab->entries + index;
+  T **slot = htab->entries + index;
   hashval_t hash2;
 
   if (*slot == HTAB_EMPTY_ENTRY)
@@ -457,18 +428,15 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
    table entries is changed.  If memory allocation fails, this function
    will abort.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 void
-hash_table <Element, Hash, Equal, Remove, Allocator>::expand ()
+hash_table <Descr, Allocator>::expand ()
 {
-  Element **oentries;
-  Element **olimit;
-  Element **p;
-  Element **nentries;
+  T **oentries;
+  T **olimit;
+  T **p;
+  T **nentries;
   size_t nsize, osize, elts;
   unsigned int oindex, nindex;
 
@@ -491,7 +459,7 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::expand ()
       nsize = osize;
     }
 
-  nentries = Allocator <Element *> ::data_alloc (nsize);
+  nentries = Allocator <T *> ::data_alloc (nsize);
   gcc_assert (nentries != NULL);
   htab->entries = nentries;
   htab->size = nsize;
@@ -502,11 +470,11 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::expand ()
   p = oentries;
   do
     {
-      Element *x = *p;
+      T *x = *p;
 
       if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
         {
-          Element **q = find_empty_slot_for_expand (Hash (x));
+          T **q = find_empty_slot_for_expand (Descr::hash (x));
 
           *q = x;
         }
@@ -515,7 +483,7 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::expand ()
     }
   while (p < olimit);
 
-  Allocator <Element *> ::data_free (oentries);
+  Allocator <T *> ::data_free (oentries);
 }
 
 
@@ -523,18 +491,15 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::expand ()
    COMPARABLE element starting with the given HASH value.  It cannot
    be used to insert or delete an element. */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
-Element *
-hash_table <Element, Hash, Equal, Remove, Allocator>
-::find_with_hash (Element *comparable, hashval_t hash)
+typename Descr::T *
+hash_table <Descr, Allocator>
+::find_with_hash (T *comparable, hashval_t hash)
 {
   hashval_t index, hash2;
   size_t size;
-  Element *entry;
+  T *entry;
 
   htab->searches++;
   size = htab->size;
@@ -542,7 +507,7 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
 
   entry = htab->entries[index];
   if (entry == HTAB_EMPTY_ENTRY
-      || (entry != HTAB_DELETED_ENTRY && Equal (entry, comparable)))
+      || (entry != HTAB_DELETED_ENTRY && Descr::equal (entry, comparable)))
     return entry;
 
   hash2 = hash_table_mod2 (hash, htab->size_prime_index);
@@ -555,7 +520,7 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
 
       entry = htab->entries[index];
       if (entry == HTAB_EMPTY_ENTRY
-          || (entry != HTAB_DELETED_ENTRY && Equal (entry, comparable)))
+          || (entry != HTAB_DELETED_ENTRY && Descr::equal (entry, comparable)))
         return entry;
     }
 }
@@ -569,20 +534,17 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
    write the value you want into the returned slot.  When inserting an
    entry, NULL may be returned if memory allocation fails. */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
-Element **
-hash_table <Element, Hash, Equal, Remove, Allocator>
-::find_slot_with_hash (Element *comparable, hashval_t hash,
+typename Descr::T **
+hash_table <Descr, Allocator>
+::find_slot_with_hash (T *comparable, hashval_t hash,
                       enum insert_option insert)
 {
-  Element **first_deleted_slot;
+  T **first_deleted_slot;
   hashval_t index, hash2;
   size_t size;
-  Element *entry;
+  T *entry;
 
   size = htab->size;
   if (insert == INSERT && size * 3 <= htab->n_elements * 4)
@@ -601,7 +563,7 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
     goto empty_entry;
   else if (entry == HTAB_DELETED_ENTRY)
     first_deleted_slot = &htab->entries[index];
-  else if (Equal (entry, comparable))
+  else if (Descr::equal (entry, comparable))
     return &htab->entries[index];
       
   hash2 = hash_table_mod2 (hash, htab->size_prime_index);
@@ -620,7 +582,7 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
          if (!first_deleted_slot)
            first_deleted_slot = &htab->entries[index];
        }
-      else if (Equal (entry, comparable))
+      else if (Descr::equal (entry, comparable))
        return &htab->entries[index];
     }
 
@@ -631,7 +593,7 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
   if (first_deleted_slot)
     {
       htab->n_deleted--;
-      *first_deleted_slot = static_cast <Element *> (HTAB_EMPTY_ENTRY);
+      *first_deleted_slot = static_cast <T *> (HTAB_EMPTY_ENTRY);
       return first_deleted_slot;
     }
 
@@ -642,21 +604,18 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
 
 /* This function clears all entries in the given hash table.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 void
-hash_table <Element, Hash, Equal, Remove, Allocator>::empty ()
+hash_table <Descr, Allocator>::empty ()
 {
   size_t size = htab_size (htab);
-  Element **entries = htab->entries;
+  T **entries = htab->entries;
   int i;
 
   for (i = size - 1; i >= 0; i--)
     if (entries[i] != HTAB_EMPTY_ENTRY && entries[i] != HTAB_DELETED_ENTRY)
-      Remove (entries[i]);
+      Descr::remove (entries[i]);
 
   /* Instead of clearing megabyte, downsize the table.  */
   if (size > 1024*1024 / sizeof (PTR))
@@ -664,13 +623,13 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::empty ()
       int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR));
       int nsize = prime_tab[nindex].prime;
 
-      Allocator <Element *> ::data_free (htab->entries);
-      htab->entries = Allocator <Element *> ::data_alloc (nsize);
+      Allocator <T *> ::data_free (htab->entries);
+      htab->entries = Allocator <T *> ::data_alloc (nsize);
       htab->size = nsize;
       htab->size_prime_index = nindex;
     }
   else
-    memset (entries, 0, size * sizeof (Element *));
+    memset (entries, 0, size * sizeof (T *));
   htab->n_deleted = 0;
   htab->n_elements = 0;
 }
@@ -680,20 +639,17 @@ hash_table <Element, Hash, Equal, Remove, Allocator>::empty ()
    useful when you've already done the lookup and don't want to do it
    again. */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 void
-hash_table <Element, Hash, Equal, Remove, Allocator>
-::clear_slot (Element **slot)
+hash_table <Descr, Allocator>
+::clear_slot (T **slot)
 {
   if (slot < htab->entries || slot >= htab->entries + htab->size
       || *slot == HTAB_EMPTY_ENTRY || *slot == HTAB_DELETED_ENTRY)
     abort ();
 
-  Remove (*slot);
+  Descr::remove (*slot);
 
   *slot = HTAB_DELETED_ENTRY;
   htab->n_deleted++;
@@ -704,24 +660,21 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
    from hash table starting with the given HASH.  If there is no
    matching element in the hash table, this function does nothing. */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 void
-hash_table <Element, Hash, Equal, Remove, Allocator>
-::remove_elt_with_hash (Element *comparable, hashval_t hash)
+hash_table <Descr, Allocator>
+::remove_elt_with_hash (T *comparable, hashval_t hash)
 {
-  Element **slot;
+  T **slot;
 
   slot = find_slot_with_hash (comparable, hash, NO_INSERT);
   if (*slot == HTAB_EMPTY_ENTRY)
     return;
 
-  Remove (*slot);
+  Descr::remove (*slot);
 
-  *slot = static_cast <Element *> (HTAB_DELETED_ENTRY);
+  *slot = static_cast <T *> (HTAB_DELETED_ENTRY);
   htab->n_deleted++;
 }
 
@@ -730,26 +683,23 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
    each live entry.  If CALLBACK returns false, the iteration stops.
    ARGUMENT is passed as CALLBACK's second argument. */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 template <typename Argument,
-         int (*Callback) (Element **slot, Argument argument)>
+         int (*Callback) (typename Descr::T **slot, Argument argument)>
 void
-hash_table <Element, Hash, Equal, Remove, Allocator>
+hash_table <Descr, Allocator>
 ::traverse_noresize (Argument argument)
 {
-  Element **slot;
-  Element **limit;
+  T **slot;
+  T **limit;
 
   slot = htab->entries;
   limit = slot + htab->size;
 
   do
     {
-      Element *x = *slot;
+      T *x = *slot;
 
       if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
         if (! Callback (slot, argument))
@@ -762,15 +712,12 @@ hash_table <Element, Hash, Equal, Remove, Allocator>
 /* Like traverse_noresize, but does resize the table when it is too empty
    to improve effectivity of subsequent calls.  */
 
-template <typename Element,
-         hashval_t (*Hash) (const Element *candidate),
-         int (*Equal) (const Element *existing, const Element * candidate),
-         void (*Remove) (Element *retired),
+template <typename Descr,
          template <typename Type> class Allocator>
 template <typename Argument,
-         int (*Callback) (Element **slot, Argument argument)>
+         int (*Callback) (typename Descr::T **slot, Argument argument)>
 void
-hash_table <Element, Hash, Equal, Remove, Allocator>
+hash_table <Descr, Allocator>
 ::traverse (Argument argument)
 {
   size_t size = htab->size;
index 4b798b7..ac6ad5d 100644 (file)
@@ -1688,10 +1688,7 @@ evaluate_stmt (gimple stmt)
   return val;
 }
 
-typedef hash_table <gimple_statement_d, typed_pointer_hash<gimple_statement_d>,
-                   typed_pointer_equal<gimple_statement_d>,
-                   typed_null_remove<gimple_statement_d> >
-                  gimple_htab;
+typedef hash_table <pointer_hash <gimple_statement_d> > gimple_htab;
 
 /* Given a BUILT_IN_STACK_SAVE value SAVED_VAL, insert a clobber of VAR before
    each matching BUILT_IN_STACK_RESTORE.  Mark visited phis in VISITED.  */
index c8557ac..dfcd4aa 100644 (file)
@@ -1258,22 +1258,29 @@ coalesce_partitions (var_map map, ssa_conflicts_p graph, coalesce_list_p cl,
     }
 }
 
-/* Returns a hash code for N.  */
+
+/* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR.  */
+
+struct ssa_name_var_hash : typed_noop_remove <union tree_node>
+{
+  typedef union tree_node T;
+  static inline hashval_t hash (const_tree);
+  static inline int equal (const_tree, const_tree);
+};
 
 inline hashval_t
-hash_ssa_name_by_var (const_tree n)
+ssa_name_var_hash::hash (const_tree n)
 {
-  return (hashval_t) htab_hash_pointer (SSA_NAME_VAR (n));
+  return DECL_UID (SSA_NAME_VAR (n));
 }
 
-/* Returns nonzero if N1 and N2 are equal.  */
-
 inline int
-eq_ssa_name_by_var (const_tree n1, const_tree n2)
+ssa_name_var_hash::equal (const_tree n1, const_tree n2)
 {
   return SSA_NAME_VAR (n1) == SSA_NAME_VAR (n2);
 }
 
+
 /* Reduce the number of copies by coalescing variables in the function.  Return
    a partition map with the resulting coalesces.  */
 
@@ -1286,9 +1293,7 @@ coalesce_ssa_name (void)
   bitmap used_in_copies = BITMAP_ALLOC (NULL);
   var_map map;
   unsigned int i;
-  static hash_table <tree_node, hash_ssa_name_by_var, eq_ssa_name_by_var,
-                    typed_null_remove<tree_node> >
-                   ssa_name_hash;
+  static hash_table <ssa_name_var_hash> ssa_name_hash;
 
   cl = create_coalesce_list ();
   map = create_outofssa_var_map (cl, used_in_copies);
index 51d9e02..e113539 100644 (file)
@@ -165,11 +165,16 @@ typedef union pre_expr_union_d
   vn_reference_t reference;
 } pre_expr_union;
 
-typedef struct pre_expr_d
+typedef struct pre_expr_d : typed_noop_remove <pre_expr_d>
 {
   enum pre_expr_kind kind;
   unsigned int id;
   pre_expr_union u;
+
+  /* hash_table support.  */
+  typedef pre_expr_d T;
+  static inline hashval_t hash (const pre_expr_d *);
+  static inline int equal (const pre_expr_d *, const pre_expr_d *);
 } *pre_expr;
 
 #define PRE_EXPR_NAME(e) (e)->u.name
@@ -180,7 +185,7 @@ typedef struct pre_expr_d
 /* Compare E1 and E1 for equality.  */
 
 inline int
-ssa_pre_expr_eq (const struct pre_expr_d *e1, const struct pre_expr_d *e2)
+pre_expr_d::equal (const struct pre_expr_d *e1, const struct pre_expr_d *e2)
 {
   if (e1->kind != e2->kind)
     return false;
@@ -205,7 +210,7 @@ ssa_pre_expr_eq (const struct pre_expr_d *e1, const struct pre_expr_d *e2)
 /* Hash E.  */
 
 inline hashval_t
-ssa_pre_expr_hash (const struct pre_expr_d *e)
+pre_expr_d::hash (const struct pre_expr_d *e)
 {
   switch (e->kind)
     {
@@ -229,9 +234,7 @@ static unsigned int next_expression_id;
 DEF_VEC_P (pre_expr);
 DEF_VEC_ALLOC_P (pre_expr, heap);
 static VEC(pre_expr, heap) *expressions;
-static hash_table <pre_expr_d, ssa_pre_expr_hash, ssa_pre_expr_eq,
-                  typed_null_remove <pre_expr_d> >
-                 expression_to_id;
+static hash_table <pre_expr_d> expression_to_id;
 static VEC(unsigned, heap) *name_to_id;
 
 /* Allocate an expression id for EXPR.  */
@@ -483,7 +486,7 @@ static bitmap need_ab_cleanup;
 /* A three tuple {e, pred, v} used to cache phi translations in the
    phi_translate_table.  */
 
-typedef struct expr_pred_trans_d
+typedef struct expr_pred_trans_d : typed_free_remove<expr_pred_trans_d>
 {
   /* The expression.  */
   pre_expr e;
@@ -497,23 +500,23 @@ typedef struct expr_pred_trans_d
   /* The hashcode for the expression, pred pair. This is cached for
      speed reasons.  */
   hashval_t hashcode;
+
+  /* hash_table support.  */
+  typedef expr_pred_trans_d T;
+  static inline hashval_t hash (const expr_pred_trans_d *);
+  static inline int equal (const expr_pred_trans_d *, const expr_pred_trans_d *);
 } *expr_pred_trans_t;
 typedef const struct expr_pred_trans_d *const_expr_pred_trans_t;
 
-/* Return the hash value for a phi translation table entry.  */
-
 inline hashval_t
-ssa_expr_pred_trans_hash (const expr_pred_trans_d *ve)
+expr_pred_trans_d::hash (const expr_pred_trans_d *e)
 {
-  return ve->hashcode;
+  return e->hashcode;
 }
 
-/* Return true if two phi translation table entries are the same.
-   P1 and P2 should point to the expr_pred_trans_t's to be compared.*/
-
 inline int
-ssa_expr_pred_trans_eq (const expr_pred_trans_d *ve1,
-                       const expr_pred_trans_d *ve2)
+expr_pred_trans_d::equal (const expr_pred_trans_d *ve1,
+                         const expr_pred_trans_d *ve2)
 {
   basic_block b1 = ve1->pred;
   basic_block b2 = ve2->pred;
@@ -522,16 +525,12 @@ ssa_expr_pred_trans_eq (const expr_pred_trans_d *ve1,
      be equal.  */
   if (b1 != b2)
     return false;
-  return ssa_pre_expr_eq (ve1->e, ve2->e);
+  return pre_expr_d::equal (ve1->e, ve2->e);
 }
 
 /* The phi_translate_table caches phi translations for a given
    expression and predecessor.  */
-
-static hash_table <expr_pred_trans_d, ssa_expr_pred_trans_hash,
-                  ssa_expr_pred_trans_eq,
-                  typed_free_remove <expr_pred_trans_d> >
-                 phi_translate_table;
+static hash_table <expr_pred_trans_d> phi_translate_table;
 
 /* Search in the phi translation table for the translation of
    expression E in basic block PRED.
@@ -545,7 +544,7 @@ phi_trans_lookup (pre_expr e, basic_block pred)
 
   ept.e = e;
   ept.pred = pred;
-  ept.hashcode = iterative_hash_hashval_t (ssa_pre_expr_hash (e), pred->index);
+  ept.hashcode = iterative_hash_hashval_t (pre_expr_d::hash (e), pred->index);
   slot = phi_translate_table.find_slot_with_hash (&ept, ept.hashcode,
                                   NO_INSERT);
   if (!slot)
@@ -566,7 +565,7 @@ phi_trans_add (pre_expr e, pre_expr v, basic_block pred)
   new_pair->e = e;
   new_pair->pred = pred;
   new_pair->v = v;
-  new_pair->hashcode = iterative_hash_hashval_t (ssa_pre_expr_hash (e),
+  new_pair->hashcode = iterative_hash_hashval_t (pre_expr_d::hash (e),
                                                 pred->index);
 
   slot = phi_translate_table.find_slot_with_hash (new_pair,
@@ -3495,7 +3494,7 @@ do_regular_insertion (basic_block block, basic_block dom)
                    do_insertion = true;
                  if (first_s == NULL)
                    first_s = edoubleprime;
-                 else if (!ssa_pre_expr_eq (first_s, edoubleprime))
+                 else if (!pre_expr_d::equal (first_s, edoubleprime))
                    all_same = false;
                }
            }
index ec644ee..372096c 100644 (file)
@@ -224,10 +224,24 @@ struct same_succ_def
   bool in_worklist;
   /* The hash value of the struct.  */
   hashval_t hashval;
+
+  /* hash_table support.  */
+  typedef same_succ_def T;
+  static inline hashval_t hash (const same_succ_def *);
+  static int equal (const same_succ_def *, const same_succ_def *);
+  static void remove (same_succ_def *);
 };
 typedef struct same_succ_def *same_succ;
 typedef const struct same_succ_def *const_same_succ;
 
+/* hash routine for hash_table support, returns hashval of E.  */
+
+inline hashval_t
+same_succ_def::hash (const same_succ_def *e)
+{
+  return e->hashval;
+}
+
 /* A group of bbs where 1 bb from bbs can replace the other bbs.  */
 
 struct bb_cluster_def
@@ -415,8 +429,8 @@ stmt_update_dep_bb (gimple stmt)
 
 /* Calculates hash value for same_succ VE.  */
 
-hashval_t
-ssa_same_succ_hash (const_same_succ e)
+static hashval_t
+same_succ_hash (const_same_succ e)
 {
   hashval_t hashval = bitmap_hash (e->succs);
   int flags;
@@ -511,10 +525,10 @@ inverse_flags (const_same_succ e1, const_same_succ e2)
   return (f1a & mask) == (f2a & mask) && (f1b & mask) == (f2b & mask);
 }
 
-/* Compares SAME_SUCCs VE1 and VE2.  */
+/* Compares SAME_SUCCs E1 and E2.  */
 
 int
-ssa_same_succ_equal (const_same_succ e1, const_same_succ e2)
+same_succ_def::equal (const_same_succ e1, const_same_succ e2)
 {
   unsigned int i, first1, first2;
   gimple_stmt_iterator gsi1, gsi2;
@@ -584,10 +598,10 @@ same_succ_alloc (void)
   return same;
 }
 
-/* Delete same_succ VE.  */
+/* Delete same_succ E.  */
 
-inline void
-ssa_same_succ_delete (same_succ e)
+void
+same_succ_def::remove (same_succ e)
 {
   BITMAP_FREE (e->bbs);
   BITMAP_FREE (e->succs);
@@ -608,11 +622,7 @@ same_succ_reset (same_succ same)
   VEC_truncate (int, same->succ_flags, 0);
 }
 
-/* Hash table with all same_succ entries.  */
-
-static hash_table <struct same_succ_def, ssa_same_succ_hash,
-                  ssa_same_succ_equal, ssa_same_succ_delete>
-                 same_succ_htab;
+static hash_table <same_succ_def> same_succ_htab;
 
 /* Array that is used to store the edge flags for a successor.  */
 
@@ -692,7 +702,7 @@ find_same_succ_bb (basic_block bb, same_succ *same_p)
   EXECUTE_IF_SET_IN_BITMAP (same->succs, 0, j, bj)
     VEC_safe_push (int, heap, same->succ_flags, same_succ_edge_flags[j]);
 
-  same->hashval = ssa_same_succ_hash (same);
+  same->hashval = same_succ_hash (same);
 
   slot = same_succ_htab.find_slot_with_hash (same, same->hashval, INSERT);
   if (*slot == NULL)
@@ -728,7 +738,7 @@ find_same_succ (void)
        same = same_succ_alloc ();
     }
 
-  ssa_same_succ_delete (same);
+  same_succ_def::remove (same);
 }
 
 /* Initializes worklist administration.  */
@@ -860,7 +870,7 @@ update_worklist (void)
       if (same == NULL)
        same = same_succ_alloc ();
     }
-  ssa_same_succ_delete (same);
+  same_succ_def::remove (same);
   bitmap_clear (deleted_bb_preds);
 }
 
index 3ecb303..86ad74f 100644 (file)
@@ -110,7 +110,7 @@ struct el
    may have many incoming edges threaded to the same outgoing edge.  This
    can be naturally implemented with a hash table.  */
 
-struct redirection_data
+struct redirection_data : typed_free_remove<redirection_data>
 {
   /* A duplicate of B with the trailing control statement removed and which
      targets a single successor of B.  */
@@ -125,8 +125,30 @@ struct redirection_data
   /* A list of incoming edges which we want to thread to
      OUTGOING_EDGE->dest.  */
   struct el *incoming_edges;
+
+  /* hash_table support.  */
+  typedef redirection_data T;
+  static inline hashval_t hash (const redirection_data *);
+  static inline int equal (const redirection_data *, const redirection_data *);
 };
 
+inline hashval_t
+redirection_data::hash (const redirection_data *p)
+{
+  edge e = p->outgoing_edge;
+  return e->dest->index;
+}
+
+inline int
+redirection_data::equal (const redirection_data *p1, const redirection_data *p2)
+{
+  edge e1 = p1->outgoing_edge;
+  edge e2 = p2->outgoing_edge;
+  edge e3 = p1->intermediate_edge;
+  edge e4 = p2->intermediate_edge;
+  return e1 == e2 && e3 == e4;
+}
+
 /* Data structure of information to pass to hash table traversal routines.  */
 struct ssa_local_info_t
 {
@@ -217,32 +239,9 @@ create_block_for_threading (basic_block bb, struct redirection_data *rd)
   rd->dup_block->count = 0;
 }
 
-/* Hashing and equality routines for our hash table.  */
-inline hashval_t
-ssa_redirection_data_hash (const struct redirection_data *p)
-{
-  edge e = p->outgoing_edge;
-  return e->dest->index;
-}
-
-inline int
-ssa_redirection_data_eq (const struct redirection_data *p1,
-                        const struct redirection_data *p2)
-{
-  edge e1 = p1->outgoing_edge;
-  edge e2 = p2->outgoing_edge;
-  edge e3 = p1->intermediate_edge;
-  edge e4 = p2->intermediate_edge;
-
-  return e1 == e2 && e3 == e4;
-}
-
 /* Main data structure to hold information for duplicates of BB.  */
 
-static hash_table <struct redirection_data, ssa_redirection_data_hash,
-                  ssa_redirection_data_eq,
-                  typed_free_remove<struct redirection_data> >
-                 redirection_data;
+static hash_table <redirection_data> redirection_data;
 
 /* Given an outgoing edge E lookup and return its entry in our hash table.