This patch extracts approved portions of the hash_table patches to the...
authorLawrence Crowl <crowl@google.com>
Tue, 23 Apr 2013 22:00:12 +0000 (22:00 +0000)
committerLawrence Crowl <crowl@gcc.gnu.org>
Tue, 23 Apr 2013 22:00:12 +0000 (22:00 +0000)
This patch extracts approved portions of the hash_table patches to
the cxx-conversion branch for files not under gcc/config.

Update various hash tables from htab_t to hash_table.
Modify types and calls to match.

* tree-ssa-coalesce.c'coalesce_list_d.list from htab_t to hash_table.

Fold coalesce_pair_map_hash and coalesce_pair_map_eq into new
struct coalesce_pair_hasher.

Removed struct coalesce_pair_iterator, as did not meet the hash_table
iterator interface and it provided no significant code reduction.
This leads to a change in the implementation of FOR_EACH_PARTITION_PAIR.

* statistics.c'statistics_hashes

Fold hash_statistics_eq into new struct stats_counter_hasher.

* hash-table.h'hash_table

Add documentation.
Add nested class iterator and methods to hash_table.
Add FOR_EACH_HASH_TABLE_ELEMENT implemented with those iterators.
Change uses of FOR_EACH_HTAB_ELEMENT to FOR_EACH_HASH_TABLE_ELEMENT.

* tree-ssa-sccvn.c'vn_tables_s.nary

Fold vn_nary_op_hash, vn_nary_op_eq into new struct vn_nary_op_hasher.
Add typedef vn_nary_op_table_type.
Add typedef vn_nary_op_iterator_type.

* tree-ssa-sccvn.c'vn_tables_s.phis

Fold vn_phi_hash, free_phi into new struct vn_phi_hasher.
Add typedef vn_phi_table_type.
Add typedef vn_phi_iterator_type.

* tree-ssa-sccvn.c'vn_tables_s.references

Fold vn_reference_hash, vn_reference_op_eq, free_reference
  into new struct vn_reference_hasher.
Add typedef vn_reference_table_type.
Add typedef vn_reference_iterator_type.

* tree-ssa-sccvn.c'constant_value_ids

Fold vn_constant_hash, vn_constant_eq into new struct vn_constant_hasher.

* tree-into-ssa.c'var_infos

Fold var_info_hash, var_info_eq into new struct var_info_hasher.

* tree-vectorizer.h'_loop_vec_info::peeling_htab

* tree-vectorizer.h

New struct peel_info_hasher.

* tree-vect-loop.c

Update dependent calls and types to match.

* tree-vect-data-refs.c

Fold vect_peeling_hash and vect_peeling_hash_eq into struct peel_info_hasher.

* tree-ssa-reassoc.c'undistribute_ops_list::ctable

Fold oecount_hash and oecount_eq into new struct oecount_hasher.

* tree-ssa-loop-im.c'memory_accesses.refs

Fold memref_hash and memref_eq into new struct mem_ref_hasher.

Tested on x86_64.

Index: gcc/ChangeLog

2013-04-23  Lawrence Crowl  <crowl@google.com>

* Makefile.in: Update as needed below.

* hash-table.h (class hash_table):
Correct many methods with parameter types compare_type to the correct
value_type.  (Correct code was unlikely to notice the change.)
(hash_table::elements_with_deleted) New.
(class hashtable::iterator): New.
(hashtable::begin()): New.
(hashtable::end()): New.
(FOR_EACH_HASH_TABLE_ELEMENT): New.

* statistics.c (statistics_hashes):
Change type to hash_table.  Update dependent calls and types.

* tree-into-ssa.c (var_infos):
Change type to hash_table.  Update dependent calls and types.

* tree-ssa-coalesce.c (struct coalesce_list_d.list):
Change type to hash_table.  Update dependent calls and types.

* tree-ssa-loop-im.c (struct mem_ref.refs):
Change type to hash_table.  Update dependent calls and types.

* tree-ssa-reassoc.c (undistribute_ops_list::ctable):
Change type to hash_table.  Update dependent calls and types.

* tree-ssa-sccvn.c (vn_tables_s::nary):
Change type to hash_table.  Update dependent calls and types.
(vn_tables_s::phis): Likewise.
(vn_tables_s::references): Likewise.

* tree-ssa-sccvn.h (vn_nary_op_eq): Update parameter and return types.
(vn_reference_eq): Update parameter and return types.

* tree-ssa-structalias.c (pointer_equiv_class_table):
Change type to hash_table.  Update dependent calls and types.
(location_equiv_class_table): Likewise.

* tree-vect-data-refs.c: Consequential changes for making
peeling a hash_table.

* tree-vect-loop.c (new_loop_vec_info): Dependent hash_table update.
(destroy_loop_vec_info): Dependent hash_table update.

* tree-vectorizer.h (peeling_htab):
Change type to hash_table.  Update dependent calls and types.

From-SVN: r198213

14 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/hash-table.h
gcc/statistics.c
gcc/tree-into-ssa.c
gcc/tree-ssa-coalesce.c
gcc/tree-ssa-loop-im.c
gcc/tree-ssa-reassoc.c
gcc/tree-ssa-sccvn.c
gcc/tree-ssa-sccvn.h
gcc/tree-ssa-structalias.c
gcc/tree-vect-data-refs.c
gcc/tree-vect-loop.c
gcc/tree-vectorizer.h

index f55df95ed8af844245635d218665eee7fdf033af..f280abea5d4d37a55247268807b79504a410427e 100644 (file)
@@ -1,3 +1,52 @@
+2013-04-23  Lawrence Crowl  <crowl@google.com>
+
+       * Makefile.in: Update as needed below.
+
+       * hash-table.h (class hash_table):
+       Correct many methods with parameter types compare_type to the correct
+       value_type.  (Correct code was unlikely to notice the change.)
+       (hash_table::elements_with_deleted) New.
+       (class hashtable::iterator): New.
+       (hashtable::begin()): New.
+       (hashtable::end()): New.
+       (FOR_EACH_HASH_TABLE_ELEMENT): New.
+
+       * statistics.c (statistics_hashes):
+       Change type to hash_table.  Update dependent calls and types.
+
+       * tree-into-ssa.c (var_infos):
+       Change type to hash_table.  Update dependent calls and types.
+
+       * tree-ssa-coalesce.c (struct coalesce_list_d.list):
+       Change type to hash_table.  Update dependent calls and types.
+
+       * tree-ssa-loop-im.c (struct mem_ref.refs):
+       Change type to hash_table.  Update dependent calls and types.
+
+       * tree-ssa-reassoc.c (undistribute_ops_list::ctable):
+       Change type to hash_table.  Update dependent calls and types.
+
+       * tree-ssa-sccvn.c (vn_tables_s::nary):
+       Change type to hash_table.  Update dependent calls and types.
+       (vn_tables_s::phis): Likewise.
+       (vn_tables_s::references): Likewise.
+
+       * tree-ssa-sccvn.h (vn_nary_op_eq): Update parameter and return types.
+       (vn_reference_eq): Update parameter and return types.
+
+       * tree-ssa-structalias.c (pointer_equiv_class_table):
+       Change type to hash_table.  Update dependent calls and types.
+       (location_equiv_class_table): Likewise.
+
+       * tree-vect-data-refs.c: Consequential changes for making
+       peeling a hash_table.
+
+       * tree-vect-loop.c (new_loop_vec_info): Dependent hash_table update.
+       (destroy_loop_vec_info): Dependent hash_table update.
+
+       * tree-vectorizer.h (peeling_htab):
+       Change type to hash_table.  Update dependent calls and types.
+
 2013-04-23  Shiva Chen  <shiva0217@gmail.com>
 
         * lra-assigns.c (find_hard_regno_for): Use lra_reg_val_equal_p
index e265730ec937ab7c75bc782c89d055bc6266eefa..84d96d29a1e8b2c781385f895d81c5b982e24119 100644 (file)
@@ -966,7 +966,8 @@ GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_H) \
 TREE_STREAMER_H = tree-streamer.h $(TREE_H) $(LTO_STREAMER_H) \
                  $(STREAMER_HOOKS_H)
 STREAMER_HOOKS_H = streamer-hooks.h $(TREE_H)
-TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) $(TARGET_H)
+TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) $(TARGET_H) \
+       $(HASH_TABLE_H)
 IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) $(GIMPLE_H) alloc-pool.h
 IPA_INLINE_H = ipa-inline.h $(IPA_PROP_H)
 GSTAB_H = gstab.h stab.def
@@ -2255,7 +2256,7 @@ tree-ssa-structalias.o: tree-ssa-structalias.c \
    $(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \
    $(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \
    $(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \
-   $(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \
+   $(GIMPLE_H) $(HASH_TABLE_H) $(FUNCTION_H) $(CGRAPH_H) \
    $(TREE_PASS_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \
    $(CGRAPH_H) $(ALIAS_H) pointer-set.h
 tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
@@ -2275,7 +2276,7 @@ tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(TM_P_H) $(DIAGNOSTIC_CORE_H) \
    $(FUNCTION_H) $(TM_H) coretypes.h \
    langhooks.h domwalk.h $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) \
-   $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASHTAB_H) \
+   $(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASH_TABLE_H) \
    $(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
 tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    $(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \
@@ -2374,7 +2375,7 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
 tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
    $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \
    $(TM_H) coretypes.h $(DUMPFILE_H) $(FLAGS_H) $(CFGLOOP_H) \
-   alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) $(GIMPLE_H) \
+   alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASH_TABLE_H) $(GIMPLE_H) \
    $(TREE_INLINE_H) tree-ssa-propagate.h tree-ssa-sccvn.h \
    $(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h
 gimple-ssa-strength-reduction.o : gimple-ssa-strength-reduction.c $(CONFIG_H) \
@@ -2509,7 +2510,7 @@ tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
    pointer-set.h alloc-pool.h \
    $(TREE_PRETTY_PRINT_H)
 tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
-   $(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \
+   $(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(DIAGNOSTIC_H) \
    $(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) \
    tree-iterator.h $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_INLINE_H) \
    $(VEC_H) langhooks.h alloc-pool.h pointer-set.h $(CFGLOOP_H) \
@@ -2765,7 +2766,7 @@ function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_
    $(TREE_PASS_H) $(DF_H) $(PARAMS_H) bb-reorder.h \
    $(COMMON_TARGET_H)
 statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-   $(TREE_PASS_H) $(TREE_DUMP_H) $(HASHTAB_H) statistics.h $(FUNCTION_H)
+   $(TREE_PASS_H) $(TREE_DUMP_H) $(HASH_TABLE_H) statistics.h $(FUNCTION_H)
 stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) $(TM_H) \
    $(RTL_H) \
    $(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \
index 206423dc58b305b1ba44b98634029b5472e5e62e..00637789923ea5a47955990a7787a7428a7a33b5 100644 (file)
@@ -155,6 +155,47 @@ along with GCC; see the file COPYING3.  If not see
 
       hash_table <pointer_hash <whatever_type>> whatever_type_hash_table;
 
+
+   HASH TABLE ITERATORS
+
+   The hash table provides standard C++ iterators.  For example, consider a
+   hash table of some_info.  We wish to consume each element of the table:
+
+      extern void consume (some_info *);
+
+   We define a convenience typedef and the hash table:
+
+      typedef hash_table <some_info_hasher> info_table_type;
+      info_table_type info_table;
+
+   Then we write the loop in typical C++ style:
+
+      for (info_table_type::iterator iter = info_table.begin ();
+           iter != info_table.end ();
+           ++iter)
+        if ((*iter).status == INFO_READY)
+          consume (&*iter);
+
+   Or with common sub-expression elimination:
+
+      for (info_table_type::iterator iter = info_table.begin ();
+           iter != info_table.end ();
+           ++iter)
+        {
+          some_info &elem = *iter;
+          if (elem.status == INFO_READY)
+            consume (&elem);
+        }
+
+   One can also use a more typical GCC style:
+
+      typedef some_info *some_info_p;
+      some_info *elem_ptr;
+      info_table_type::iterator iter;
+      FOR_EACH_HASH_TABLE_ELEMENT (info_table, elem_ptr, some_info_p, iter)
+        if (elem_ptr->status == INFO_READY)
+          consume (elem_ptr);
+
 */
 
 
@@ -368,6 +409,20 @@ public:
   typedef typename Descriptor::value_type value_type;
   typedef typename Descriptor::compare_type compare_type;
 
+  class iterator
+  {
+  public:
+    inline iterator ();
+    inline iterator (value_type **, value_type **);
+    inline value_type &operator * ();
+    void slide ();
+    inline iterator &operator ++ ();
+    inline bool operator != (const iterator &) const;
+  private:
+    value_type **slot_;
+    value_type **limit_;
+  };
+
 private:
   hash_table_control <value_type> *htab;
 
@@ -379,19 +434,19 @@ public:
   void create (size_t initial_slots);
   bool is_created ();
   void dispose ();
-  value_type *find (const compare_type *comparable);
+  value_type *find (const value_type *value);
   value_type *find_with_hash (const compare_type *comparable, hashval_t hash);
-  value_type **find_slot (const compare_type *comparable,
-                         enum insert_option insert);
+  value_type **find_slot (const value_type *value, enum insert_option insert);
   value_type **find_slot_with_hash (const compare_type *comparable,
                                    hashval_t hash, enum insert_option insert);
   void empty ();
   void clear_slot (value_type **slot);
-  void remove_elt (const compare_type *comparable);
+  void remove_elt (const value_type *value);
   void remove_elt_with_hash (const compare_type *comparable, hashval_t hash);
-  size_t size();
-  size_t elements();
-  double collisions();
+  size_t size ();
+  size_t elements ();
+  size_t elements_with_deleted ();
+  double collisions ();
 
   template <typename Argument,
            int (*Callback) (value_type **slot, Argument argument)>
@@ -400,6 +455,9 @@ public:
   template <typename Argument,
            int (*Callback) (value_type **slot, Argument argument)>
   void traverse (Argument argument);
+
+  iterator begin();
+  iterator end();
 };
 
 
@@ -430,9 +488,9 @@ hash_table <Descriptor, Allocator>::is_created ()
 template <typename Descriptor,
          template <typename Type> class Allocator>
 inline typename Descriptor::value_type *
-hash_table <Descriptor, Allocator>::find (const compare_type *comparable)
+hash_table <Descriptor, Allocator>::find (const value_type *value)
 {
-  return find_with_hash (comparable, Descriptor::hash (comparable));
+  return find_with_hash (value, Descriptor::hash (value));
 }
 
 
@@ -442,9 +500,9 @@ template <typename Descriptor,
          template <typename Type> class Allocator>
 inline typename Descriptor::value_type **
 hash_table <Descriptor, Allocator>
-::find_slot (const compare_type *comparable, enum insert_option insert)
+::find_slot (const value_type *value, enum insert_option insert)
 {
-  return find_slot_with_hash (comparable, Descriptor::hash (comparable), insert);
+  return find_slot_with_hash (value, Descriptor::hash (value), insert);
 }
 
 
@@ -453,9 +511,9 @@ hash_table <Descriptor, Allocator>
 template <typename Descriptor,
          template <typename Type> class Allocator>
 inline void
-hash_table <Descriptor, Allocator>::remove_elt (const compare_type *comparable)
+hash_table <Descriptor, Allocator>::remove_elt (const value_type *value)
 {
-  remove_elt_with_hash (comparable, Descriptor::hash (comparable));
+  remove_elt_with_hash (value, Descriptor::hash (value));
 }
 
 
@@ -475,12 +533,23 @@ hash_table <Descriptor, Allocator>::size()
 template <typename Descriptor,
          template <typename Type> class Allocator>
 inline size_t
-hash_table <Descriptor, Allocator>::elements()
+hash_table <Descriptor, Allocator>::elements ()
 {
   return htab->n_elements - htab->n_deleted;
 }
 
 
+/* Return the current number of elements in this hash table. */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+inline size_t
+hash_table <Descriptor, Allocator>::elements_with_deleted ()
+{
+  return htab->n_elements;
+}
+
+
   /* Return the fraction of fixed collisions during all work with given
      hash table. */
 
@@ -881,4 +950,114 @@ hash_table <Descriptor, Allocator>::traverse (Argument argument)
   traverse_noresize <Argument, Callback> (argument);
 }
 
+
+/* Iterator definitions.  */
+
+/* The default constructor produces the end value.  */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+inline
+hash_table <Descriptor, Allocator>::iterator::iterator ()
+: slot_ (NULL), limit_ (NULL)
+{
+}
+
+/* The parameterized constructor produces the begin value.  */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+inline
+hash_table <Descriptor, Allocator>::iterator::iterator
+   (value_type **slot, value_type **limit)
+: slot_ (slot), limit_ (limit)
+{
+}
+
+/* Obtain the element.  */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+inline typename hash_table <Descriptor, Allocator>::value_type &
+hash_table <Descriptor, Allocator>::iterator::operator * ()
+{
+  return **slot_;
+}
+
+/* Slide down the iterator slots until an active entry is found.  */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+void
+hash_table <Descriptor, Allocator>::iterator::slide ()
+{
+  for ( ; slot_ < limit_; ++slot_ )
+    {
+      value_type *x = *slot_;
+      if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
+        return;
+    }
+  slot_ = NULL;
+  limit_ = NULL;
+}
+
+/* Bump the iterator.  */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+inline typename hash_table <Descriptor, Allocator>::iterator &
+hash_table <Descriptor, Allocator>::iterator::operator ++ ()
+{
+  ++slot_;
+  slide ();
+  return *this;
+}
+
+/* Compare iterators.  */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+inline bool
+hash_table <Descriptor, Allocator>::iterator::
+  operator != (const iterator &other) const
+{
+  return slot_ != other.slot_ || limit_ != other.limit_;
+}
+
+/* Hash table iterator producers.  */
+
+/* The beginning of a hash table iteration.  */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+inline typename hash_table <Descriptor, Allocator>::iterator
+hash_table <Descriptor, Allocator>::begin ()
+{
+  iterator hti (htab->entries, htab->entries + htab->size);
+  hti.slide ();
+  return hti;
+}
+
+/* The end of a hash table iteration.  */
+
+template <typename Descriptor,
+         template <typename Type> class Allocator>
+inline typename hash_table <Descriptor, Allocator>::iterator
+hash_table <Descriptor, Allocator>::end ()
+{
+  return iterator ();
+}
+
+/* Iterate through the elements of hash_table HTAB,
+   using hash_table <....>::iterator ITER,
+   storing each element in RESULT, which is of type TYPE.
+
+   This macro has this form for compatibility with the
+   FOR_EACH_HTAB_ELEMENT currently defined in tree-flow.h.  */
+
+#define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
+  for ((ITER) = (HTAB).begin (); \
+       (ITER) != (HTAB).end () ? (RESULT = &*(ITER) , true) : false; \
+       ++(ITER))
+
 #endif /* TYPED_HASHTAB_H */
index 3b9685d01d0021621dcaa357e0926be78530dce3..3077cc0c36ce5e7dd8751259054f08be20ad6bdc 100644 (file)
@@ -24,7 +24,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-pass.h"
 #include "tree-dump.h"
 #include "statistics.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "function.h"
 
 static int statistics_dump_nr;
@@ -42,42 +42,52 @@ typedef struct statistics_counter_s {
   unsigned HOST_WIDE_INT prev_dumped_count;
 } statistics_counter_t;
 
-/* Array of statistic hashes, indexed by pass id.  */
-static htab_t *statistics_hashes;
-static unsigned nr_statistics_hashes;
+/* Hashtable helpers.  */
+
+struct stats_counter_hasher
+{
+  typedef statistics_counter_t value_type;
+  typedef statistics_counter_t compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+  static inline void remove (value_type *);
+};
 
 /* Hash a statistic counter by its string ID.  */
 
-static hashval_t
-hash_statistics_hash (const void *p)
+inline hashval_t
+stats_counter_hasher::hash (const value_type *c)
 {
-  const statistics_counter_t *const c = (const statistics_counter_t *)p;
   return htab_hash_string (c->id) + c->val;
 }
 
 /* Compare two statistic counters by their string IDs.  */
 
-static int
-hash_statistics_eq (const void *p, const void *q)
+inline bool
+stats_counter_hasher::equal (const value_type *c1, const compare_type *c2)
 {
-  const statistics_counter_t *const c1 = (const statistics_counter_t *)p;
-  const statistics_counter_t *const c2 = (const statistics_counter_t *)q;
   return c1->val == c2->val && strcmp (c1->id, c2->id) == 0;
 }
 
 /* Free a statistics entry.  */
 
-static void
-hash_statistics_free (void *p)
+inline void
+stats_counter_hasher::remove (value_type *v)
 {
-  free (CONST_CAST(char *, ((statistics_counter_t *)p)->id));
-  free (p);
+  free (CONST_CAST(char *, v->id));
+  free (v);
 }
 
+typedef hash_table <stats_counter_hasher> stats_counter_table_type;
+
+/* Array of statistic hashes, indexed by pass id.  */
+static stats_counter_table_type *statistics_hashes;
+static unsigned nr_statistics_hashes;
+
 /* Return the current hashtable to be used for recording or printing
    statistics.  */
 
-static htab_t
+static stats_counter_table_type
 curr_statistics_hash (void)
 {
   unsigned idx;
@@ -86,20 +96,20 @@ curr_statistics_hash (void)
   idx = current_pass->static_pass_number;
 
   if (idx < nr_statistics_hashes
-      && statistics_hashes[idx] != NULL)
+      && statistics_hashes[idx].is_created ())
     return statistics_hashes[idx];
 
   if (idx >= nr_statistics_hashes)
     {
-      statistics_hashes = XRESIZEVEC (struct htab *, statistics_hashes, idx+1);
+      statistics_hashes = XRESIZEVEC (stats_counter_table_type,
+                                     statistics_hashes, idx+1);
       memset (statistics_hashes + nr_statistics_hashes, 0,
-             (idx + 1 - nr_statistics_hashes) * sizeof (htab_t));
+             (idx + 1 - nr_statistics_hashes)
+             * sizeof (stats_counter_table_type));
       nr_statistics_hashes = idx + 1;
     }
 
-  statistics_hashes[idx] = htab_create (15, hash_statistics_hash,
-                                       hash_statistics_eq,
-                                       hash_statistics_free);
+  statistics_hashes[idx].create (15);
 
   return statistics_hashes[idx];
 }
@@ -107,10 +117,11 @@ curr_statistics_hash (void)
 /* Helper for statistics_fini_pass.  Print the counter difference
    since the last dump for the pass dump files.  */
 
-static int
-statistics_fini_pass_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+statistics_fini_pass_1 (statistics_counter_t **slot,
+                       void *data ATTRIBUTE_UNUSED)
 {
-  statistics_counter_t *counter = (statistics_counter_t *)*slot;
+  statistics_counter_t *counter = *slot;
   unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
   if (count == 0)
     return 1;
@@ -127,10 +138,11 @@ statistics_fini_pass_1 (void **slot, void *data ATTRIBUTE_UNUSED)
 /* Helper for statistics_fini_pass.  Print the counter difference
    since the last dump for the statistics dump.  */
 
-static int
-statistics_fini_pass_2 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+statistics_fini_pass_2 (statistics_counter_t **slot,
+                       void *data ATTRIBUTE_UNUSED)
 {
-  statistics_counter_t *counter = (statistics_counter_t *)*slot;
+  statistics_counter_t *counter = *slot;
   unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
   if (count == 0)
     return 1;
@@ -157,10 +169,11 @@ statistics_fini_pass_2 (void **slot, void *data ATTRIBUTE_UNUSED)
 
 /* Helper for statistics_fini_pass, reset the counters.  */
 
-static int
-statistics_fini_pass_3 (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+statistics_fini_pass_3 (statistics_counter_t **slot,
+                       void *data ATTRIBUTE_UNUSED)
 {
-  statistics_counter_t *counter = (statistics_counter_t *)*slot;
+  statistics_counter_t *counter = *slot;
   counter->prev_dumped_count = counter->count;
   return 1;
 }
@@ -179,26 +192,25 @@ statistics_fini_pass (void)
       fprintf (dump_file, "\n");
       fprintf (dump_file, "Pass statistics:\n");
       fprintf (dump_file, "----------------\n");
-      htab_traverse_noresize (curr_statistics_hash (),
-                             statistics_fini_pass_1, NULL);
+      curr_statistics_hash ()
+       .traverse_noresize <void *, statistics_fini_pass_1> (NULL);
       fprintf (dump_file, "\n");
     }
   if (statistics_dump_file
       && !(statistics_dump_flags & TDF_STATS
           || statistics_dump_flags & TDF_DETAILS))
-    htab_traverse_noresize (curr_statistics_hash (),
-                           statistics_fini_pass_2, NULL);
-  htab_traverse_noresize (curr_statistics_hash (),
-                         statistics_fini_pass_3, NULL);
+    curr_statistics_hash ()
+      .traverse_noresize <void *, statistics_fini_pass_2> (NULL);
+  curr_statistics_hash ()
+    .traverse_noresize <void *, statistics_fini_pass_3> (NULL);
 }
 
 /* Helper for printing summary information.  */
 
-static int
-statistics_fini_1 (void **slot, void *data)
+int
+statistics_fini_1 (statistics_counter_t **slot, opt_pass *pass)
 {
-  struct opt_pass *pass = (struct opt_pass *)data;
-  statistics_counter_t *counter = (statistics_counter_t *)*slot;
+  statistics_counter_t *counter = *slot;
   if (counter->count == 0)
     return 1;
   if (counter->histogram_p)
@@ -230,10 +242,11 @@ statistics_fini (void)
     {
       unsigned i;
       for (i = 0; i < nr_statistics_hashes; ++i)
-       if (statistics_hashes[i] != NULL
+       if (statistics_hashes[i].is_created ()
            && get_pass_for_id (i) != NULL)
-         htab_traverse_noresize (statistics_hashes[i],
-                                 statistics_fini_1, get_pass_for_id (i));
+         statistics_hashes[i]
+           .traverse_noresize <opt_pass *, statistics_fini_1>
+           (get_pass_for_id (i));
     }
 
   dump_end (statistics_dump_nr, statistics_dump_file);
@@ -261,14 +274,14 @@ statistics_init (void)
    and HISTOGRAM_P.  */
 
 static statistics_counter_t *
-lookup_or_add_counter (htab_t hash, const char *id, int val,
+lookup_or_add_counter (stats_counter_table_type hash, const char *id, int val,
                       bool histogram_p)
 {
   statistics_counter_t **counter;
   statistics_counter_t c;
   c.id = id;
   c.val = val;
-  counter = (statistics_counter_t **) htab_find_slot (hash, &c, INSERT);
+  counter = hash.find_slot (&c, INSERT);
   if (!*counter)
     {
       *counter = XNEW (struct statistics_counter_s);
index 65c15daca4ce11dbff42b64636d1fbc595673bef..f028b25b19a0df9562c2faa43d704a0ed60041ec 100644 (file)
@@ -33,7 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-flow.h"
 #include "gimple.h"
 #include "tree-inline.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "tree-pass.h"
 #include "cfgloop.h"
 #include "domwalk.h"
@@ -160,9 +160,32 @@ struct var_info_d
 typedef struct var_info_d *var_info_p;
 
 
+/* VAR_INFOS hashtable helpers.  */
+
+struct var_info_hasher : typed_free_remove <var_info_d>
+{
+  typedef var_info_d value_type;
+  typedef var_info_d compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+var_info_hasher::hash (const value_type *p)
+{
+  return DECL_UID (p->var);
+}
+
+inline bool
+var_info_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+  return p1->var == p2->var;
+}
+
+
 /* Each entry in VAR_INFOS contains an element of type STRUCT 
    VAR_INFO_D.  */
-static htab_t var_infos;
+static hash_table <var_info_hasher> var_infos;
 
 
 /* Information stored for SSA names.  */
@@ -340,17 +363,17 @@ static inline var_info_p
 get_var_info (tree decl)
 {
   struct var_info_d vi;
-  void **slot;
+  var_info_d **slot;
   vi.var = decl;
-  slot = htab_find_slot_with_hash (var_infos, &vi, DECL_UID (decl), INSERT);
+  slot = var_infos.find_slot_with_hash (&vi, DECL_UID (decl), INSERT);
   if (*slot == NULL)
     {
       var_info_p v = XCNEW (struct var_info_d);
       v->var = decl;
-      *slot = (void *)v;
+      *slot = v;
       return v;
     }
-  return (var_info_p) *slot;
+  return *slot;
 }
 
 
@@ -1044,15 +1067,15 @@ insert_phi_nodes_compare_var_infos (const void *a, const void *b)
 static void
 insert_phi_nodes (bitmap_head *dfs)
 {
-  htab_iterator hi;
+  hash_table <var_info_hasher>::iterator hi;
   unsigned i;
   var_info_p info;
   vec<var_info_p> vars;
 
   timevar_push (TV_TREE_INSERT_PHI_NODES);
 
-  vars.create (htab_elements (var_infos));
-  FOR_EACH_HTAB_ELEMENT (var_infos, info, var_info_p, hi)
+  vars.create (var_infos.elements ());
+  FOR_EACH_HASH_TABLE_ELEMENT (var_infos, info, var_info_p, hi)
     if (info->info.need_phi_state != NEED_PHI_STATE_NO)
       vars.quick_push (info);
 
@@ -1632,12 +1655,12 @@ debug_tree_ssa (void)
 /* Dump statistics for the hash table HTAB.  */
 
 static void
-htab_statistics (FILE *file, htab_t htab)
+htab_statistics (FILE *file, hash_table <var_info_hasher> htab)
 {
   fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
-          (long) htab_size (htab),
-          (long) htab_elements (htab),
-          htab_collisions (htab));
+          (long) htab.size (),
+          (long) htab.elements (),
+          htab.collisions ());
 }
 
 
@@ -1646,7 +1669,7 @@ htab_statistics (FILE *file, htab_t htab)
 void
 dump_tree_ssa_stats (FILE *file)
 {
-  if (var_infos)
+  if (var_infos.is_created ())
     {
       fprintf (file, "\nHash table statistics:\n");
       fprintf (file, "    var_infos:   ");
@@ -1665,29 +1688,12 @@ debug_tree_ssa_stats (void)
 }
 
 
-/* Hashing and equality functions for VAR_INFOS.  */
-
-static hashval_t
-var_info_hash (const void *p)
-{
-  return DECL_UID (((const struct var_info_d *)p)->var);
-}
-
-static int
-var_info_eq (const void *p1, const void *p2)
-{
-  return ((const struct var_info_d *)p1)->var
-        == ((const struct var_info_d *)p2)->var;
-}
-
-
 /* Callback for htab_traverse to dump the VAR_INFOS hash table.  */
 
-static int
-debug_var_infos_r (void **slot, void *data)
+int
+debug_var_infos_r (var_info_d **slot, FILE *file)
 {
-  FILE *file = (FILE *) data;
-  struct var_info_d *info = (struct var_info_d *) *slot;
+  struct var_info_d *info = *slot;
 
   fprintf (file, "VAR: ");
   print_generic_expr (file, info->var, dump_flags);
@@ -1708,8 +1714,8 @@ void
 dump_var_infos (FILE *file)
 {
   fprintf (file, "\n\nDefinition and live-in blocks:\n\n");
-  if (var_infos)
-    htab_traverse (var_infos, debug_var_infos_r, file);
+  if (var_infos.is_created ())
+    var_infos.traverse <FILE *, debug_var_infos_r> (file);
 }
 
 
@@ -2216,7 +2222,7 @@ rewrite_blocks (basic_block entry, enum rewrite_mode what)
   if (dump_file && (dump_flags & TDF_STATS))
     {
       dump_dfa_stats (dump_file);
-      if (var_infos)
+      if (var_infos.is_created ())
        dump_tree_ssa_stats (dump_file);
     }
 
@@ -2296,9 +2302,8 @@ init_ssa_renamer (void)
   cfun->gimple_df->in_ssa_p = false;
 
   /* Allocate memory for the DEF_BLOCKS hash table.  */
-  gcc_assert (var_infos == NULL);
-  var_infos = htab_create (vec_safe_length (cfun->local_decls),
-                          var_info_hash, var_info_eq, free);
+  gcc_assert (!var_infos.is_created ());
+  var_infos.create (vec_safe_length (cfun->local_decls));
 
   bitmap_obstack_initialize (&update_ssa_obstack);
 }
@@ -2309,11 +2314,8 @@ init_ssa_renamer (void)
 static void
 fini_ssa_renamer (void)
 {
-  if (var_infos)
-    {
-      htab_delete (var_infos);
-      var_infos = NULL;
-    }
+  if (var_infos.is_created ())
+    var_infos.dispose ();
 
   bitmap_obstack_release (&update_ssa_obstack);
 
@@ -3189,7 +3191,7 @@ update_ssa (unsigned update_flags)
     {
       /* If we rename bare symbols initialize the mapping to
          auxiliar info we need to keep track of.  */
-      var_infos = htab_create (47, var_info_hash, var_info_eq, free);
+      var_infos.create (47);
 
       /* If we have to rename some symbols from scratch, we need to
         start the process at the root of the CFG.  FIXME, it should
index fd9c2cbdb33ffd57ef5238772e09545b3d90b52a..354b5f182a8bb28cef73d8dffe025fb4ebfb37ae 100644 (file)
@@ -49,6 +49,41 @@ typedef struct coalesce_pair
 } * coalesce_pair_p;
 typedef const struct coalesce_pair *const_coalesce_pair_p;
 
+/* Coalesce pair hashtable helpers.  */
+
+struct coalesce_pair_hasher : typed_noop_remove <coalesce_pair>
+{
+  typedef coalesce_pair value_type;
+  typedef coalesce_pair compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash function for coalesce list.  Calculate hash for PAIR.   */
+
+inline hashval_t
+coalesce_pair_hasher::hash (const value_type *pair)
+{
+  hashval_t a = (hashval_t)(pair->first_element);
+  hashval_t b = (hashval_t)(pair->second_element);
+
+  return b * (b - 1) / 2 + a;
+}
+
+/* Equality function for coalesce list hash table.  Compare PAIR1 and PAIR2,
+   returning TRUE if the two pairs are equivalent.  */
+
+inline bool
+coalesce_pair_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+  return (p1->first_element == p2->first_element
+         && p1->second_element == p2->second_element);
+}
+
+typedef hash_table <coalesce_pair_hasher> coalesce_table_type;
+typedef coalesce_table_type::iterator coalesce_iterator_type;
+
+
 typedef struct cost_one_pair_d
 {
   int first_element;
@@ -60,7 +95,7 @@ typedef struct cost_one_pair_d
 
 typedef struct coalesce_list_d
 {
-  htab_t list;                 /* Hash table.  */
+  coalesce_table_type list;    /* Hash table.  */
   coalesce_pair_p *sorted;     /* List when sorted.  */
   int num_sorted;              /* Number in the sorted list.  */
   cost_one_pair_p cost_one_list;/* Single use coalesces with cost 1.  */
@@ -185,34 +220,6 @@ pop_best_coalesce (coalesce_list_p cl, int *p1, int *p2)
 }
 
 
-#define COALESCE_HASH_FN(R1, R2) ((R2) * ((R2) - 1) / 2 + (R1))
-
-/* Hash function for coalesce list.  Calculate hash for PAIR.   */
-
-static unsigned int
-coalesce_pair_map_hash (const void *pair)
-{
-  hashval_t a = (hashval_t)(((const_coalesce_pair_p)pair)->first_element);
-  hashval_t b = (hashval_t)(((const_coalesce_pair_p)pair)->second_element);
-
-  return COALESCE_HASH_FN (a,b);
-}
-
-
-/* Equality function for coalesce list hash table.  Compare PAIR1 and PAIR2,
-   returning TRUE if the two pairs are equivalent.  */
-
-static int
-coalesce_pair_map_eq (const void *pair1, const void *pair2)
-{
-  const_coalesce_pair_p const p1 = (const_coalesce_pair_p) pair1;
-  const_coalesce_pair_p const p2 = (const_coalesce_pair_p) pair2;
-
-  return (p1->first_element == p2->first_element
-         && p1->second_element == p2->second_element);
-}
-
-
 /* Create a new empty coalesce list object and return it.  */
 
 static inline coalesce_list_p
@@ -225,8 +232,7 @@ create_coalesce_list (void)
     size = 40;
 
   list = (coalesce_list_p) xmalloc (sizeof (struct coalesce_list_d));
-  list->list = htab_create (size, coalesce_pair_map_hash,
-                           coalesce_pair_map_eq, NULL);
+  list->list.create (size);
   list->sorted = NULL;
   list->num_sorted = 0;
   list->cost_one_list = NULL;
@@ -240,7 +246,7 @@ static inline void
 delete_coalesce_list (coalesce_list_p cl)
 {
   gcc_assert (cl->cost_one_list == NULL);
-  htab_delete (cl->list);
+  cl->list.dispose ();
   free (cl->sorted);
   gcc_assert (cl->num_sorted == 0);
   free (cl);
@@ -255,7 +261,7 @@ static coalesce_pair_p
 find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
 {
   struct coalesce_pair p;
-  void **slot;
+  coalesce_pair **slot;
   unsigned int hash;
 
   /* Normalize so that p1 is the smaller value.  */
@@ -270,9 +276,8 @@ find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
       p.second_element = p2;
     }
 
-  hash = coalesce_pair_map_hash (&p);
-  slot = htab_find_slot_with_hash (cl->list, &p, hash,
-                                  create ? INSERT : NO_INSERT);
+  hash = coalesce_pair_hasher::hash (&p);
+  slot = cl->list.find_slot_with_hash (&p, hash, create ? INSERT : NO_INSERT);
   if (!slot)
     return NULL;
 
@@ -283,7 +288,7 @@ find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
       pair->first_element = p.first_element;
       pair->second_element = p.second_element;
       pair->cost = 0;
-      *slot = (void *)pair;
+      *slot = pair;
     }
 
   return (struct coalesce_pair *) *slot;
@@ -355,56 +360,14 @@ compare_pairs (const void *p1, const void *p2)
 static inline int
 num_coalesce_pairs (coalesce_list_p cl)
 {
-  return htab_elements (cl->list);
-}
-
-
-/* Iterator over hash table pairs.  */
-typedef struct
-{
-  htab_iterator hti;
-} coalesce_pair_iterator;
-
-
-/* Return first partition pair from list CL, initializing iterator ITER.  */
-
-static inline coalesce_pair_p
-first_coalesce_pair (coalesce_list_p cl, coalesce_pair_iterator *iter)
-{
-  coalesce_pair_p pair;
-
-  pair = (coalesce_pair_p) first_htab_element (&(iter->hti), cl->list);
-  return pair;
-}
-
-
-/* Return TRUE if there are no more partitions in for ITER to process.  */
-
-static inline bool
-end_coalesce_pair_p (coalesce_pair_iterator *iter)
-{
-  return end_htab_p (&(iter->hti));
-}
-
-
-/* Return the next partition pair to be visited by ITER.  */
-
-static inline coalesce_pair_p
-next_coalesce_pair (coalesce_pair_iterator *iter)
-{
-  coalesce_pair_p pair;
-
-  pair = (coalesce_pair_p) next_htab_element (&(iter->hti));
-  return pair;
+  return cl->list.elements ();
 }
 
 
 /* Iterate over CL using ITER, returning values in PAIR.  */
 
 #define FOR_EACH_PARTITION_PAIR(PAIR, ITER, CL)                \
-  for ((PAIR) = first_coalesce_pair ((CL), &(ITER));   \
-       !end_coalesce_pair_p (&(ITER));                 \
-       (PAIR) = next_coalesce_pair (&(ITER)))
+  FOR_EACH_HASH_TABLE_ELEMENT ((CL)->list, (PAIR), coalesce_pair_p, (ITER))
 
 
 /* Prepare CL for removal of preferred pairs.  When finished they are sorted
@@ -415,7 +378,7 @@ sort_coalesce_list (coalesce_list_p cl)
 {
   unsigned x, num;
   coalesce_pair_p p;
-  coalesce_pair_iterator ppi;
+  coalesce_iterator_type ppi;
 
   gcc_assert (cl->sorted == NULL);
 
@@ -461,7 +424,8 @@ static void
 dump_coalesce_list (FILE *f, coalesce_list_p cl)
 {
   coalesce_pair_p node;
-  coalesce_pair_iterator ppi;
+  coalesce_iterator_type ppi;
+
   int x;
   tree var;
 
index 188af0012a7f828bcfe1c0364a4ba509b0b0bc9d..90e4d361e2f7d6fe298ff6660bbdd37a7d41f38e 100644 (file)
@@ -31,7 +31,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "params.h"
 #include "tree-pass.h"
 #include "flags.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "tree-affine.h"
 #include "pointer-set.h"
 #include "tree-ssa-propagate.h"
@@ -133,6 +133,32 @@ typedef struct mem_ref
    and its subloops.  */
 #define LOOP_DEP_BIT(loopnum, storedp) (2 * (loopnum) + (storedp ? 1 : 0))
 
+/* Mem_ref hashtable helpers.  */
+
+struct mem_ref_hasher : typed_noop_remove <mem_ref>
+{
+  typedef mem_ref value_type;
+  typedef tree_node compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* A hash function for struct mem_ref object OBJ.  */
+
+inline hashval_t
+mem_ref_hasher::hash (const value_type *mem)
+{
+  return mem->hash;
+}
+
+/* An equality function for struct mem_ref object MEM1 with
+   memory reference OBJ2.  */
+
+inline bool
+mem_ref_hasher::equal (const value_type *mem1, const compare_type *obj2)
+{
+  return operand_equal_p (mem1->mem.ref, (const_tree) obj2, 0);
+}
 
 
 /* Description of memory accesses in loops.  */
@@ -140,7 +166,7 @@ typedef struct mem_ref
 static struct
 {
   /* The hash table of memory references accessed in loops.  */
-  htab_t refs;
+  hash_table <mem_ref_hasher> refs;
 
   /* The list of memory references.  */
   vec<mem_ref_p> refs_list;
@@ -646,7 +672,7 @@ mem_ref_in_stmt (gimple stmt)
   gcc_assert (!store);
 
   hash = iterative_hash_expr (*mem, 0);
-  ref = (mem_ref_p) htab_find_with_hash (memory_accesses.refs, *mem, hash);
+  ref = memory_accesses.refs.find_with_hash (*mem, hash);
 
   gcc_assert (ref != NULL);
   return ref;
@@ -1411,27 +1437,6 @@ force_move_till (tree ref, tree *index, void *data)
   return true;
 }
 
-/* A hash function for struct mem_ref object OBJ.  */
-
-static hashval_t
-memref_hash (const void *obj)
-{
-  const struct mem_ref *const mem = (const struct mem_ref *) obj;
-
-  return mem->hash;
-}
-
-/* An equality function for struct mem_ref object OBJ1 with
-   memory reference OBJ2.  */
-
-static int
-memref_eq (const void *obj1, const void *obj2)
-{
-  const struct mem_ref *const mem1 = (const struct mem_ref *) obj1;
-
-  return operand_equal_p (mem1->mem.ref, (const_tree) obj2, 0);
-}
-
 /* A function to free the mem_ref object OBJ.  */
 
 static void
@@ -1502,7 +1507,7 @@ gather_mem_refs_stmt (struct loop *loop, gimple stmt)
 {
   tree *mem = NULL;
   hashval_t hash;
-  PTR *slot;
+  mem_ref **slot;
   mem_ref_p ref;
   bool is_stored;
   unsigned id;
@@ -1526,8 +1531,7 @@ gather_mem_refs_stmt (struct loop *loop, gimple stmt)
   else
     {
       hash = iterative_hash_expr (*mem, 0);
-      slot = htab_find_slot_with_hash (memory_accesses.refs,
-                                      *mem, hash, INSERT);
+      slot = memory_accesses.refs.find_slot_with_hash (*mem, hash, INSERT);
       if (*slot)
        {
          ref = (mem_ref_p) *slot;
@@ -2553,7 +2557,7 @@ tree_ssa_lim_initialize (void)
 
   alloc_aux_for_edges (0);
 
-  memory_accesses.refs = htab_create (100, memref_hash, memref_eq, NULL);
+  memory_accesses.refs.create (100);
   memory_accesses.refs_list.create (100);
   /* Allocate a special, unanalyzable mem-ref with ID zero.  */
   memory_accesses.refs_list.quick_push
@@ -2596,7 +2600,7 @@ tree_ssa_lim_finalize (void)
   bitmap_obstack_release (&lim_bitmap_obstack);
   pointer_map_destroy (lim_aux_data_map);
 
-  htab_delete (memory_accesses.refs);
+  memory_accesses.refs.dispose ();
 
   FOR_EACH_VEC_ELT (memory_accesses.refs_list, i, ref)
     memref_free (ref);
index 0089dc515dec03b20da974a8e579476bd1f94bbb..4fc19cb551eda29a067b2f656903ed6a03e3ff99 100644 (file)
@@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "hash-table.h"
 #include "tm.h"
 #include "tree.h"
 #include "basic-block.h"
@@ -943,10 +944,23 @@ typedef struct oecount_s {
 /* The heap for the oecount hashtable and the sorted list of operands.  */
 static vec<oecount> cvec;
 
+
+/* Oecount hashtable helpers.  */
+
+struct oecount_hasher : typed_noop_remove <void>
+{
+  /* Note that this hash table stores integers, not pointers.
+     So, observe the casting in the member functions.  */
+  typedef void value_type;
+  typedef void compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
 /* Hash function for oecount.  */
 
-static hashval_t
-oecount_hash (const void *p)
+inline hashval_t
+oecount_hasher::hash (const value_type *p)
 {
   const oecount *c = &cvec[(size_t)p - 42];
   return htab_hash_pointer (c->op) ^ (hashval_t)c->oecode;
@@ -954,8 +968,8 @@ oecount_hash (const void *p)
 
 /* Comparison function for oecount.  */
 
-static int
-oecount_eq (const void *p1, const void *p2)
+inline bool
+oecount_hasher::equal (const value_type *p1, const compare_type *p2)
 {
   const oecount *c1 = &cvec[(size_t)p1 - 42];
   const oecount *c2 = &cvec[(size_t)p2 - 42];
@@ -1257,7 +1271,7 @@ undistribute_ops_list (enum tree_code opcode,
   unsigned nr_candidates, nr_candidates2;
   sbitmap_iterator sbi0;
   vec<operand_entry_t> *subops;
-  htab_t ctable;
+  hash_table <oecount_hasher> ctable;
   bool changed = false;
   int next_oecount_id = 0;
 
@@ -1305,7 +1319,7 @@ undistribute_ops_list (enum tree_code opcode,
 
   /* Build linearized sub-operand lists and the counting table.  */
   cvec.create (0);
-  ctable = htab_create (15, oecount_hash, oecount_eq, NULL);
+  ctable.create (15);
   /* ??? Macro arguments cannot have multi-argument template types in
      them.  This typedef is needed to workaround that limitation.  */
   typedef vec<operand_entry_t> vec_operand_entry_t_heap;
@@ -1332,7 +1346,7 @@ undistribute_ops_list (enum tree_code opcode,
          c.op = oe1->op;
          cvec.safe_push (c);
          idx = cvec.length () + 41;
-         slot = htab_find_slot (ctable, (void *)idx, INSERT);
+         slot = ctable.find_slot ((void *)idx, INSERT);
          if (!*slot)
            {
              *slot = (void *)idx;
@@ -1344,7 +1358,7 @@ undistribute_ops_list (enum tree_code opcode,
            }
        }
     }
-  htab_delete (ctable);
+  ctable.dispose ();
 
   /* Sort the counting table.  */
   cvec.qsort (oecount_cmp);
index e7aefbf0551dae86f658e1a2d4cfcf74757993b2..07bfdcccb81beb56075db9e133cc6360f38d6bd4 100644 (file)
@@ -29,7 +29,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-flow.h"
 #include "gimple.h"
 #include "dumpfile.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "alloc-pool.h"
 #include "flags.h"
 #include "bitmap.h"
@@ -96,19 +96,187 @@ along with GCC; see the file COPYING3.  If not see
    structure copies.
 */
 
+
+/* vn_nary_op hashtable helpers.  */
+
+struct vn_nary_op_hasher : typed_noop_remove <vn_nary_op_s>
+{
+  typedef vn_nary_op_s value_type;
+  typedef vn_nary_op_s compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Return the computed hashcode for nary operation P1.  */
+
+inline hashval_t
+vn_nary_op_hasher::hash (const value_type *vno1)
+{
+  return vno1->hashcode;
+}
+
+/* Compare nary operations P1 and P2 and return true if they are
+   equivalent.  */
+
+inline bool
+vn_nary_op_hasher::equal (const value_type *vno1, const compare_type *vno2)
+{
+  return vn_nary_op_eq (vno1, vno2);
+}
+
+typedef hash_table <vn_nary_op_hasher> vn_nary_op_table_type;
+typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type;
+
+
+/* vn_phi hashtable helpers.  */
+
+static int
+vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2);
+
+struct vn_phi_hasher
+{ 
+  typedef vn_phi_s value_type;
+  typedef vn_phi_s compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+  static inline void remove (value_type *);
+};
+
+/* Return the computed hashcode for phi operation P1.  */
+
+inline hashval_t
+vn_phi_hasher::hash (const value_type *vp1)
+{
+  return vp1->hashcode;
+}
+
+/* Compare two phi entries for equality, ignoring VN_TOP arguments.  */
+
+inline bool
+vn_phi_hasher::equal (const value_type *vp1, const compare_type *vp2)
+{
+  return vn_phi_eq (vp1, vp2);
+}
+
+/* Free a phi operation structure VP.  */
+
+inline void
+vn_phi_hasher::remove (value_type *phi)
+{
+  phi->phiargs.release ();
+}
+
+typedef hash_table <vn_phi_hasher> vn_phi_table_type;
+typedef vn_phi_table_type::iterator vn_phi_iterator_type;
+
+
+/* Compare two reference operands P1 and P2 for equality.  Return true if
+   they are equal, and false otherwise.  */
+
+static int
+vn_reference_op_eq (const void *p1, const void *p2)
+{
+  const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
+  const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
+
+  return (vro1->opcode == vro2->opcode
+         /* We do not care for differences in type qualification.  */
+         && (vro1->type == vro2->type
+             || (vro1->type && vro2->type
+                 && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
+                                        TYPE_MAIN_VARIANT (vro2->type))))
+         && expressions_equal_p (vro1->op0, vro2->op0)
+         && expressions_equal_p (vro1->op1, vro2->op1)
+         && expressions_equal_p (vro1->op2, vro2->op2));
+}
+
+/* Free a reference operation structure VP.  */
+
+static inline void
+free_reference (vn_reference_s *vr)
+{
+  vr->operands.release ();
+}
+
+
+/* vn_reference hashtable helpers.  */
+
+struct vn_reference_hasher
+{
+  typedef vn_reference_s value_type;
+  typedef vn_reference_s compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+  static inline void remove (value_type *);
+};
+
+/* Return the hashcode for a given reference operation P1.  */
+
+inline hashval_t
+vn_reference_hasher::hash (const value_type *vr1)
+{
+  return vr1->hashcode;
+}
+
+inline bool
+vn_reference_hasher::equal (const value_type *v, const compare_type *c)
+{
+  return vn_reference_eq (v, c);
+}
+
+inline void
+vn_reference_hasher::remove (value_type *v)
+{
+  free_reference (v);
+}
+
+typedef hash_table <vn_reference_hasher> vn_reference_table_type;
+typedef vn_reference_table_type::iterator vn_reference_iterator_type;
+
+
 /* The set of hashtables and alloc_pool's for their items.  */
 
 typedef struct vn_tables_s
 {
-  htab_t nary;
-  htab_t phis;
-  htab_t references;
+  vn_nary_op_table_type nary;
+  vn_phi_table_type phis;
+  vn_reference_table_type references;
   struct obstack nary_obstack;
   alloc_pool phis_pool;
   alloc_pool references_pool;
 } *vn_tables_t;
 
-static htab_t constant_to_value_id;
+
+/* vn_constant hashtable helpers.  */
+
+struct vn_constant_hasher : typed_free_remove <vn_constant_s>
+{ 
+  typedef vn_constant_s value_type;
+  typedef vn_constant_s compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Hash table hash function for vn_constant_t.  */
+
+inline hashval_t
+vn_constant_hasher::hash (const value_type *vc1)
+{
+  return vc1->hashcode;
+}
+
+/* Hash table equality function for vn_constant_t.  */
+
+inline bool
+vn_constant_hasher::equal (const value_type *vc1, const compare_type *vc2)
+{
+  if (vc1->hashcode != vc2->hashcode)
+    return false;
+
+  return vn_constant_eq_with_type (vc1->constant, vc2->constant);
+}
+
+static hash_table <vn_constant_hasher> constant_to_value_id;
 static bitmap constant_value_ids;
 
 
@@ -338,62 +506,20 @@ vn_get_stmt_kind (gimple stmt)
     }
 }
 
-/* Free a phi operation structure VP.  */
-
-static void
-free_phi (void *vp)
-{
-  vn_phi_t phi = (vn_phi_t) vp;
-  phi->phiargs.release ();
-}
-
-/* Free a reference operation structure VP.  */
-
-static void
-free_reference (void *vp)
-{
-  vn_reference_t vr = (vn_reference_t) vp;
-  vr->operands.release ();
-}
-
-/* Hash table equality function for vn_constant_t.  */
-
-static int
-vn_constant_eq (const void *p1, const void *p2)
-{
-  const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
-  const struct vn_constant_s *vc2 = (const struct vn_constant_s *) p2;
-
-  if (vc1->hashcode != vc2->hashcode)
-    return false;
-
-  return vn_constant_eq_with_type (vc1->constant, vc2->constant);
-}
-
-/* Hash table hash function for vn_constant_t.  */
-
-static hashval_t
-vn_constant_hash (const void *p1)
-{
-  const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
-  return vc1->hashcode;
-}
-
 /* Lookup a value id for CONSTANT and return it.  If it does not
    exist returns 0.  */
 
 unsigned int
 get_constant_value_id (tree constant)
 {
-  void **slot;
+  vn_constant_s **slot;
   struct vn_constant_s vc;
 
   vc.hashcode = vn_hash_constant_with_type (constant);
   vc.constant = constant;
-  slot = htab_find_slot_with_hash (constant_to_value_id, &vc,
-                                  vc.hashcode, NO_INSERT);
+  slot = constant_to_value_id.find_slot_with_hash (&vc, vc.hashcode, NO_INSERT);
   if (slot)
-    return ((vn_constant_t)*slot)->value_id;
+    return (*slot)->value_id;
   return 0;
 }
 
@@ -403,22 +529,21 @@ get_constant_value_id (tree constant)
 unsigned int
 get_or_alloc_constant_value_id (tree constant)
 {
-  void **slot;
+  vn_constant_s **slot;
   struct vn_constant_s vc;
   vn_constant_t vcp;
 
   vc.hashcode = vn_hash_constant_with_type (constant);
   vc.constant = constant;
-  slot = htab_find_slot_with_hash (constant_to_value_id, &vc,
-                                  vc.hashcode, INSERT);
+  slot = constant_to_value_id.find_slot_with_hash (&vc, vc.hashcode, INSERT);
   if (*slot)
-    return ((vn_constant_t)*slot)->value_id;
+    return (*slot)->value_id;
 
   vcp = XNEW (struct vn_constant_s);
   vcp->hashcode = vc.hashcode;
   vcp->constant = constant;
   vcp->value_id = get_next_value_id ();
-  *slot = (void *) vcp;
+  *slot = vcp;
   bitmap_set_bit (constant_value_ids, vcp->value_id);
   return vcp->value_id;
 }
@@ -431,26 +556,6 @@ value_id_constant_p (unsigned int v)
   return bitmap_bit_p (constant_value_ids, v);
 }
 
-/* Compare two reference operands P1 and P2 for equality.  Return true if
-   they are equal, and false otherwise.  */
-
-static int
-vn_reference_op_eq (const void *p1, const void *p2)
-{
-  const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
-  const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
-
-  return (vro1->opcode == vro2->opcode
-         /* We do not care for differences in type qualification.  */
-         && (vro1->type == vro2->type
-             || (vro1->type && vro2->type
-                 && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
-                                        TYPE_MAIN_VARIANT (vro2->type))))
-         && expressions_equal_p (vro1->op0, vro2->op0)
-         && expressions_equal_p (vro1->op1, vro2->op1)
-         && expressions_equal_p (vro1->op2, vro2->op2));
-}
-
 /* Compute the hash for a reference operand VRO1.  */
 
 static hashval_t
@@ -466,15 +571,6 @@ vn_reference_op_compute_hash (const vn_reference_op_t vro1, hashval_t result)
   return result;
 }
 
-/* Return the hashcode for a given reference operation P1.  */
-
-static hashval_t
-vn_reference_hash (const void *p1)
-{
-  const_vn_reference_t const vr1 = (const_vn_reference_t) p1;
-  return vr1->hashcode;
-}
-
 /* Compute a hash for the reference operation VR1 and return it.  */
 
 hashval_t
@@ -524,16 +620,14 @@ vn_reference_compute_hash (const vn_reference_t vr1)
   return result;
 }
 
-/* Return true if reference operations P1 and P2 are equivalent.  This
+/* Return true if reference operations VR1 and VR2 are equivalent.  This
    means they have the same set of operands and vuses.  */
 
-int
-vn_reference_eq (const void *p1, const void *p2)
+bool
+vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2)
 {
   unsigned i, j;
 
-  const_vn_reference_t const vr1 = (const_vn_reference_t) p1;
-  const_vn_reference_t const vr2 = (const_vn_reference_t) p2;
   if (vr1->hashcode != vr2->hashcode)
     return false;
 
@@ -1346,15 +1440,13 @@ valueize_shared_reference_ops_from_call (gimple call)
 static tree
 vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
 {
-  void **slot;
+  vn_reference_s **slot;
   hashval_t hash;
 
   hash = vr->hashcode;
-  slot = htab_find_slot_with_hash (current_info->references, vr,
-                                  hash, NO_INSERT);
+  slot = current_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
   if (!slot && current_info == optimistic_info)
-    slot = htab_find_slot_with_hash (valid_info->references, vr,
-                                    hash, NO_INSERT);
+    slot = valid_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
   if (slot)
     {
       if (vnresult)
@@ -1377,7 +1469,7 @@ vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse,
                       unsigned int cnt, void *vr_)
 {
   vn_reference_t vr = (vn_reference_t)vr_;
-  void **slot;
+  vn_reference_s **slot;
   hashval_t hash;
 
   /* This bounds the stmt walks we perform on reference lookups
@@ -1397,11 +1489,9 @@ vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse,
     vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
 
   hash = vr->hashcode;
-  slot = htab_find_slot_with_hash (current_info->references, vr,
-                                  hash, NO_INSERT);
+  slot = current_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
   if (!slot && current_info == optimistic_info)
-    slot = htab_find_slot_with_hash (valid_info->references, vr,
-                                    hash, NO_INSERT);
+    slot = valid_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
   if (slot)
     return *slot;
 
@@ -2004,7 +2094,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
 vn_reference_t
 vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
 {
-  void **slot;
+  vn_reference_s **slot;
   vn_reference_t vr1;
 
   vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
@@ -2020,8 +2110,8 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
   vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
   vr1->result_vdef = vdef;
 
-  slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
-                                  INSERT);
+  slot = current_info->references.find_slot_with_hash (vr1, vr1->hashcode,
+                                                      INSERT);
 
   /* Because we lookup stores using vuses, and value number failures
      using the vdefs (see visit_reference_op_store for how and why),
@@ -2049,7 +2139,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
                            tree result, unsigned int value_id)
 
 {
-  void **slot;
+  vn_reference_s **slot;
   vn_reference_t vr1;
 
   vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
@@ -2063,8 +2153,8 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
     result = SSA_VAL (result);
   vr1->result = result;
 
-  slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
-                                  INSERT);
+  slot = current_info->references.find_slot_with_hash (vr1, vr1->hashcode,
+                                                      INSERT);
 
   /* At this point we should have all the things inserted that we have
      seen before, and we should never try inserting something that
@@ -2105,23 +2195,12 @@ vn_nary_op_compute_hash (const vn_nary_op_t vno1)
   return hash;
 }
 
-/* Return the computed hashcode for nary operation P1.  */
-
-static hashval_t
-vn_nary_op_hash (const void *p1)
-{
-  const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1;
-  return vno1->hashcode;
-}
-
-/* Compare nary operations P1 and P2 and return true if they are
+/* Compare nary operations VNO1 and VNO2 and return true if they are
    equivalent.  */
 
-int
-vn_nary_op_eq (const void *p1, const void *p2)
+bool
+vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2)
 {
-  const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1;
-  const_vn_nary_op_t const vno2 = (const_vn_nary_op_t) p2;
   unsigned i;
 
   if (vno1->hashcode != vno2->hashcode)
@@ -2238,22 +2317,20 @@ init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple stmt)
 static tree
 vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
 {
-  void **slot;
+  vn_nary_op_s **slot;
 
   if (vnresult)
     *vnresult = NULL;
 
   vno->hashcode = vn_nary_op_compute_hash (vno);
-  slot = htab_find_slot_with_hash (current_info->nary, vno, vno->hashcode,
-                                  NO_INSERT);
+  slot = current_info->nary.find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
   if (!slot && current_info == optimistic_info)
-    slot = htab_find_slot_with_hash (valid_info->nary, vno, vno->hashcode,
-                                    NO_INSERT);
+    slot = valid_info->nary.find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
   if (!slot)
     return NULL_TREE;
   if (vnresult)
-    *vnresult = (vn_nary_op_t)*slot;
-  return ((vn_nary_op_t)*slot)->result;
+    *vnresult = *slot;
+  return (*slot)->result;
 }
 
 /* Lookup a n-ary operation by its pieces and return the resulting value
@@ -2331,14 +2408,15 @@ alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id)
    VNO->HASHCODE first.  */
 
 static vn_nary_op_t
-vn_nary_op_insert_into (vn_nary_op_t vno, htab_t table, bool compute_hash)
+vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type table,
+                       bool compute_hash)
 {
-  void **slot;
+  vn_nary_op_s **slot;
 
   if (compute_hash)
     vno->hashcode = vn_nary_op_compute_hash (vno);
 
-  slot = htab_find_slot_with_hash (table, vno, vno->hashcode, INSERT);
+  slot = table.find_slot_with_hash (vno, vno->hashcode, INSERT);
   gcc_assert (!*slot);
 
   *slot = vno;
@@ -2414,23 +2492,11 @@ vn_phi_compute_hash (vn_phi_t vp1)
   return result;
 }
 
-/* Return the computed hashcode for phi operation P1.  */
-
-static hashval_t
-vn_phi_hash (const void *p1)
-{
-  const_vn_phi_t const vp1 = (const_vn_phi_t) p1;
-  return vp1->hashcode;
-}
-
 /* Compare two phi entries for equality, ignoring VN_TOP arguments.  */
 
 static int
-vn_phi_eq (const void *p1, const void *p2)
+vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
 {
-  const_vn_phi_t const vp1 = (const_vn_phi_t) p1;
-  const_vn_phi_t const vp2 = (const_vn_phi_t) p2;
-
   if (vp1->hashcode != vp2->hashcode)
     return false;
 
@@ -2468,7 +2534,7 @@ static vec<tree> shared_lookup_phiargs;
 static tree
 vn_phi_lookup (gimple phi)
 {
-  void **slot;
+  vn_phi_s **slot;
   struct vn_phi_s vp1;
   unsigned i;
 
@@ -2485,14 +2551,12 @@ vn_phi_lookup (gimple phi)
   vp1.phiargs = shared_lookup_phiargs;
   vp1.block = gimple_bb (phi);
   vp1.hashcode = vn_phi_compute_hash (&vp1);
-  slot = htab_find_slot_with_hash (current_info->phis, &vp1, vp1.hashcode,
-                                  NO_INSERT);
+  slot = current_info->phis.find_slot_with_hash (&vp1, vp1.hashcode, NO_INSERT);
   if (!slot && current_info == optimistic_info)
-    slot = htab_find_slot_with_hash (valid_info->phis, &vp1, vp1.hashcode,
-                                    NO_INSERT);
+    slot = valid_info->phis.find_slot_with_hash (&vp1, vp1.hashcode, NO_INSERT);
   if (!slot)
     return NULL_TREE;
-  return ((vn_phi_t)*slot)->result;
+  return (*slot)->result;
 }
 
 /* Insert PHI into the current hash table with a value number of
@@ -2501,7 +2565,7 @@ vn_phi_lookup (gimple phi)
 static vn_phi_t
 vn_phi_insert (gimple phi, tree result)
 {
-  void **slot;
+  vn_phi_s **slot;
   vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool);
   unsigned i;
   vec<tree> args = vNULL;
@@ -2520,8 +2584,7 @@ vn_phi_insert (gimple phi, tree result)
   vp1->result = result;
   vp1->hashcode = vn_phi_compute_hash (vp1);
 
-  slot = htab_find_slot_with_hash (current_info->phis, vp1, vp1->hashcode,
-                                  INSERT);
+  slot = current_info->phis.find_slot_with_hash (vp1, vp1->hashcode, INSERT);
 
   /* Because we iterate over phi operations more than once, it's
      possible the slot might already exist here, hence no assert.*/
@@ -2724,7 +2787,7 @@ visit_reference_op_call (tree lhs, gimple stmt)
     }
   else
     {
-      void **slot;
+      vn_reference_s **slot;
       vn_reference_t vr2;
       if (vdef)
        changed |= set_ssa_val_to (vdef, vdef);
@@ -2738,8 +2801,8 @@ visit_reference_op_call (tree lhs, gimple stmt)
       vr2->hashcode = vr1.hashcode;
       vr2->result = lhs;
       vr2->result_vdef = vdef;
-      slot = htab_find_slot_with_hash (current_info->references,
-                                      vr2, vr2->hashcode, INSERT);
+      slot = current_info->references.find_slot_with_hash (vr2, vr2->hashcode,
+                                                          INSERT);
       if (*slot)
        free_reference (*slot);
       *slot = vr2;
@@ -3599,10 +3662,10 @@ static void
 copy_phi (vn_phi_t ophi, vn_tables_t info)
 {
   vn_phi_t phi = (vn_phi_t) pool_alloc (info->phis_pool);
-  void **slot;
+  vn_phi_s **slot;
   memcpy (phi, ophi, sizeof (*phi));
   ophi->phiargs.create (0);
-  slot = htab_find_slot_with_hash (info->phis, phi, phi->hashcode, INSERT);
+  slot = info->phis.find_slot_with_hash (phi, phi->hashcode, INSERT);
   gcc_assert (!*slot);
   *slot = phi;
 }
@@ -3613,12 +3676,11 @@ static void
 copy_reference (vn_reference_t oref, vn_tables_t info)
 {
   vn_reference_t ref;
-  void **slot;
+  vn_reference_s **slot;
   ref = (vn_reference_t) pool_alloc (info->references_pool);
   memcpy (ref, oref, sizeof (*ref));
   oref->operands.create (0);
-  slot = htab_find_slot_with_hash (info->references, ref, ref->hashcode,
-                                  INSERT);
+  slot = info->references.find_slot_with_hash (ref, ref->hashcode, INSERT);
   if (*slot)
     free_reference (*slot);
   *slot = ref;
@@ -3633,7 +3695,9 @@ process_scc (vec<tree> scc)
   unsigned int i;
   unsigned int iterations = 0;
   bool changed = true;
-  htab_iterator hi;
+  vn_nary_op_iterator_type hin;
+  vn_phi_iterator_type hip;
+  vn_reference_iterator_type hir;
   vn_nary_op_t nary;
   vn_phi_t phi;
   vn_reference_t ref;
@@ -3670,9 +3734,9 @@ process_scc (vec<tree> scc)
       /* As we are value-numbering optimistically we have to
         clear the expression tables and the simplified expressions
         in each iteration until we converge.  */
-      htab_empty (optimistic_info->nary);
-      htab_empty (optimistic_info->phis);
-      htab_empty (optimistic_info->references);
+      optimistic_info->nary.empty ();
+      optimistic_info->phis.empty ();
+      optimistic_info->references.empty ();
       obstack_free (&optimistic_info->nary_obstack, NULL);
       gcc_obstack_init (&optimistic_info->nary_obstack);
       empty_alloc_pool (optimistic_info->phis_pool);
@@ -3687,11 +3751,12 @@ process_scc (vec<tree> scc)
 
   /* Finally, copy the contents of the no longer used optimistic
      table to the valid table.  */
-  FOR_EACH_HTAB_ELEMENT (optimistic_info->nary, nary, vn_nary_op_t, hi)
+  FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->nary, nary, vn_nary_op_t, hin)
     copy_nary (nary, valid_info);
-  FOR_EACH_HTAB_ELEMENT (optimistic_info->phis, phi, vn_phi_t, hi)
+  FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->phis, phi, vn_phi_t, hip)
     copy_phi (phi, valid_info);
-  FOR_EACH_HTAB_ELEMENT (optimistic_info->references, ref, vn_reference_t, hi)
+  FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->references,
+                              ref, vn_reference_t, hir)
     copy_reference (ref, valid_info);
 
   current_info = valid_info;
@@ -3851,10 +3916,9 @@ continue_walking:
 static void
 allocate_vn_table (vn_tables_t table)
 {
-  table->phis = htab_create (23, vn_phi_hash, vn_phi_eq, free_phi);
-  table->nary = htab_create (23, vn_nary_op_hash, vn_nary_op_eq, NULL);
-  table->references = htab_create (23, vn_reference_hash, vn_reference_eq,
-                                  free_reference);
+  table->phis.create (23);
+  table->nary.create (23);
+  table->references.create (23);
 
   gcc_obstack_init (&table->nary_obstack);
   table->phis_pool = create_alloc_pool ("VN phis",
@@ -3870,9 +3934,9 @@ allocate_vn_table (vn_tables_t table)
 static void
 free_vn_table (vn_tables_t table)
 {
-  htab_delete (table->phis);
-  htab_delete (table->nary);
-  htab_delete (table->references);
+  table->phis.dispose ();
+  table->nary.dispose ();
+  table->references.dispose ();
   obstack_free (&table->nary_obstack, NULL);
   free_alloc_pool (table->phis_pool);
   free_alloc_pool (table->references_pool);
@@ -3887,8 +3951,7 @@ init_scc_vn (void)
 
   calculate_dominance_info (CDI_DOMINATORS);
   sccstack.create (0);
-  constant_to_value_id = htab_create (23, vn_constant_hash, vn_constant_eq,
-                                 free);
+  constant_to_value_id.create (23);
 
   constant_value_ids = BITMAP_ALLOC (NULL);
 
@@ -3944,7 +4007,7 @@ free_scc_vn (void)
 {
   size_t i;
 
-  htab_delete (constant_to_value_id);
+  constant_to_value_id.dispose ();
   BITMAP_FREE (constant_value_ids);
   shared_lookup_phiargs.release ();
   shared_lookup_references.release ();
@@ -3985,7 +4048,9 @@ set_value_id_for_result (tree result, unsigned int *id)
 static void
 set_hashtable_value_ids (void)
 {
-  htab_iterator hi;
+  vn_nary_op_iterator_type hin;
+  vn_phi_iterator_type hip;
+  vn_reference_iterator_type hir;
   vn_nary_op_t vno;
   vn_reference_t vr;
   vn_phi_t vp;
@@ -3993,16 +4058,13 @@ set_hashtable_value_ids (void)
   /* Now set the value ids of the things we had put in the hash
      table.  */
 
-  FOR_EACH_HTAB_ELEMENT (valid_info->nary,
-                        vno, vn_nary_op_t, hi)
+  FOR_EACH_HASH_TABLE_ELEMENT (valid_info->nary, vno, vn_nary_op_t, hin)
     set_value_id_for_result (vno->result, &vno->value_id);
 
-  FOR_EACH_HTAB_ELEMENT (valid_info->phis,
-                        vp, vn_phi_t, hi)
+  FOR_EACH_HASH_TABLE_ELEMENT (valid_info->phis, vp, vn_phi_t, hip)
     set_value_id_for_result (vp->result, &vp->value_id);
 
-  FOR_EACH_HTAB_ELEMENT (valid_info->references,
-                        vr, vn_reference_t, hi)
+  FOR_EACH_HASH_TABLE_ELEMENT (valid_info->references, vr, vn_reference_t, hir)
     set_value_id_for_result (vr->result, &vr->value_id);
 }
 
index 072f7ddf65e48fdafeb5ca9d31bc1f1380aa54e1..94e3603f7406baaef67191dd5a16dbd90b8873f8 100644 (file)
@@ -216,10 +216,11 @@ vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
                                           tree, unsigned int);
 
 hashval_t vn_nary_op_compute_hash (const vn_nary_op_t);
-int vn_nary_op_eq (const void *, const void *);
+bool vn_nary_op_eq (const_vn_nary_op_t const vno1,
+                   const_vn_nary_op_t const vno2);
 bool vn_nary_may_trap (vn_nary_op_t);
 hashval_t vn_reference_compute_hash (const vn_reference_t);
-int vn_reference_eq (const void *, const void *);
+bool vn_reference_eq (const_vn_reference_t const, const_vn_reference_t const);
 unsigned int get_max_value_id (void);
 unsigned int get_next_value_id (void);
 unsigned int get_constant_value_id (tree);
index 37751a74fd5dc65acaccc6137e05fcbc02aa23bb..9eb06f6b09751e47b20065f0ac2694b405cd56f1 100644 (file)
@@ -32,7 +32,7 @@
 #include "tree-inline.h"
 #include "diagnostic-core.h"
 #include "gimple.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "function.h"
 #include "cgraph.h"
 #include "tree-pass.h"
@@ -1862,48 +1862,54 @@ typedef struct equiv_class_label
 } *equiv_class_label_t;
 typedef const struct equiv_class_label *const_equiv_class_label_t;
 
-/* A hashtable for mapping a bitmap of labels->pointer equivalence
-   classes.  */
-static htab_t pointer_equiv_class_table;
+/* Equiv_class_label hashtable helpers.  */
 
-/* A hashtable for mapping a bitmap of labels->location equivalence
-   classes.  */
-static htab_t location_equiv_class_table;
+struct equiv_class_hasher : typed_free_remove <equiv_class_label>
+{
+  typedef equiv_class_label value_type;
+  typedef equiv_class_label compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
 
 /* Hash function for a equiv_class_label_t */
 
-static hashval_t
-equiv_class_label_hash (const void *p)
+inline hashval_t
+equiv_class_hasher::hash (const value_type *ecl)
 {
-  const_equiv_class_label_t const ecl = (const_equiv_class_label_t) p;
   return ecl->hashcode;
 }
 
 /* Equality function for two equiv_class_label_t's.  */
 
-static int
-equiv_class_label_eq (const void *p1, const void *p2)
+inline bool
+equiv_class_hasher::equal (const value_type *eql1, const compare_type *eql2)
 {
-  const_equiv_class_label_t const eql1 = (const_equiv_class_label_t) p1;
-  const_equiv_class_label_t const eql2 = (const_equiv_class_label_t) p2;
   return (eql1->hashcode == eql2->hashcode
          && bitmap_equal_p (eql1->labels, eql2->labels));
 }
 
+/* A hashtable for mapping a bitmap of labels->pointer equivalence
+   classes.  */
+static hash_table <equiv_class_hasher> pointer_equiv_class_table;
+
+/* A hashtable for mapping a bitmap of labels->location equivalence
+   classes.  */
+static hash_table <equiv_class_hasher> location_equiv_class_table;
+
 /* Lookup a equivalence class in TABLE by the bitmap of LABELS with
    hash HAS it contains.  Sets *REF_LABELS to the bitmap LABELS
    is equivalent to.  */
 
 static equiv_class_label *
-equiv_class_lookup_or_add (htab_t table, bitmap labels)
+equiv_class_lookup_or_add (hash_table <equiv_class_hasher> table, bitmap labels)
 {
   equiv_class_label **slot;
   equiv_class_label ecl;
 
   ecl.labels = labels;
   ecl.hashcode = bitmap_hash (labels);
-  slot = (equiv_class_label **) htab_find_slot_with_hash (table, &ecl,
-                                                         ecl.hashcode, INSERT);
+  slot = table.find_slot_with_hash (&ecl, ecl.hashcode, INSERT);
   if (!*slot)
     {
       *slot = XNEW (struct equiv_class_label);
@@ -2222,10 +2228,8 @@ perform_var_substitution (constraint_graph_t graph)
   struct scc_info *si = init_scc_info (size);
 
   bitmap_obstack_initialize (&iteration_obstack);
-  pointer_equiv_class_table = htab_create (511, equiv_class_label_hash,
-                                          equiv_class_label_eq, free);
-  location_equiv_class_table = htab_create (511, equiv_class_label_hash,
-                                           equiv_class_label_eq, free);
+  pointer_equiv_class_table.create (511);
+  location_equiv_class_table.create (511);
   pointer_equiv_class = 1;
   location_equiv_class = 1;
 
@@ -2358,8 +2362,8 @@ free_var_substitution_info (struct scc_info *si)
   free (graph->points_to);
   free (graph->eq_rep);
   sbitmap_free (graph->direct_nodes);
-  htab_delete (pointer_equiv_class_table);
-  htab_delete (location_equiv_class_table);
+  pointer_equiv_class_table.dispose ();
+  location_equiv_class_table.dispose ();
   bitmap_obstack_release (&iteration_obstack);
 }
 
@@ -5900,45 +5904,54 @@ typedef struct shared_bitmap_info
 } *shared_bitmap_info_t;
 typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
 
-static htab_t shared_bitmap_table;
+/* Shared_bitmap hashtable helpers.  */
+
+struct shared_bitmap_hasher : typed_free_remove <shared_bitmap_info>
+{
+  typedef shared_bitmap_info value_type;
+  typedef shared_bitmap_info compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
 
 /* Hash function for a shared_bitmap_info_t */
 
-static hashval_t
-shared_bitmap_hash (const void *p)
+inline hashval_t
+shared_bitmap_hasher::hash (const value_type *bi)
 {
-  const_shared_bitmap_info_t const bi = (const_shared_bitmap_info_t) p;
   return bi->hashcode;
 }
 
 /* Equality function for two shared_bitmap_info_t's. */
 
-static int
-shared_bitmap_eq (const void *p1, const void *p2)
+inline bool
+shared_bitmap_hasher::equal (const value_type *sbi1, const compare_type *sbi2)
 {
-  const_shared_bitmap_info_t const sbi1 = (const_shared_bitmap_info_t) p1;
-  const_shared_bitmap_info_t const sbi2 = (const_shared_bitmap_info_t) p2;
   return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
 }
 
+/* Shared_bitmap hashtable.  */
+
+static hash_table <shared_bitmap_hasher> shared_bitmap_table;
+
 /* Lookup a bitmap in the shared bitmap hashtable, and return an already
    existing instance if there is one, NULL otherwise.  */
 
 static bitmap
 shared_bitmap_lookup (bitmap pt_vars)
 {
-  void **slot;
+  shared_bitmap_info **slot;
   struct shared_bitmap_info sbi;
 
   sbi.pt_vars = pt_vars;
   sbi.hashcode = bitmap_hash (pt_vars);
 
-  slot = htab_find_slot_with_hash (shared_bitmap_table, &sbi,
-                                  sbi.hashcode, NO_INSERT);
+  slot = shared_bitmap_table.find_slot_with_hash (&sbi, sbi.hashcode,
+                                                 NO_INSERT);
   if (!slot)
     return NULL;
   else
-    return ((shared_bitmap_info_t) *slot)->pt_vars;
+    return (*slot)->pt_vars;
 }
 
 
@@ -5947,16 +5960,15 @@ shared_bitmap_lookup (bitmap pt_vars)
 static void
 shared_bitmap_add (bitmap pt_vars)
 {
-  void **slot;
+  shared_bitmap_info **slot;
   shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
 
   sbi->pt_vars = pt_vars;
   sbi->hashcode = bitmap_hash (pt_vars);
 
-  slot = htab_find_slot_with_hash (shared_bitmap_table, sbi,
-                                  sbi->hashcode, INSERT);
+  slot = shared_bitmap_table.find_slot_with_hash (sbi, sbi->hashcode, INSERT);
   gcc_assert (!*slot);
-  *slot = (void *) sbi;
+  *slot = sbi;
 }
 
 
@@ -6612,8 +6624,7 @@ init_alias_vars (void)
   call_stmt_vars = pointer_map_create ();
 
   memset (&stats, 0, sizeof (stats));
-  shared_bitmap_table = htab_create (511, shared_bitmap_hash,
-                                    shared_bitmap_eq, free);
+  shared_bitmap_table.create (511);
   init_base_vars ();
 
   gcc_obstack_init (&fake_var_decl_obstack);
@@ -6869,7 +6880,7 @@ delete_points_to_sets (void)
 {
   unsigned int i;
 
-  htab_delete (shared_bitmap_table);
+  shared_bitmap_table.dispose ();
   if (dump_file && (dump_flags & TDF_STATS))
     fprintf (dump_file, "Points to sets created:%d\n",
             stats.points_to_sets_created);
index 9cbc5c72cf6bf34f7f9b1c3bce452e4403dd5c91..c1b5826ee1274cb90bd10afd3e71822bc86e544e 100644 (file)
@@ -1062,27 +1062,6 @@ vect_get_data_access_cost (struct data_reference *dr,
 }
 
 
-static hashval_t
-vect_peeling_hash (const void *elem)
-{
-  const struct _vect_peel_info *peel_info;
-
-  peel_info = (const struct _vect_peel_info *) elem;
-  return (hashval_t) peel_info->npeel;
-}
-
-
-static int
-vect_peeling_hash_eq (const void *elem1, const void *elem2)
-{
-  const struct _vect_peel_info *a, *b;
-
-  a = (const struct _vect_peel_info *) elem1;
-  b = (const struct _vect_peel_info *) elem2;
-  return (a->npeel == b->npeel);
-}
-
-
 /* Insert DR into peeling hash table with NPEEL as key.  */
 
 static void
@@ -1090,12 +1069,11 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
                           int npeel)
 {
   struct _vect_peel_info elem, *slot;
-  void **new_slot;
+  _vect_peel_info **new_slot;
   bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
 
   elem.npeel = npeel;
-  slot = (vect_peel_info) htab_find (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
-                                     &elem);
+  slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo).find (&elem);
   if (slot)
     slot->count++;
   else
@@ -1104,8 +1082,7 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
       slot->npeel = npeel;
       slot->dr = dr;
       slot->count = 1;
-      new_slot = htab_find_slot (LOOP_VINFO_PEELING_HTAB (loop_vinfo), slot,
-                                 INSERT);
+      new_slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo).find_slot (slot, INSERT);
       *new_slot = slot;
     }
 
@@ -1117,11 +1094,11 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
 /* Traverse peeling hash table to find peeling option that aligns maximum
    number of data accesses.  */
 
-static int
-vect_peeling_hash_get_most_frequent (void **slot, void *data)
+int
+vect_peeling_hash_get_most_frequent (_vect_peel_info **slot,
+                                    _vect_peel_extended_info *max)
 {
-  vect_peel_info elem = (vect_peel_info) *slot;
-  vect_peel_extended_info max = (vect_peel_extended_info) data;
+  vect_peel_info elem = *slot;
 
   if (elem->count > max->peel_info.count
       || (elem->count == max->peel_info.count
@@ -1139,11 +1116,11 @@ vect_peeling_hash_get_most_frequent (void **slot, void *data)
 /* Traverse peeling hash table and calculate cost for each peeling option.
    Find the one with the lowest cost.  */
 
-static int
-vect_peeling_hash_get_lowest_cost (void **slot, void *data)
+int
+vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot,
+                                  _vect_peel_extended_info *min)
 {
-  vect_peel_info elem = (vect_peel_info) *slot;
-  vect_peel_extended_info min = (vect_peel_extended_info) data;
+  vect_peel_info elem = *slot;
   int save_misalignment, dummy;
   unsigned int inside_cost = 0, outside_cost = 0, i;
   gimple stmt = DR_STMT (elem->dr);
@@ -1223,14 +1200,16 @@ vect_peeling_hash_choose_best_peeling (loop_vec_info loop_vinfo,
      {
        res.inside_cost = INT_MAX;
        res.outside_cost = INT_MAX;
-       htab_traverse (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
-                      vect_peeling_hash_get_lowest_cost, &res);
+       LOOP_VINFO_PEELING_HTAB (loop_vinfo)
+           .traverse <_vect_peel_extended_info *,
+                      vect_peeling_hash_get_lowest_cost> (&res);
      }
    else
      {
        res.peel_info.count = 0;
-       htab_traverse (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
-                      vect_peeling_hash_get_most_frequent, &res);
+       LOOP_VINFO_PEELING_HTAB (loop_vinfo)
+           .traverse <_vect_peel_extended_info *,
+                      vect_peeling_hash_get_most_frequent> (&res);
      }
 
    *npeel = res.peel_info.npeel;
@@ -1423,10 +1402,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
                                                    size_zero_node) < 0;
 
               /* Save info about DR in the hash table.  */
-              if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo))
-                LOOP_VINFO_PEELING_HTAB (loop_vinfo) =
-                           htab_create (1, vect_peeling_hash,
-                                        vect_peeling_hash_eq, free);
+              if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo).is_created ())
+                LOOP_VINFO_PEELING_HTAB (loop_vinfo).create (1);
 
               vectype = STMT_VINFO_VECTYPE (stmt_info);
               nelements = TYPE_VECTOR_SUBPARTS (vectype);
index a684c9ff5b6b3ca3576f29c16524bf0409514070..40eccea550072964654c2cf69764ebba4ff7d3e4 100644 (file)
@@ -879,7 +879,6 @@ new_loop_vec_info (struct loop *loop)
   LOOP_VINFO_REDUCTION_CHAINS (res).create (10);
   LOOP_VINFO_SLP_INSTANCES (res).create (10);
   LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
-  LOOP_VINFO_PEELING_HTAB (res) = NULL;
   LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
   LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
   LOOP_VINFO_OPERANDS_SWAPPED (res) = false;
@@ -960,8 +959,8 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
   LOOP_VINFO_REDUCTIONS (loop_vinfo).release ();
   LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).release ();
 
-  if (LOOP_VINFO_PEELING_HTAB (loop_vinfo))
-    htab_delete (LOOP_VINFO_PEELING_HTAB (loop_vinfo));
+  if (LOOP_VINFO_PEELING_HTAB (loop_vinfo).is_created ())
+    LOOP_VINFO_PEELING_HTAB (loop_vinfo).dispose ();
 
   destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));
 
index 2f0374d760c9a8cafc94ebd7ae243fdb58175f29..85c885654c0dba1d0ea3d8a9dd38040e3db53798 100644 (file)
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "tree-data-ref.h"
 #include "target.h"
+#include "hash-table.h"
 
 typedef source_location LOC;
 #define UNKNOWN_LOC UNKNOWN_LOCATION
@@ -189,6 +190,30 @@ typedef struct _vect_peel_extended_info
   stmt_vector_for_cost body_cost_vec;
 } *vect_peel_extended_info;
 
+
+/* Peeling hashtable helpers.  */
+
+struct peel_info_hasher : typed_free_remove <_vect_peel_info>
+{
+  typedef _vect_peel_info value_type;
+  typedef _vect_peel_info compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+peel_info_hasher::hash (const value_type *peel_info)
+{
+  return (hashval_t) peel_info->npeel;
+}
+
+inline bool
+peel_info_hasher::equal (const value_type *a, const compare_type *b)
+{
+  return (a->npeel == b->npeel);
+}
+
+
 /*-----------------------------------------------------------------*/
 /* Info on vectorized loops.                                       */
 /*-----------------------------------------------------------------*/
@@ -273,7 +298,7 @@ typedef struct _loop_vec_info {
   vec<gimple> reduction_chains;
 
   /* Hash table used to choose the best peeling option.  */
-  htab_t peeling_htab;
+  hash_table <peel_info_hasher> peeling_htab;
 
   /* Cost data used by the target cost model.  */
   void *target_cost_data;