summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLawrence Crowl <crowl@google.com>2013-04-23 22:00:12 +0000
committerLawrence Crowl <crowl@gcc.gnu.org>2013-04-23 22:00:12 +0000
commitbf190e8df270025e2d0729858c031eb4ef7d49d2 (patch)
treefd9e547e6ac26ffd9c7200538fb2582c9ab2c3dc
parent4a8043c4e02c8c2517424722ba3055a159b93e87 (diff)
This patch extracts approved portions of the hash_table patches to the...
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
-rw-r--r--gcc/ChangeLog49
-rw-r--r--gcc/Makefile.in13
-rw-r--r--gcc/hash-table.h207
-rw-r--r--gcc/statistics.c105
-rw-r--r--gcc/tree-into-ssa.c94
-rw-r--r--gcc/tree-ssa-coalesce.c130
-rw-r--r--gcc/tree-ssa-loop-im.c62
-rw-r--r--gcc/tree-ssa-reassoc.c30
-rw-r--r--gcc/tree-ssa-sccvn.c428
-rw-r--r--gcc/tree-ssa-sccvn.h5
-rw-r--r--gcc/tree-ssa-structalias.c95
-rw-r--r--gcc/tree-vect-data-refs.c61
-rw-r--r--gcc/tree-vect-loop.c5
-rw-r--r--gcc/tree-vectorizer.h27
14 files changed, 806 insertions, 505 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f55df95ed8a..f280abea5d4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index e265730ec93..84d96d29a1e 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -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) \
diff --git a/gcc/hash-table.h b/gcc/hash-table.h
index 206423dc58b..00637789923 100644
--- a/gcc/hash-table.h
+++ b/gcc/hash-table.h
@@ -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 */
diff --git a/gcc/statistics.c b/gcc/statistics.c
index 3b9685d01d0..3077cc0c36c 100644
--- a/gcc/statistics.c
+++ b/gcc/statistics.c
@@ -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);
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 65c15daca4c..f028b25b19a 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -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
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index fd9c2cbdb33..354b5f182a8 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -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;
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 188af0012a7..90e4d361e2f 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -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);
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 0089dc515de..4fc19cb551e 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -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);
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index e7aefbf0551..07bfdcccb81 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -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);
}
diff --git a/gcc/tree-ssa-sccvn.h b/gcc/tree-ssa-sccvn.h
index 072f7ddf65e..94e3603f740 100644
--- a/gcc/tree-ssa-sccvn.h
+++ b/gcc/tree-ssa-sccvn.h
@@ -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);
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 37751a74fd5..9eb06f6b097 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -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);
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 9cbc5c72cf6..c1b5826ee12 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -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);
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index a684c9ff5b6..40eccea5500 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -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));
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 2f0374d760c..85c885654c0 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -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;