diff options
author | Lawrence Crowl <crowl@google.com> | 2013-04-23 22:00:12 +0000 |
---|---|---|
committer | Lawrence Crowl <crowl@gcc.gnu.org> | 2013-04-23 22:00:12 +0000 |
commit | bf190e8df270025e2d0729858c031eb4ef7d49d2 (patch) | |
tree | fd9e547e6ac26ffd9c7200538fb2582c9ab2c3dc | |
parent | 4a8043c4e02c8c2517424722ba3055a159b93e87 (diff) | |
download | gcc-bf190e8df270025e2d0729858c031eb4ef7d49d2.zip gcc-bf190e8df270025e2d0729858c031eb4ef7d49d2.tar.gz gcc-bf190e8df270025e2d0729858c031eb4ef7d49d2.tar.bz2 |
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/ChangeLog | 49 | ||||
-rw-r--r-- | gcc/Makefile.in | 13 | ||||
-rw-r--r-- | gcc/hash-table.h | 207 | ||||
-rw-r--r-- | gcc/statistics.c | 105 | ||||
-rw-r--r-- | gcc/tree-into-ssa.c | 94 | ||||
-rw-r--r-- | gcc/tree-ssa-coalesce.c | 130 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-im.c | 62 | ||||
-rw-r--r-- | gcc/tree-ssa-reassoc.c | 30 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 428 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.h | 5 | ||||
-rw-r--r-- | gcc/tree-ssa-structalias.c | 95 | ||||
-rw-r--r-- | gcc/tree-vect-data-refs.c | 61 | ||||
-rw-r--r-- | gcc/tree-vect-loop.c | 5 | ||||
-rw-r--r-- | gcc/tree-vectorizer.h | 27 |
14 files changed, 806 insertions, 505 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f55df95..f280abe 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 e265730..84d96d2 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 206423d..0063778 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 3b9685d..3077cc0 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 65c15da..f028b25 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 fd9c2cb..354b5f1 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 188af00..90e4d36 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 0089dc5..4fc19cb 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 e7aefbf..07bfdccc 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 072f7dd..94e3603 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 37751a7..9eb06f6 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 9cbc5c7..c1b5826 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 a684c9f..40eccea 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 2f0374d..85c8856 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; |