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
This commit is contained in:
Lawrence Crowl 2013-04-23 22:00:12 +00:00 committed by Lawrence Crowl
parent 4a8043c4e0
commit bf190e8df2
14 changed files with 806 additions and 505 deletions

View File

@ -1,3 +1,52 @@
2013-04-23 Lawrence Crowl <crowl@google.com>
* Makefile.in: Update as needed below.
* hash-table.h (class hash_table):
Correct many methods with parameter types compare_type to the correct
value_type. (Correct code was unlikely to notice the change.)
(hash_table::elements_with_deleted) New.
(class hashtable::iterator): New.
(hashtable::begin()): New.
(hashtable::end()): New.
(FOR_EACH_HASH_TABLE_ELEMENT): New.
* statistics.c (statistics_hashes):
Change type to hash_table. Update dependent calls and types.
* tree-into-ssa.c (var_infos):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-coalesce.c (struct coalesce_list_d.list):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-loop-im.c (struct mem_ref.refs):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-reassoc.c (undistribute_ops_list::ctable):
Change type to hash_table. Update dependent calls and types.
* tree-ssa-sccvn.c (vn_tables_s::nary):
Change type to hash_table. Update dependent calls and types.
(vn_tables_s::phis): Likewise.
(vn_tables_s::references): Likewise.
* tree-ssa-sccvn.h (vn_nary_op_eq): Update parameter and return types.
(vn_reference_eq): Update parameter and return types.
* tree-ssa-structalias.c (pointer_equiv_class_table):
Change type to hash_table. Update dependent calls and types.
(location_equiv_class_table): Likewise.
* tree-vect-data-refs.c: Consequential changes for making
peeling a hash_table.
* tree-vect-loop.c (new_loop_vec_info): Dependent hash_table update.
(destroy_loop_vec_info): Dependent hash_table update.
* tree-vectorizer.h (peeling_htab):
Change type to hash_table. Update dependent calls and types.
2013-04-23 Shiva Chen <shiva0217@gmail.com>
* lra-assigns.c (find_hard_regno_for): Use lra_reg_val_equal_p

View File

@ -966,7 +966,8 @@ GIMPLE_STREAMER_H = gimple-streamer.h $(LTO_STREAMER_H) $(BASIC_BLOCK_H) \
TREE_STREAMER_H = tree-streamer.h $(TREE_H) $(LTO_STREAMER_H) \
$(STREAMER_HOOKS_H)
STREAMER_HOOKS_H = streamer-hooks.h $(TREE_H)
TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) $(TARGET_H)
TREE_VECTORIZER_H = tree-vectorizer.h $(TREE_DATA_REF_H) $(TARGET_H) \
$(HASH_TABLE_H)
IPA_PROP_H = ipa-prop.h $(TREE_H) $(VEC_H) $(CGRAPH_H) $(GIMPLE_H) alloc-pool.h
IPA_INLINE_H = ipa-inline.h $(IPA_PROP_H)
GSTAB_H = gstab.h stab.def
@ -2255,7 +2256,7 @@ tree-ssa-structalias.o: tree-ssa-structalias.c \
$(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(GGC_H) $(OBSTACK_H) $(BITMAP_H) \
$(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(DIAGNOSTIC_H) $(TREE_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \
$(GIMPLE_H) $(HASHTAB_H) $(FUNCTION_H) $(CGRAPH_H) \
$(GIMPLE_H) $(HASH_TABLE_H) $(FUNCTION_H) $(CGRAPH_H) \
$(TREE_PASS_H) alloc-pool.h $(SPLAY_TREE_H) $(PARAMS_H) \
$(CGRAPH_H) $(ALIAS_H) pointer-set.h
tree-ssa-uninit.o : tree-ssa-uninit.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
@ -2275,7 +2276,7 @@ tree-into-ssa.o : tree-into-ssa.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(DIAGNOSTIC_CORE_H) \
$(FUNCTION_H) $(TM_H) coretypes.h \
langhooks.h domwalk.h $(TREE_PASS_H) $(PARAMS_H) $(BASIC_BLOCK_H) \
$(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASHTAB_H) \
$(BITMAP_H) $(CFGLOOP_H) $(FLAGS_H) $(HASH_TABLE_H) \
$(GIMPLE_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
tree-ssa-ter.o : tree-ssa-ter.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(DIAGNOSTIC_H) $(TM_H) coretypes.h $(DUMPFILE_H) \
@ -2374,7 +2375,7 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_FLOW_H) $(CONFIG_H) \
tree-ssa-sccvn.o : tree-ssa-sccvn.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \
$(TM_H) coretypes.h $(DUMPFILE_H) $(FLAGS_H) $(CFGLOOP_H) \
alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASHTAB_H) $(GIMPLE_H) \
alloc-pool.h $(BASIC_BLOCK_H) $(BITMAP_H) $(HASH_TABLE_H) $(GIMPLE_H) \
$(TREE_INLINE_H) tree-ssa-propagate.h tree-ssa-sccvn.h \
$(PARAMS_H) $(GIMPLE_PRETTY_PRINT_H) gimple-fold.h
gimple-ssa-strength-reduction.o : gimple-ssa-strength-reduction.c $(CONFIG_H) \
@ -2509,7 +2510,7 @@ tree-ssa-alias.o : tree-ssa-alias.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
pointer-set.h alloc-pool.h \
$(TREE_PRETTY_PRINT_H)
tree-ssa-reassoc.o : tree-ssa-reassoc.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \
$(SYSTEM_H) $(HASH_TABLE_H) $(TREE_H) $(DIAGNOSTIC_H) \
$(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) \
tree-iterator.h $(BASIC_BLOCK_H) $(GIMPLE_H) $(TREE_INLINE_H) \
$(VEC_H) langhooks.h alloc-pool.h pointer-set.h $(CFGLOOP_H) \
@ -2765,7 +2766,7 @@ function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_
$(TREE_PASS_H) $(DF_H) $(PARAMS_H) bb-reorder.h \
$(COMMON_TARGET_H)
statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TREE_PASS_H) $(TREE_DUMP_H) $(HASHTAB_H) statistics.h $(FUNCTION_H)
$(TREE_PASS_H) $(TREE_DUMP_H) $(HASH_TABLE_H) statistics.h $(FUNCTION_H)
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) $(TM_H) \
$(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \

View File

@ -155,6 +155,47 @@ along with GCC; see the file COPYING3. If not see
hash_table <pointer_hash <whatever_type>> whatever_type_hash_table;
HASH TABLE ITERATORS
The hash table provides standard C++ iterators. For example, consider a
hash table of some_info. We wish to consume each element of the table:
extern void consume (some_info *);
We define a convenience typedef and the hash table:
typedef hash_table <some_info_hasher> info_table_type;
info_table_type info_table;
Then we write the loop in typical C++ style:
for (info_table_type::iterator iter = info_table.begin ();
iter != info_table.end ();
++iter)
if ((*iter).status == INFO_READY)
consume (&*iter);
Or with common sub-expression elimination:
for (info_table_type::iterator iter = info_table.begin ();
iter != info_table.end ();
++iter)
{
some_info &elem = *iter;
if (elem.status == INFO_READY)
consume (&elem);
}
One can also use a more typical GCC style:
typedef some_info *some_info_p;
some_info *elem_ptr;
info_table_type::iterator iter;
FOR_EACH_HASH_TABLE_ELEMENT (info_table, elem_ptr, some_info_p, iter)
if (elem_ptr->status == INFO_READY)
consume (elem_ptr);
*/
@ -368,6 +409,20 @@ public:
typedef typename Descriptor::value_type value_type;
typedef typename Descriptor::compare_type compare_type;
class iterator
{
public:
inline iterator ();
inline iterator (value_type **, value_type **);
inline value_type &operator * ();
void slide ();
inline iterator &operator ++ ();
inline bool operator != (const iterator &) const;
private:
value_type **slot_;
value_type **limit_;
};
private:
hash_table_control <value_type> *htab;
@ -379,19 +434,19 @@ public:
void create (size_t initial_slots);
bool is_created ();
void dispose ();
value_type *find (const compare_type *comparable);
value_type *find (const value_type *value);
value_type *find_with_hash (const compare_type *comparable, hashval_t hash);
value_type **find_slot (const compare_type *comparable,
enum insert_option insert);
value_type **find_slot (const value_type *value, enum insert_option insert);
value_type **find_slot_with_hash (const compare_type *comparable,
hashval_t hash, enum insert_option insert);
void empty ();
void clear_slot (value_type **slot);
void remove_elt (const compare_type *comparable);
void remove_elt (const value_type *value);
void remove_elt_with_hash (const compare_type *comparable, hashval_t hash);
size_t size();
size_t elements();
double collisions();
size_t size ();
size_t elements ();
size_t elements_with_deleted ();
double collisions ();
template <typename Argument,
int (*Callback) (value_type **slot, Argument argument)>
@ -400,6 +455,9 @@ public:
template <typename Argument,
int (*Callback) (value_type **slot, Argument argument)>
void traverse (Argument argument);
iterator begin();
iterator end();
};
@ -430,9 +488,9 @@ hash_table <Descriptor, Allocator>::is_created ()
template <typename Descriptor,
template <typename Type> class Allocator>
inline typename Descriptor::value_type *
hash_table <Descriptor, Allocator>::find (const compare_type *comparable)
hash_table <Descriptor, Allocator>::find (const value_type *value)
{
return find_with_hash (comparable, Descriptor::hash (comparable));
return find_with_hash (value, Descriptor::hash (value));
}
@ -442,9 +500,9 @@ template <typename Descriptor,
template <typename Type> class Allocator>
inline typename Descriptor::value_type **
hash_table <Descriptor, Allocator>
::find_slot (const compare_type *comparable, enum insert_option insert)
::find_slot (const value_type *value, enum insert_option insert)
{
return find_slot_with_hash (comparable, Descriptor::hash (comparable), insert);
return find_slot_with_hash (value, Descriptor::hash (value), insert);
}
@ -453,9 +511,9 @@ hash_table <Descriptor, Allocator>
template <typename Descriptor,
template <typename Type> class Allocator>
inline void
hash_table <Descriptor, Allocator>::remove_elt (const compare_type *comparable)
hash_table <Descriptor, Allocator>::remove_elt (const value_type *value)
{
remove_elt_with_hash (comparable, Descriptor::hash (comparable));
remove_elt_with_hash (value, Descriptor::hash (value));
}
@ -475,12 +533,23 @@ hash_table <Descriptor, Allocator>::size()
template <typename Descriptor,
template <typename Type> class Allocator>
inline size_t
hash_table <Descriptor, Allocator>::elements()
hash_table <Descriptor, Allocator>::elements ()
{
return htab->n_elements - htab->n_deleted;
}
/* Return the current number of elements in this hash table. */
template <typename Descriptor,
template <typename Type> class Allocator>
inline size_t
hash_table <Descriptor, Allocator>::elements_with_deleted ()
{
return htab->n_elements;
}
/* Return the fraction of fixed collisions during all work with given
hash table. */
@ -881,4 +950,114 @@ hash_table <Descriptor, Allocator>::traverse (Argument argument)
traverse_noresize <Argument, Callback> (argument);
}
/* Iterator definitions. */
/* The default constructor produces the end value. */
template <typename Descriptor,
template <typename Type> class Allocator>
inline
hash_table <Descriptor, Allocator>::iterator::iterator ()
: slot_ (NULL), limit_ (NULL)
{
}
/* The parameterized constructor produces the begin value. */
template <typename Descriptor,
template <typename Type> class Allocator>
inline
hash_table <Descriptor, Allocator>::iterator::iterator
(value_type **slot, value_type **limit)
: slot_ (slot), limit_ (limit)
{
}
/* Obtain the element. */
template <typename Descriptor,
template <typename Type> class Allocator>
inline typename hash_table <Descriptor, Allocator>::value_type &
hash_table <Descriptor, Allocator>::iterator::operator * ()
{
return **slot_;
}
/* Slide down the iterator slots until an active entry is found. */
template <typename Descriptor,
template <typename Type> class Allocator>
void
hash_table <Descriptor, Allocator>::iterator::slide ()
{
for ( ; slot_ < limit_; ++slot_ )
{
value_type *x = *slot_;
if (x != HTAB_EMPTY_ENTRY && x != HTAB_DELETED_ENTRY)
return;
}
slot_ = NULL;
limit_ = NULL;
}
/* Bump the iterator. */
template <typename Descriptor,
template <typename Type> class Allocator>
inline typename hash_table <Descriptor, Allocator>::iterator &
hash_table <Descriptor, Allocator>::iterator::operator ++ ()
{
++slot_;
slide ();
return *this;
}
/* Compare iterators. */
template <typename Descriptor,
template <typename Type> class Allocator>
inline bool
hash_table <Descriptor, Allocator>::iterator::
operator != (const iterator &other) const
{
return slot_ != other.slot_ || limit_ != other.limit_;
}
/* Hash table iterator producers. */
/* The beginning of a hash table iteration. */
template <typename Descriptor,
template <typename Type> class Allocator>
inline typename hash_table <Descriptor, Allocator>::iterator
hash_table <Descriptor, Allocator>::begin ()
{
iterator hti (htab->entries, htab->entries + htab->size);
hti.slide ();
return hti;
}
/* The end of a hash table iteration. */
template <typename Descriptor,
template <typename Type> class Allocator>
inline typename hash_table <Descriptor, Allocator>::iterator
hash_table <Descriptor, Allocator>::end ()
{
return iterator ();
}
/* Iterate through the elements of hash_table HTAB,
using hash_table <....>::iterator ITER,
storing each element in RESULT, which is of type TYPE.
This macro has this form for compatibility with the
FOR_EACH_HTAB_ELEMENT currently defined in tree-flow.h. */
#define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
for ((ITER) = (HTAB).begin (); \
(ITER) != (HTAB).end () ? (RESULT = &*(ITER) , true) : false; \
++(ITER))
#endif /* TYPED_HASHTAB_H */

View File

@ -24,7 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pass.h"
#include "tree-dump.h"
#include "statistics.h"
#include "hashtab.h"
#include "hash-table.h"
#include "function.h"
static int statistics_dump_nr;
@ -42,42 +42,52 @@ typedef struct statistics_counter_s {
unsigned HOST_WIDE_INT prev_dumped_count;
} statistics_counter_t;
/* Array of statistic hashes, indexed by pass id. */
static htab_t *statistics_hashes;
static unsigned nr_statistics_hashes;
/* Hashtable helpers. */
struct stats_counter_hasher
{
typedef statistics_counter_t value_type;
typedef statistics_counter_t compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
static inline void remove (value_type *);
};
/* Hash a statistic counter by its string ID. */
static hashval_t
hash_statistics_hash (const void *p)
inline hashval_t
stats_counter_hasher::hash (const value_type *c)
{
const statistics_counter_t *const c = (const statistics_counter_t *)p;
return htab_hash_string (c->id) + c->val;
}
/* Compare two statistic counters by their string IDs. */
static int
hash_statistics_eq (const void *p, const void *q)
inline bool
stats_counter_hasher::equal (const value_type *c1, const compare_type *c2)
{
const statistics_counter_t *const c1 = (const statistics_counter_t *)p;
const statistics_counter_t *const c2 = (const statistics_counter_t *)q;
return c1->val == c2->val && strcmp (c1->id, c2->id) == 0;
}
/* Free a statistics entry. */
static void
hash_statistics_free (void *p)
inline void
stats_counter_hasher::remove (value_type *v)
{
free (CONST_CAST(char *, ((statistics_counter_t *)p)->id));
free (p);
free (CONST_CAST(char *, v->id));
free (v);
}
typedef hash_table <stats_counter_hasher> stats_counter_table_type;
/* Array of statistic hashes, indexed by pass id. */
static stats_counter_table_type *statistics_hashes;
static unsigned nr_statistics_hashes;
/* Return the current hashtable to be used for recording or printing
statistics. */
static htab_t
static stats_counter_table_type
curr_statistics_hash (void)
{
unsigned idx;
@ -86,20 +96,20 @@ curr_statistics_hash (void)
idx = current_pass->static_pass_number;
if (idx < nr_statistics_hashes
&& statistics_hashes[idx] != NULL)
&& statistics_hashes[idx].is_created ())
return statistics_hashes[idx];
if (idx >= nr_statistics_hashes)
{
statistics_hashes = XRESIZEVEC (struct htab *, statistics_hashes, idx+1);
statistics_hashes = XRESIZEVEC (stats_counter_table_type,
statistics_hashes, idx+1);
memset (statistics_hashes + nr_statistics_hashes, 0,
(idx + 1 - nr_statistics_hashes) * sizeof (htab_t));
(idx + 1 - nr_statistics_hashes)
* sizeof (stats_counter_table_type));
nr_statistics_hashes = idx + 1;
}
statistics_hashes[idx] = htab_create (15, hash_statistics_hash,
hash_statistics_eq,
hash_statistics_free);
statistics_hashes[idx].create (15);
return statistics_hashes[idx];
}
@ -107,10 +117,11 @@ curr_statistics_hash (void)
/* Helper for statistics_fini_pass. Print the counter difference
since the last dump for the pass dump files. */
static int
statistics_fini_pass_1 (void **slot, void *data ATTRIBUTE_UNUSED)
int
statistics_fini_pass_1 (statistics_counter_t **slot,
void *data ATTRIBUTE_UNUSED)
{
statistics_counter_t *counter = (statistics_counter_t *)*slot;
statistics_counter_t *counter = *slot;
unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
if (count == 0)
return 1;
@ -127,10 +138,11 @@ statistics_fini_pass_1 (void **slot, void *data ATTRIBUTE_UNUSED)
/* Helper for statistics_fini_pass. Print the counter difference
since the last dump for the statistics dump. */
static int
statistics_fini_pass_2 (void **slot, void *data ATTRIBUTE_UNUSED)
int
statistics_fini_pass_2 (statistics_counter_t **slot,
void *data ATTRIBUTE_UNUSED)
{
statistics_counter_t *counter = (statistics_counter_t *)*slot;
statistics_counter_t *counter = *slot;
unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
if (count == 0)
return 1;
@ -157,10 +169,11 @@ statistics_fini_pass_2 (void **slot, void *data ATTRIBUTE_UNUSED)
/* Helper for statistics_fini_pass, reset the counters. */
static int
statistics_fini_pass_3 (void **slot, void *data ATTRIBUTE_UNUSED)
int
statistics_fini_pass_3 (statistics_counter_t **slot,
void *data ATTRIBUTE_UNUSED)
{
statistics_counter_t *counter = (statistics_counter_t *)*slot;
statistics_counter_t *counter = *slot;
counter->prev_dumped_count = counter->count;
return 1;
}
@ -179,26 +192,25 @@ statistics_fini_pass (void)
fprintf (dump_file, "\n");
fprintf (dump_file, "Pass statistics:\n");
fprintf (dump_file, "----------------\n");
htab_traverse_noresize (curr_statistics_hash (),
statistics_fini_pass_1, NULL);
curr_statistics_hash ()
.traverse_noresize <void *, statistics_fini_pass_1> (NULL);
fprintf (dump_file, "\n");
}
if (statistics_dump_file
&& !(statistics_dump_flags & TDF_STATS
|| statistics_dump_flags & TDF_DETAILS))
htab_traverse_noresize (curr_statistics_hash (),
statistics_fini_pass_2, NULL);
htab_traverse_noresize (curr_statistics_hash (),
statistics_fini_pass_3, NULL);
curr_statistics_hash ()
.traverse_noresize <void *, statistics_fini_pass_2> (NULL);
curr_statistics_hash ()
.traverse_noresize <void *, statistics_fini_pass_3> (NULL);
}
/* Helper for printing summary information. */
static int
statistics_fini_1 (void **slot, void *data)
int
statistics_fini_1 (statistics_counter_t **slot, opt_pass *pass)
{
struct opt_pass *pass = (struct opt_pass *)data;
statistics_counter_t *counter = (statistics_counter_t *)*slot;
statistics_counter_t *counter = *slot;
if (counter->count == 0)
return 1;
if (counter->histogram_p)
@ -230,10 +242,11 @@ statistics_fini (void)
{
unsigned i;
for (i = 0; i < nr_statistics_hashes; ++i)
if (statistics_hashes[i] != NULL
if (statistics_hashes[i].is_created ()
&& get_pass_for_id (i) != NULL)
htab_traverse_noresize (statistics_hashes[i],
statistics_fini_1, get_pass_for_id (i));
statistics_hashes[i]
.traverse_noresize <opt_pass *, statistics_fini_1>
(get_pass_for_id (i));
}
dump_end (statistics_dump_nr, statistics_dump_file);
@ -261,14 +274,14 @@ statistics_init (void)
and HISTOGRAM_P. */
static statistics_counter_t *
lookup_or_add_counter (htab_t hash, const char *id, int val,
lookup_or_add_counter (stats_counter_table_type hash, const char *id, int val,
bool histogram_p)
{
statistics_counter_t **counter;
statistics_counter_t c;
c.id = id;
c.val = val;
counter = (statistics_counter_t **) htab_find_slot (hash, &c, INSERT);
counter = hash.find_slot (&c, INSERT);
if (!*counter)
{
*counter = XNEW (struct statistics_counter_s);

View File

@ -33,7 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "gimple.h"
#include "tree-inline.h"
#include "hashtab.h"
#include "hash-table.h"
#include "tree-pass.h"
#include "cfgloop.h"
#include "domwalk.h"
@ -160,9 +160,32 @@ struct var_info_d
typedef struct var_info_d *var_info_p;
/* VAR_INFOS hashtable helpers. */
struct var_info_hasher : typed_free_remove <var_info_d>
{
typedef var_info_d value_type;
typedef var_info_d compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
inline hashval_t
var_info_hasher::hash (const value_type *p)
{
return DECL_UID (p->var);
}
inline bool
var_info_hasher::equal (const value_type *p1, const compare_type *p2)
{
return p1->var == p2->var;
}
/* Each entry in VAR_INFOS contains an element of type STRUCT
VAR_INFO_D. */
static htab_t var_infos;
static hash_table <var_info_hasher> var_infos;
/* Information stored for SSA names. */
@ -340,17 +363,17 @@ static inline var_info_p
get_var_info (tree decl)
{
struct var_info_d vi;
void **slot;
var_info_d **slot;
vi.var = decl;
slot = htab_find_slot_with_hash (var_infos, &vi, DECL_UID (decl), INSERT);
slot = var_infos.find_slot_with_hash (&vi, DECL_UID (decl), INSERT);
if (*slot == NULL)
{
var_info_p v = XCNEW (struct var_info_d);
v->var = decl;
*slot = (void *)v;
*slot = v;
return v;
}
return (var_info_p) *slot;
return *slot;
}
@ -1044,15 +1067,15 @@ insert_phi_nodes_compare_var_infos (const void *a, const void *b)
static void
insert_phi_nodes (bitmap_head *dfs)
{
htab_iterator hi;
hash_table <var_info_hasher>::iterator hi;
unsigned i;
var_info_p info;
vec<var_info_p> vars;
timevar_push (TV_TREE_INSERT_PHI_NODES);
vars.create (htab_elements (var_infos));
FOR_EACH_HTAB_ELEMENT (var_infos, info, var_info_p, hi)
vars.create (var_infos.elements ());
FOR_EACH_HASH_TABLE_ELEMENT (var_infos, info, var_info_p, hi)
if (info->info.need_phi_state != NEED_PHI_STATE_NO)
vars.quick_push (info);
@ -1632,12 +1655,12 @@ debug_tree_ssa (void)
/* Dump statistics for the hash table HTAB. */
static void
htab_statistics (FILE *file, htab_t htab)
htab_statistics (FILE *file, hash_table <var_info_hasher> htab)
{
fprintf (file, "size %ld, %ld elements, %f collision/search ratio\n",
(long) htab_size (htab),
(long) htab_elements (htab),
htab_collisions (htab));
(long) htab.size (),
(long) htab.elements (),
htab.collisions ());
}
@ -1646,7 +1669,7 @@ htab_statistics (FILE *file, htab_t htab)
void
dump_tree_ssa_stats (FILE *file)
{
if (var_infos)
if (var_infos.is_created ())
{
fprintf (file, "\nHash table statistics:\n");
fprintf (file, " var_infos: ");
@ -1665,29 +1688,12 @@ debug_tree_ssa_stats (void)
}
/* Hashing and equality functions for VAR_INFOS. */
static hashval_t
var_info_hash (const void *p)
{
return DECL_UID (((const struct var_info_d *)p)->var);
}
static int
var_info_eq (const void *p1, const void *p2)
{
return ((const struct var_info_d *)p1)->var
== ((const struct var_info_d *)p2)->var;
}
/* Callback for htab_traverse to dump the VAR_INFOS hash table. */
static int
debug_var_infos_r (void **slot, void *data)
int
debug_var_infos_r (var_info_d **slot, FILE *file)
{
FILE *file = (FILE *) data;
struct var_info_d *info = (struct var_info_d *) *slot;
struct var_info_d *info = *slot;
fprintf (file, "VAR: ");
print_generic_expr (file, info->var, dump_flags);
@ -1708,8 +1714,8 @@ void
dump_var_infos (FILE *file)
{
fprintf (file, "\n\nDefinition and live-in blocks:\n\n");
if (var_infos)
htab_traverse (var_infos, debug_var_infos_r, file);
if (var_infos.is_created ())
var_infos.traverse <FILE *, debug_var_infos_r> (file);
}
@ -2216,7 +2222,7 @@ rewrite_blocks (basic_block entry, enum rewrite_mode what)
if (dump_file && (dump_flags & TDF_STATS))
{
dump_dfa_stats (dump_file);
if (var_infos)
if (var_infos.is_created ())
dump_tree_ssa_stats (dump_file);
}
@ -2296,9 +2302,8 @@ init_ssa_renamer (void)
cfun->gimple_df->in_ssa_p = false;
/* Allocate memory for the DEF_BLOCKS hash table. */
gcc_assert (var_infos == NULL);
var_infos = htab_create (vec_safe_length (cfun->local_decls),
var_info_hash, var_info_eq, free);
gcc_assert (!var_infos.is_created ());
var_infos.create (vec_safe_length (cfun->local_decls));
bitmap_obstack_initialize (&update_ssa_obstack);
}
@ -2309,11 +2314,8 @@ init_ssa_renamer (void)
static void
fini_ssa_renamer (void)
{
if (var_infos)
{
htab_delete (var_infos);
var_infos = NULL;
}
if (var_infos.is_created ())
var_infos.dispose ();
bitmap_obstack_release (&update_ssa_obstack);
@ -3189,7 +3191,7 @@ update_ssa (unsigned update_flags)
{
/* If we rename bare symbols initialize the mapping to
auxiliar info we need to keep track of. */
var_infos = htab_create (47, var_info_hash, var_info_eq, free);
var_infos.create (47);
/* If we have to rename some symbols from scratch, we need to
start the process at the root of the CFG. FIXME, it should

View File

@ -49,6 +49,41 @@ typedef struct coalesce_pair
} * coalesce_pair_p;
typedef const struct coalesce_pair *const_coalesce_pair_p;
/* Coalesce pair hashtable helpers. */
struct coalesce_pair_hasher : typed_noop_remove <coalesce_pair>
{
typedef coalesce_pair value_type;
typedef coalesce_pair compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
/* Hash function for coalesce list. Calculate hash for PAIR. */
inline hashval_t
coalesce_pair_hasher::hash (const value_type *pair)
{
hashval_t a = (hashval_t)(pair->first_element);
hashval_t b = (hashval_t)(pair->second_element);
return b * (b - 1) / 2 + a;
}
/* Equality function for coalesce list hash table. Compare PAIR1 and PAIR2,
returning TRUE if the two pairs are equivalent. */
inline bool
coalesce_pair_hasher::equal (const value_type *p1, const compare_type *p2)
{
return (p1->first_element == p2->first_element
&& p1->second_element == p2->second_element);
}
typedef hash_table <coalesce_pair_hasher> coalesce_table_type;
typedef coalesce_table_type::iterator coalesce_iterator_type;
typedef struct cost_one_pair_d
{
int first_element;
@ -60,7 +95,7 @@ typedef struct cost_one_pair_d
typedef struct coalesce_list_d
{
htab_t list; /* Hash table. */
coalesce_table_type list; /* Hash table. */
coalesce_pair_p *sorted; /* List when sorted. */
int num_sorted; /* Number in the sorted list. */
cost_one_pair_p cost_one_list;/* Single use coalesces with cost 1. */
@ -185,34 +220,6 @@ pop_best_coalesce (coalesce_list_p cl, int *p1, int *p2)
}
#define COALESCE_HASH_FN(R1, R2) ((R2) * ((R2) - 1) / 2 + (R1))
/* Hash function for coalesce list. Calculate hash for PAIR. */
static unsigned int
coalesce_pair_map_hash (const void *pair)
{
hashval_t a = (hashval_t)(((const_coalesce_pair_p)pair)->first_element);
hashval_t b = (hashval_t)(((const_coalesce_pair_p)pair)->second_element);
return COALESCE_HASH_FN (a,b);
}
/* Equality function for coalesce list hash table. Compare PAIR1 and PAIR2,
returning TRUE if the two pairs are equivalent. */
static int
coalesce_pair_map_eq (const void *pair1, const void *pair2)
{
const_coalesce_pair_p const p1 = (const_coalesce_pair_p) pair1;
const_coalesce_pair_p const p2 = (const_coalesce_pair_p) pair2;
return (p1->first_element == p2->first_element
&& p1->second_element == p2->second_element);
}
/* Create a new empty coalesce list object and return it. */
static inline coalesce_list_p
@ -225,8 +232,7 @@ create_coalesce_list (void)
size = 40;
list = (coalesce_list_p) xmalloc (sizeof (struct coalesce_list_d));
list->list = htab_create (size, coalesce_pair_map_hash,
coalesce_pair_map_eq, NULL);
list->list.create (size);
list->sorted = NULL;
list->num_sorted = 0;
list->cost_one_list = NULL;
@ -240,7 +246,7 @@ static inline void
delete_coalesce_list (coalesce_list_p cl)
{
gcc_assert (cl->cost_one_list == NULL);
htab_delete (cl->list);
cl->list.dispose ();
free (cl->sorted);
gcc_assert (cl->num_sorted == 0);
free (cl);
@ -255,7 +261,7 @@ static coalesce_pair_p
find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
{
struct coalesce_pair p;
void **slot;
coalesce_pair **slot;
unsigned int hash;
/* Normalize so that p1 is the smaller value. */
@ -270,9 +276,8 @@ find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
p.second_element = p2;
}
hash = coalesce_pair_map_hash (&p);
slot = htab_find_slot_with_hash (cl->list, &p, hash,
create ? INSERT : NO_INSERT);
hash = coalesce_pair_hasher::hash (&p);
slot = cl->list.find_slot_with_hash (&p, hash, create ? INSERT : NO_INSERT);
if (!slot)
return NULL;
@ -283,7 +288,7 @@ find_coalesce_pair (coalesce_list_p cl, int p1, int p2, bool create)
pair->first_element = p.first_element;
pair->second_element = p.second_element;
pair->cost = 0;
*slot = (void *)pair;
*slot = pair;
}
return (struct coalesce_pair *) *slot;
@ -355,56 +360,14 @@ compare_pairs (const void *p1, const void *p2)
static inline int
num_coalesce_pairs (coalesce_list_p cl)
{
return htab_elements (cl->list);
}
/* Iterator over hash table pairs. */
typedef struct
{
htab_iterator hti;
} coalesce_pair_iterator;
/* Return first partition pair from list CL, initializing iterator ITER. */
static inline coalesce_pair_p
first_coalesce_pair (coalesce_list_p cl, coalesce_pair_iterator *iter)
{
coalesce_pair_p pair;
pair = (coalesce_pair_p) first_htab_element (&(iter->hti), cl->list);
return pair;
}
/* Return TRUE if there are no more partitions in for ITER to process. */
static inline bool
end_coalesce_pair_p (coalesce_pair_iterator *iter)
{
return end_htab_p (&(iter->hti));
}
/* Return the next partition pair to be visited by ITER. */
static inline coalesce_pair_p
next_coalesce_pair (coalesce_pair_iterator *iter)
{
coalesce_pair_p pair;
pair = (coalesce_pair_p) next_htab_element (&(iter->hti));
return pair;
return cl->list.elements ();
}
/* Iterate over CL using ITER, returning values in PAIR. */
#define FOR_EACH_PARTITION_PAIR(PAIR, ITER, CL) \
for ((PAIR) = first_coalesce_pair ((CL), &(ITER)); \
!end_coalesce_pair_p (&(ITER)); \
(PAIR) = next_coalesce_pair (&(ITER)))
FOR_EACH_HASH_TABLE_ELEMENT ((CL)->list, (PAIR), coalesce_pair_p, (ITER))
/* Prepare CL for removal of preferred pairs. When finished they are sorted
@ -415,7 +378,7 @@ sort_coalesce_list (coalesce_list_p cl)
{
unsigned x, num;
coalesce_pair_p p;
coalesce_pair_iterator ppi;
coalesce_iterator_type ppi;
gcc_assert (cl->sorted == NULL);
@ -461,7 +424,8 @@ static void
dump_coalesce_list (FILE *f, coalesce_list_p cl)
{
coalesce_pair_p node;
coalesce_pair_iterator ppi;
coalesce_iterator_type ppi;
int x;
tree var;

View File

@ -31,7 +31,7 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "tree-pass.h"
#include "flags.h"
#include "hashtab.h"
#include "hash-table.h"
#include "tree-affine.h"
#include "pointer-set.h"
#include "tree-ssa-propagate.h"
@ -133,6 +133,32 @@ typedef struct mem_ref
and its subloops. */
#define LOOP_DEP_BIT(loopnum, storedp) (2 * (loopnum) + (storedp ? 1 : 0))
/* Mem_ref hashtable helpers. */
struct mem_ref_hasher : typed_noop_remove <mem_ref>
{
typedef mem_ref value_type;
typedef tree_node compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
/* A hash function for struct mem_ref object OBJ. */
inline hashval_t
mem_ref_hasher::hash (const value_type *mem)
{
return mem->hash;
}
/* An equality function for struct mem_ref object MEM1 with
memory reference OBJ2. */
inline bool
mem_ref_hasher::equal (const value_type *mem1, const compare_type *obj2)
{
return operand_equal_p (mem1->mem.ref, (const_tree) obj2, 0);
}
/* Description of memory accesses in loops. */
@ -140,7 +166,7 @@ typedef struct mem_ref
static struct
{
/* The hash table of memory references accessed in loops. */
htab_t refs;
hash_table <mem_ref_hasher> refs;
/* The list of memory references. */
vec<mem_ref_p> refs_list;
@ -646,7 +672,7 @@ mem_ref_in_stmt (gimple stmt)
gcc_assert (!store);
hash = iterative_hash_expr (*mem, 0);
ref = (mem_ref_p) htab_find_with_hash (memory_accesses.refs, *mem, hash);
ref = memory_accesses.refs.find_with_hash (*mem, hash);
gcc_assert (ref != NULL);
return ref;
@ -1411,27 +1437,6 @@ force_move_till (tree ref, tree *index, void *data)
return true;
}
/* A hash function for struct mem_ref object OBJ. */
static hashval_t
memref_hash (const void *obj)
{
const struct mem_ref *const mem = (const struct mem_ref *) obj;
return mem->hash;
}
/* An equality function for struct mem_ref object OBJ1 with
memory reference OBJ2. */
static int
memref_eq (const void *obj1, const void *obj2)
{
const struct mem_ref *const mem1 = (const struct mem_ref *) obj1;
return operand_equal_p (mem1->mem.ref, (const_tree) obj2, 0);
}
/* A function to free the mem_ref object OBJ. */
static void
@ -1502,7 +1507,7 @@ gather_mem_refs_stmt (struct loop *loop, gimple stmt)
{
tree *mem = NULL;
hashval_t hash;
PTR *slot;
mem_ref **slot;
mem_ref_p ref;
bool is_stored;
unsigned id;
@ -1526,8 +1531,7 @@ gather_mem_refs_stmt (struct loop *loop, gimple stmt)
else
{
hash = iterative_hash_expr (*mem, 0);
slot = htab_find_slot_with_hash (memory_accesses.refs,
*mem, hash, INSERT);
slot = memory_accesses.refs.find_slot_with_hash (*mem, hash, INSERT);
if (*slot)
{
ref = (mem_ref_p) *slot;
@ -2553,7 +2557,7 @@ tree_ssa_lim_initialize (void)
alloc_aux_for_edges (0);
memory_accesses.refs = htab_create (100, memref_hash, memref_eq, NULL);
memory_accesses.refs.create (100);
memory_accesses.refs_list.create (100);
/* Allocate a special, unanalyzable mem-ref with ID zero. */
memory_accesses.refs_list.quick_push
@ -2596,7 +2600,7 @@ tree_ssa_lim_finalize (void)
bitmap_obstack_release (&lim_bitmap_obstack);
pointer_map_destroy (lim_aux_data_map);
htab_delete (memory_accesses.refs);
memory_accesses.refs.dispose ();
FOR_EACH_VEC_ELT (memory_accesses.refs_list, i, ref)
memref_free (ref);

View File

@ -21,6 +21,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "hash-table.h"
#include "tm.h"
#include "tree.h"
#include "basic-block.h"
@ -943,10 +944,23 @@ typedef struct oecount_s {
/* The heap for the oecount hashtable and the sorted list of operands. */
static vec<oecount> cvec;
/* Oecount hashtable helpers. */
struct oecount_hasher : typed_noop_remove <void>
{
/* Note that this hash table stores integers, not pointers.
So, observe the casting in the member functions. */
typedef void value_type;
typedef void compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
/* Hash function for oecount. */
static hashval_t
oecount_hash (const void *p)
inline hashval_t
oecount_hasher::hash (const value_type *p)
{
const oecount *c = &cvec[(size_t)p - 42];
return htab_hash_pointer (c->op) ^ (hashval_t)c->oecode;
@ -954,8 +968,8 @@ oecount_hash (const void *p)
/* Comparison function for oecount. */
static int
oecount_eq (const void *p1, const void *p2)
inline bool
oecount_hasher::equal (const value_type *p1, const compare_type *p2)
{
const oecount *c1 = &cvec[(size_t)p1 - 42];
const oecount *c2 = &cvec[(size_t)p2 - 42];
@ -1257,7 +1271,7 @@ undistribute_ops_list (enum tree_code opcode,
unsigned nr_candidates, nr_candidates2;
sbitmap_iterator sbi0;
vec<operand_entry_t> *subops;
htab_t ctable;
hash_table <oecount_hasher> ctable;
bool changed = false;
int next_oecount_id = 0;
@ -1305,7 +1319,7 @@ undistribute_ops_list (enum tree_code opcode,
/* Build linearized sub-operand lists and the counting table. */
cvec.create (0);
ctable = htab_create (15, oecount_hash, oecount_eq, NULL);
ctable.create (15);
/* ??? Macro arguments cannot have multi-argument template types in
them. This typedef is needed to workaround that limitation. */
typedef vec<operand_entry_t> vec_operand_entry_t_heap;
@ -1332,7 +1346,7 @@ undistribute_ops_list (enum tree_code opcode,
c.op = oe1->op;
cvec.safe_push (c);
idx = cvec.length () + 41;
slot = htab_find_slot (ctable, (void *)idx, INSERT);
slot = ctable.find_slot ((void *)idx, INSERT);
if (!*slot)
{
*slot = (void *)idx;
@ -1344,7 +1358,7 @@ undistribute_ops_list (enum tree_code opcode,
}
}
}
htab_delete (ctable);
ctable.dispose ();
/* Sort the counting table. */
cvec.qsort (oecount_cmp);

View File

@ -29,7 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "gimple.h"
#include "dumpfile.h"
#include "hashtab.h"
#include "hash-table.h"
#include "alloc-pool.h"
#include "flags.h"
#include "bitmap.h"
@ -96,19 +96,187 @@ along with GCC; see the file COPYING3. If not see
structure copies.
*/
/* vn_nary_op hashtable helpers. */
struct vn_nary_op_hasher : typed_noop_remove <vn_nary_op_s>
{
typedef vn_nary_op_s value_type;
typedef vn_nary_op_s compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
/* Return the computed hashcode for nary operation P1. */
inline hashval_t
vn_nary_op_hasher::hash (const value_type *vno1)
{
return vno1->hashcode;
}
/* Compare nary operations P1 and P2 and return true if they are
equivalent. */
inline bool
vn_nary_op_hasher::equal (const value_type *vno1, const compare_type *vno2)
{
return vn_nary_op_eq (vno1, vno2);
}
typedef hash_table <vn_nary_op_hasher> vn_nary_op_table_type;
typedef vn_nary_op_table_type::iterator vn_nary_op_iterator_type;
/* vn_phi hashtable helpers. */
static int
vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2);
struct vn_phi_hasher
{
typedef vn_phi_s value_type;
typedef vn_phi_s compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
static inline void remove (value_type *);
};
/* Return the computed hashcode for phi operation P1. */
inline hashval_t
vn_phi_hasher::hash (const value_type *vp1)
{
return vp1->hashcode;
}
/* Compare two phi entries for equality, ignoring VN_TOP arguments. */
inline bool
vn_phi_hasher::equal (const value_type *vp1, const compare_type *vp2)
{
return vn_phi_eq (vp1, vp2);
}
/* Free a phi operation structure VP. */
inline void
vn_phi_hasher::remove (value_type *phi)
{
phi->phiargs.release ();
}
typedef hash_table <vn_phi_hasher> vn_phi_table_type;
typedef vn_phi_table_type::iterator vn_phi_iterator_type;
/* Compare two reference operands P1 and P2 for equality. Return true if
they are equal, and false otherwise. */
static int
vn_reference_op_eq (const void *p1, const void *p2)
{
const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
return (vro1->opcode == vro2->opcode
/* We do not care for differences in type qualification. */
&& (vro1->type == vro2->type
|| (vro1->type && vro2->type
&& types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
TYPE_MAIN_VARIANT (vro2->type))))
&& expressions_equal_p (vro1->op0, vro2->op0)
&& expressions_equal_p (vro1->op1, vro2->op1)
&& expressions_equal_p (vro1->op2, vro2->op2));
}
/* Free a reference operation structure VP. */
static inline void
free_reference (vn_reference_s *vr)
{
vr->operands.release ();
}
/* vn_reference hashtable helpers. */
struct vn_reference_hasher
{
typedef vn_reference_s value_type;
typedef vn_reference_s compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
static inline void remove (value_type *);
};
/* Return the hashcode for a given reference operation P1. */
inline hashval_t
vn_reference_hasher::hash (const value_type *vr1)
{
return vr1->hashcode;
}
inline bool
vn_reference_hasher::equal (const value_type *v, const compare_type *c)
{
return vn_reference_eq (v, c);
}
inline void
vn_reference_hasher::remove (value_type *v)
{
free_reference (v);
}
typedef hash_table <vn_reference_hasher> vn_reference_table_type;
typedef vn_reference_table_type::iterator vn_reference_iterator_type;
/* The set of hashtables and alloc_pool's for their items. */
typedef struct vn_tables_s
{
htab_t nary;
htab_t phis;
htab_t references;
vn_nary_op_table_type nary;
vn_phi_table_type phis;
vn_reference_table_type references;
struct obstack nary_obstack;
alloc_pool phis_pool;
alloc_pool references_pool;
} *vn_tables_t;
static htab_t constant_to_value_id;
/* vn_constant hashtable helpers. */
struct vn_constant_hasher : typed_free_remove <vn_constant_s>
{
typedef vn_constant_s value_type;
typedef vn_constant_s compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
/* Hash table hash function for vn_constant_t. */
inline hashval_t
vn_constant_hasher::hash (const value_type *vc1)
{
return vc1->hashcode;
}
/* Hash table equality function for vn_constant_t. */
inline bool
vn_constant_hasher::equal (const value_type *vc1, const compare_type *vc2)
{
if (vc1->hashcode != vc2->hashcode)
return false;
return vn_constant_eq_with_type (vc1->constant, vc2->constant);
}
static hash_table <vn_constant_hasher> constant_to_value_id;
static bitmap constant_value_ids;
@ -338,62 +506,20 @@ vn_get_stmt_kind (gimple stmt)
}
}
/* Free a phi operation structure VP. */
static void
free_phi (void *vp)
{
vn_phi_t phi = (vn_phi_t) vp;
phi->phiargs.release ();
}
/* Free a reference operation structure VP. */
static void
free_reference (void *vp)
{
vn_reference_t vr = (vn_reference_t) vp;
vr->operands.release ();
}
/* Hash table equality function for vn_constant_t. */
static int
vn_constant_eq (const void *p1, const void *p2)
{
const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
const struct vn_constant_s *vc2 = (const struct vn_constant_s *) p2;
if (vc1->hashcode != vc2->hashcode)
return false;
return vn_constant_eq_with_type (vc1->constant, vc2->constant);
}
/* Hash table hash function for vn_constant_t. */
static hashval_t
vn_constant_hash (const void *p1)
{
const struct vn_constant_s *vc1 = (const struct vn_constant_s *) p1;
return vc1->hashcode;
}
/* Lookup a value id for CONSTANT and return it. If it does not
exist returns 0. */
unsigned int
get_constant_value_id (tree constant)
{
void **slot;
vn_constant_s **slot;
struct vn_constant_s vc;
vc.hashcode = vn_hash_constant_with_type (constant);
vc.constant = constant;
slot = htab_find_slot_with_hash (constant_to_value_id, &vc,
vc.hashcode, NO_INSERT);
slot = constant_to_value_id.find_slot_with_hash (&vc, vc.hashcode, NO_INSERT);
if (slot)
return ((vn_constant_t)*slot)->value_id;
return (*slot)->value_id;
return 0;
}
@ -403,22 +529,21 @@ get_constant_value_id (tree constant)
unsigned int
get_or_alloc_constant_value_id (tree constant)
{
void **slot;
vn_constant_s **slot;
struct vn_constant_s vc;
vn_constant_t vcp;
vc.hashcode = vn_hash_constant_with_type (constant);
vc.constant = constant;
slot = htab_find_slot_with_hash (constant_to_value_id, &vc,
vc.hashcode, INSERT);
slot = constant_to_value_id.find_slot_with_hash (&vc, vc.hashcode, INSERT);
if (*slot)
return ((vn_constant_t)*slot)->value_id;
return (*slot)->value_id;
vcp = XNEW (struct vn_constant_s);
vcp->hashcode = vc.hashcode;
vcp->constant = constant;
vcp->value_id = get_next_value_id ();
*slot = (void *) vcp;
*slot = vcp;
bitmap_set_bit (constant_value_ids, vcp->value_id);
return vcp->value_id;
}
@ -431,26 +556,6 @@ value_id_constant_p (unsigned int v)
return bitmap_bit_p (constant_value_ids, v);
}
/* Compare two reference operands P1 and P2 for equality. Return true if
they are equal, and false otherwise. */
static int
vn_reference_op_eq (const void *p1, const void *p2)
{
const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
return (vro1->opcode == vro2->opcode
/* We do not care for differences in type qualification. */
&& (vro1->type == vro2->type
|| (vro1->type && vro2->type
&& types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
TYPE_MAIN_VARIANT (vro2->type))))
&& expressions_equal_p (vro1->op0, vro2->op0)
&& expressions_equal_p (vro1->op1, vro2->op1)
&& expressions_equal_p (vro1->op2, vro2->op2));
}
/* Compute the hash for a reference operand VRO1. */
static hashval_t
@ -466,15 +571,6 @@ vn_reference_op_compute_hash (const vn_reference_op_t vro1, hashval_t result)
return result;
}
/* Return the hashcode for a given reference operation P1. */
static hashval_t
vn_reference_hash (const void *p1)
{
const_vn_reference_t const vr1 = (const_vn_reference_t) p1;
return vr1->hashcode;
}
/* Compute a hash for the reference operation VR1 and return it. */
hashval_t
@ -524,16 +620,14 @@ vn_reference_compute_hash (const vn_reference_t vr1)
return result;
}
/* Return true if reference operations P1 and P2 are equivalent. This
/* Return true if reference operations VR1 and VR2 are equivalent. This
means they have the same set of operands and vuses. */
int
vn_reference_eq (const void *p1, const void *p2)
bool
vn_reference_eq (const_vn_reference_t const vr1, const_vn_reference_t const vr2)
{
unsigned i, j;
const_vn_reference_t const vr1 = (const_vn_reference_t) p1;
const_vn_reference_t const vr2 = (const_vn_reference_t) p2;
if (vr1->hashcode != vr2->hashcode)
return false;
@ -1346,15 +1440,13 @@ valueize_shared_reference_ops_from_call (gimple call)
static tree
vn_reference_lookup_1 (vn_reference_t vr, vn_reference_t *vnresult)
{
void **slot;
vn_reference_s **slot;
hashval_t hash;
hash = vr->hashcode;
slot = htab_find_slot_with_hash (current_info->references, vr,
hash, NO_INSERT);
slot = current_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
if (!slot && current_info == optimistic_info)
slot = htab_find_slot_with_hash (valid_info->references, vr,
hash, NO_INSERT);
slot = valid_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
if (slot)
{
if (vnresult)
@ -1377,7 +1469,7 @@ vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse,
unsigned int cnt, void *vr_)
{
vn_reference_t vr = (vn_reference_t)vr_;
void **slot;
vn_reference_s **slot;
hashval_t hash;
/* This bounds the stmt walks we perform on reference lookups
@ -1397,11 +1489,9 @@ vn_reference_lookup_2 (ao_ref *op ATTRIBUTE_UNUSED, tree vuse,
vr->hashcode = vr->hashcode + SSA_NAME_VERSION (vr->vuse);
hash = vr->hashcode;
slot = htab_find_slot_with_hash (current_info->references, vr,
hash, NO_INSERT);
slot = current_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
if (!slot && current_info == optimistic_info)
slot = htab_find_slot_with_hash (valid_info->references, vr,
hash, NO_INSERT);
slot = valid_info->references.find_slot_with_hash (vr, hash, NO_INSERT);
if (slot)
return *slot;
@ -2004,7 +2094,7 @@ vn_reference_lookup (tree op, tree vuse, vn_lookup_kind kind,
vn_reference_t
vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
{
void **slot;
vn_reference_s **slot;
vn_reference_t vr1;
vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
@ -2020,8 +2110,8 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef)
vr1->result = TREE_CODE (result) == SSA_NAME ? SSA_VAL (result) : result;
vr1->result_vdef = vdef;
slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
INSERT);
slot = current_info->references.find_slot_with_hash (vr1, vr1->hashcode,
INSERT);
/* Because we lookup stores using vuses, and value number failures
using the vdefs (see visit_reference_op_store for how and why),
@ -2049,7 +2139,7 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
tree result, unsigned int value_id)
{
void **slot;
vn_reference_s **slot;
vn_reference_t vr1;
vr1 = (vn_reference_t) pool_alloc (current_info->references_pool);
@ -2063,8 +2153,8 @@ vn_reference_insert_pieces (tree vuse, alias_set_type set, tree type,
result = SSA_VAL (result);
vr1->result = result;
slot = htab_find_slot_with_hash (current_info->references, vr1, vr1->hashcode,
INSERT);
slot = current_info->references.find_slot_with_hash (vr1, vr1->hashcode,
INSERT);
/* At this point we should have all the things inserted that we have
seen before, and we should never try inserting something that
@ -2105,23 +2195,12 @@ vn_nary_op_compute_hash (const vn_nary_op_t vno1)
return hash;
}
/* Return the computed hashcode for nary operation P1. */
static hashval_t
vn_nary_op_hash (const void *p1)
{
const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1;
return vno1->hashcode;
}
/* Compare nary operations P1 and P2 and return true if they are
/* Compare nary operations VNO1 and VNO2 and return true if they are
equivalent. */
int
vn_nary_op_eq (const void *p1, const void *p2)
bool
vn_nary_op_eq (const_vn_nary_op_t const vno1, const_vn_nary_op_t const vno2)
{
const_vn_nary_op_t const vno1 = (const_vn_nary_op_t) p1;
const_vn_nary_op_t const vno2 = (const_vn_nary_op_t) p2;
unsigned i;
if (vno1->hashcode != vno2->hashcode)
@ -2238,22 +2317,20 @@ init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple stmt)
static tree
vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
{
void **slot;
vn_nary_op_s **slot;
if (vnresult)
*vnresult = NULL;
vno->hashcode = vn_nary_op_compute_hash (vno);
slot = htab_find_slot_with_hash (current_info->nary, vno, vno->hashcode,
NO_INSERT);
slot = current_info->nary.find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
if (!slot && current_info == optimistic_info)
slot = htab_find_slot_with_hash (valid_info->nary, vno, vno->hashcode,
NO_INSERT);
slot = valid_info->nary.find_slot_with_hash (vno, vno->hashcode, NO_INSERT);
if (!slot)
return NULL_TREE;
if (vnresult)
*vnresult = (vn_nary_op_t)*slot;
return ((vn_nary_op_t)*slot)->result;
*vnresult = *slot;
return (*slot)->result;
}
/* Lookup a n-ary operation by its pieces and return the resulting value
@ -2331,14 +2408,15 @@ alloc_vn_nary_op (unsigned int length, tree result, unsigned int value_id)
VNO->HASHCODE first. */
static vn_nary_op_t
vn_nary_op_insert_into (vn_nary_op_t vno, htab_t table, bool compute_hash)
vn_nary_op_insert_into (vn_nary_op_t vno, vn_nary_op_table_type table,
bool compute_hash)
{
void **slot;
vn_nary_op_s **slot;
if (compute_hash)
vno->hashcode = vn_nary_op_compute_hash (vno);
slot = htab_find_slot_with_hash (table, vno, vno->hashcode, INSERT);
slot = table.find_slot_with_hash (vno, vno->hashcode, INSERT);
gcc_assert (!*slot);
*slot = vno;
@ -2414,23 +2492,11 @@ vn_phi_compute_hash (vn_phi_t vp1)
return result;
}
/* Return the computed hashcode for phi operation P1. */
static hashval_t
vn_phi_hash (const void *p1)
{
const_vn_phi_t const vp1 = (const_vn_phi_t) p1;
return vp1->hashcode;
}
/* Compare two phi entries for equality, ignoring VN_TOP arguments. */
static int
vn_phi_eq (const void *p1, const void *p2)
vn_phi_eq (const_vn_phi_t const vp1, const_vn_phi_t const vp2)
{
const_vn_phi_t const vp1 = (const_vn_phi_t) p1;
const_vn_phi_t const vp2 = (const_vn_phi_t) p2;
if (vp1->hashcode != vp2->hashcode)
return false;
@ -2468,7 +2534,7 @@ static vec<tree> shared_lookup_phiargs;
static tree
vn_phi_lookup (gimple phi)
{
void **slot;
vn_phi_s **slot;
struct vn_phi_s vp1;
unsigned i;
@ -2485,14 +2551,12 @@ vn_phi_lookup (gimple phi)
vp1.phiargs = shared_lookup_phiargs;
vp1.block = gimple_bb (phi);
vp1.hashcode = vn_phi_compute_hash (&vp1);
slot = htab_find_slot_with_hash (current_info->phis, &vp1, vp1.hashcode,
NO_INSERT);
slot = current_info->phis.find_slot_with_hash (&vp1, vp1.hashcode, NO_INSERT);
if (!slot && current_info == optimistic_info)
slot = htab_find_slot_with_hash (valid_info->phis, &vp1, vp1.hashcode,
NO_INSERT);
slot = valid_info->phis.find_slot_with_hash (&vp1, vp1.hashcode, NO_INSERT);
if (!slot)
return NULL_TREE;
return ((vn_phi_t)*slot)->result;
return (*slot)->result;
}
/* Insert PHI into the current hash table with a value number of
@ -2501,7 +2565,7 @@ vn_phi_lookup (gimple phi)
static vn_phi_t
vn_phi_insert (gimple phi, tree result)
{
void **slot;
vn_phi_s **slot;
vn_phi_t vp1 = (vn_phi_t) pool_alloc (current_info->phis_pool);
unsigned i;
vec<tree> args = vNULL;
@ -2520,8 +2584,7 @@ vn_phi_insert (gimple phi, tree result)
vp1->result = result;
vp1->hashcode = vn_phi_compute_hash (vp1);
slot = htab_find_slot_with_hash (current_info->phis, vp1, vp1->hashcode,
INSERT);
slot = current_info->phis.find_slot_with_hash (vp1, vp1->hashcode, INSERT);
/* Because we iterate over phi operations more than once, it's
possible the slot might already exist here, hence no assert.*/
@ -2724,7 +2787,7 @@ visit_reference_op_call (tree lhs, gimple stmt)
}
else
{
void **slot;
vn_reference_s **slot;
vn_reference_t vr2;
if (vdef)
changed |= set_ssa_val_to (vdef, vdef);
@ -2738,8 +2801,8 @@ visit_reference_op_call (tree lhs, gimple stmt)
vr2->hashcode = vr1.hashcode;
vr2->result = lhs;
vr2->result_vdef = vdef;
slot = htab_find_slot_with_hash (current_info->references,
vr2, vr2->hashcode, INSERT);
slot = current_info->references.find_slot_with_hash (vr2, vr2->hashcode,
INSERT);
if (*slot)
free_reference (*slot);
*slot = vr2;
@ -3599,10 +3662,10 @@ static void
copy_phi (vn_phi_t ophi, vn_tables_t info)
{
vn_phi_t phi = (vn_phi_t) pool_alloc (info->phis_pool);
void **slot;
vn_phi_s **slot;
memcpy (phi, ophi, sizeof (*phi));
ophi->phiargs.create (0);
slot = htab_find_slot_with_hash (info->phis, phi, phi->hashcode, INSERT);
slot = info->phis.find_slot_with_hash (phi, phi->hashcode, INSERT);
gcc_assert (!*slot);
*slot = phi;
}
@ -3613,12 +3676,11 @@ static void
copy_reference (vn_reference_t oref, vn_tables_t info)
{
vn_reference_t ref;
void **slot;
vn_reference_s **slot;
ref = (vn_reference_t) pool_alloc (info->references_pool);
memcpy (ref, oref, sizeof (*ref));
oref->operands.create (0);
slot = htab_find_slot_with_hash (info->references, ref, ref->hashcode,
INSERT);
slot = info->references.find_slot_with_hash (ref, ref->hashcode, INSERT);
if (*slot)
free_reference (*slot);
*slot = ref;
@ -3633,7 +3695,9 @@ process_scc (vec<tree> scc)
unsigned int i;
unsigned int iterations = 0;
bool changed = true;
htab_iterator hi;
vn_nary_op_iterator_type hin;
vn_phi_iterator_type hip;
vn_reference_iterator_type hir;
vn_nary_op_t nary;
vn_phi_t phi;
vn_reference_t ref;
@ -3670,9 +3734,9 @@ process_scc (vec<tree> scc)
/* As we are value-numbering optimistically we have to
clear the expression tables and the simplified expressions
in each iteration until we converge. */
htab_empty (optimistic_info->nary);
htab_empty (optimistic_info->phis);
htab_empty (optimistic_info->references);
optimistic_info->nary.empty ();
optimistic_info->phis.empty ();
optimistic_info->references.empty ();
obstack_free (&optimistic_info->nary_obstack, NULL);
gcc_obstack_init (&optimistic_info->nary_obstack);
empty_alloc_pool (optimistic_info->phis_pool);
@ -3687,11 +3751,12 @@ process_scc (vec<tree> scc)
/* Finally, copy the contents of the no longer used optimistic
table to the valid table. */
FOR_EACH_HTAB_ELEMENT (optimistic_info->nary, nary, vn_nary_op_t, hi)
FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->nary, nary, vn_nary_op_t, hin)
copy_nary (nary, valid_info);
FOR_EACH_HTAB_ELEMENT (optimistic_info->phis, phi, vn_phi_t, hi)
FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->phis, phi, vn_phi_t, hip)
copy_phi (phi, valid_info);
FOR_EACH_HTAB_ELEMENT (optimistic_info->references, ref, vn_reference_t, hi)
FOR_EACH_HASH_TABLE_ELEMENT (optimistic_info->references,
ref, vn_reference_t, hir)
copy_reference (ref, valid_info);
current_info = valid_info;
@ -3851,10 +3916,9 @@ continue_walking:
static void
allocate_vn_table (vn_tables_t table)
{
table->phis = htab_create (23, vn_phi_hash, vn_phi_eq, free_phi);
table->nary = htab_create (23, vn_nary_op_hash, vn_nary_op_eq, NULL);
table->references = htab_create (23, vn_reference_hash, vn_reference_eq,
free_reference);
table->phis.create (23);
table->nary.create (23);
table->references.create (23);
gcc_obstack_init (&table->nary_obstack);
table->phis_pool = create_alloc_pool ("VN phis",
@ -3870,9 +3934,9 @@ allocate_vn_table (vn_tables_t table)
static void
free_vn_table (vn_tables_t table)
{
htab_delete (table->phis);
htab_delete (table->nary);
htab_delete (table->references);
table->phis.dispose ();
table->nary.dispose ();
table->references.dispose ();
obstack_free (&table->nary_obstack, NULL);
free_alloc_pool (table->phis_pool);
free_alloc_pool (table->references_pool);
@ -3887,8 +3951,7 @@ init_scc_vn (void)
calculate_dominance_info (CDI_DOMINATORS);
sccstack.create (0);
constant_to_value_id = htab_create (23, vn_constant_hash, vn_constant_eq,
free);
constant_to_value_id.create (23);
constant_value_ids = BITMAP_ALLOC (NULL);
@ -3944,7 +4007,7 @@ free_scc_vn (void)
{
size_t i;
htab_delete (constant_to_value_id);
constant_to_value_id.dispose ();
BITMAP_FREE (constant_value_ids);
shared_lookup_phiargs.release ();
shared_lookup_references.release ();
@ -3985,7 +4048,9 @@ set_value_id_for_result (tree result, unsigned int *id)
static void
set_hashtable_value_ids (void)
{
htab_iterator hi;
vn_nary_op_iterator_type hin;
vn_phi_iterator_type hip;
vn_reference_iterator_type hir;
vn_nary_op_t vno;
vn_reference_t vr;
vn_phi_t vp;
@ -3993,16 +4058,13 @@ set_hashtable_value_ids (void)
/* Now set the value ids of the things we had put in the hash
table. */
FOR_EACH_HTAB_ELEMENT (valid_info->nary,
vno, vn_nary_op_t, hi)
FOR_EACH_HASH_TABLE_ELEMENT (valid_info->nary, vno, vn_nary_op_t, hin)
set_value_id_for_result (vno->result, &vno->value_id);
FOR_EACH_HTAB_ELEMENT (valid_info->phis,
vp, vn_phi_t, hi)
FOR_EACH_HASH_TABLE_ELEMENT (valid_info->phis, vp, vn_phi_t, hip)
set_value_id_for_result (vp->result, &vp->value_id);
FOR_EACH_HTAB_ELEMENT (valid_info->references,
vr, vn_reference_t, hi)
FOR_EACH_HASH_TABLE_ELEMENT (valid_info->references, vr, vn_reference_t, hir)
set_value_id_for_result (vr->result, &vr->value_id);
}

View File

@ -216,10 +216,11 @@ vn_reference_t vn_reference_insert_pieces (tree, alias_set_type, tree,
tree, unsigned int);
hashval_t vn_nary_op_compute_hash (const vn_nary_op_t);
int vn_nary_op_eq (const void *, const void *);
bool vn_nary_op_eq (const_vn_nary_op_t const vno1,
const_vn_nary_op_t const vno2);
bool vn_nary_may_trap (vn_nary_op_t);
hashval_t vn_reference_compute_hash (const vn_reference_t);
int vn_reference_eq (const void *, const void *);
bool vn_reference_eq (const_vn_reference_t const, const_vn_reference_t const);
unsigned int get_max_value_id (void);
unsigned int get_next_value_id (void);
unsigned int get_constant_value_id (tree);

View File

@ -32,7 +32,7 @@
#include "tree-inline.h"
#include "diagnostic-core.h"
#include "gimple.h"
#include "hashtab.h"
#include "hash-table.h"
#include "function.h"
#include "cgraph.h"
#include "tree-pass.h"
@ -1862,48 +1862,54 @@ typedef struct equiv_class_label
} *equiv_class_label_t;
typedef const struct equiv_class_label *const_equiv_class_label_t;
/* A hashtable for mapping a bitmap of labels->pointer equivalence
classes. */
static htab_t pointer_equiv_class_table;
/* Equiv_class_label hashtable helpers. */
/* A hashtable for mapping a bitmap of labels->location equivalence
classes. */
static htab_t location_equiv_class_table;
struct equiv_class_hasher : typed_free_remove <equiv_class_label>
{
typedef equiv_class_label value_type;
typedef equiv_class_label compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
/* Hash function for a equiv_class_label_t */
static hashval_t
equiv_class_label_hash (const void *p)
inline hashval_t
equiv_class_hasher::hash (const value_type *ecl)
{
const_equiv_class_label_t const ecl = (const_equiv_class_label_t) p;
return ecl->hashcode;
}
/* Equality function for two equiv_class_label_t's. */
static int
equiv_class_label_eq (const void *p1, const void *p2)
inline bool
equiv_class_hasher::equal (const value_type *eql1, const compare_type *eql2)
{
const_equiv_class_label_t const eql1 = (const_equiv_class_label_t) p1;
const_equiv_class_label_t const eql2 = (const_equiv_class_label_t) p2;
return (eql1->hashcode == eql2->hashcode
&& bitmap_equal_p (eql1->labels, eql2->labels));
}
/* A hashtable for mapping a bitmap of labels->pointer equivalence
classes. */
static hash_table <equiv_class_hasher> pointer_equiv_class_table;
/* A hashtable for mapping a bitmap of labels->location equivalence
classes. */
static hash_table <equiv_class_hasher> location_equiv_class_table;
/* Lookup a equivalence class in TABLE by the bitmap of LABELS with
hash HAS it contains. Sets *REF_LABELS to the bitmap LABELS
is equivalent to. */
static equiv_class_label *
equiv_class_lookup_or_add (htab_t table, bitmap labels)
equiv_class_lookup_or_add (hash_table <equiv_class_hasher> table, bitmap labels)
{
equiv_class_label **slot;
equiv_class_label ecl;
ecl.labels = labels;
ecl.hashcode = bitmap_hash (labels);
slot = (equiv_class_label **) htab_find_slot_with_hash (table, &ecl,
ecl.hashcode, INSERT);
slot = table.find_slot_with_hash (&ecl, ecl.hashcode, INSERT);
if (!*slot)
{
*slot = XNEW (struct equiv_class_label);
@ -2222,10 +2228,8 @@ perform_var_substitution (constraint_graph_t graph)
struct scc_info *si = init_scc_info (size);
bitmap_obstack_initialize (&iteration_obstack);
pointer_equiv_class_table = htab_create (511, equiv_class_label_hash,
equiv_class_label_eq, free);
location_equiv_class_table = htab_create (511, equiv_class_label_hash,
equiv_class_label_eq, free);
pointer_equiv_class_table.create (511);
location_equiv_class_table.create (511);
pointer_equiv_class = 1;
location_equiv_class = 1;
@ -2358,8 +2362,8 @@ free_var_substitution_info (struct scc_info *si)
free (graph->points_to);
free (graph->eq_rep);
sbitmap_free (graph->direct_nodes);
htab_delete (pointer_equiv_class_table);
htab_delete (location_equiv_class_table);
pointer_equiv_class_table.dispose ();
location_equiv_class_table.dispose ();
bitmap_obstack_release (&iteration_obstack);
}
@ -5900,45 +5904,54 @@ typedef struct shared_bitmap_info
} *shared_bitmap_info_t;
typedef const struct shared_bitmap_info *const_shared_bitmap_info_t;
static htab_t shared_bitmap_table;
/* Shared_bitmap hashtable helpers. */
struct shared_bitmap_hasher : typed_free_remove <shared_bitmap_info>
{
typedef shared_bitmap_info value_type;
typedef shared_bitmap_info compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
/* Hash function for a shared_bitmap_info_t */
static hashval_t
shared_bitmap_hash (const void *p)
inline hashval_t
shared_bitmap_hasher::hash (const value_type *bi)
{
const_shared_bitmap_info_t const bi = (const_shared_bitmap_info_t) p;
return bi->hashcode;
}
/* Equality function for two shared_bitmap_info_t's. */
static int
shared_bitmap_eq (const void *p1, const void *p2)
inline bool
shared_bitmap_hasher::equal (const value_type *sbi1, const compare_type *sbi2)
{
const_shared_bitmap_info_t const sbi1 = (const_shared_bitmap_info_t) p1;
const_shared_bitmap_info_t const sbi2 = (const_shared_bitmap_info_t) p2;
return bitmap_equal_p (sbi1->pt_vars, sbi2->pt_vars);
}
/* Shared_bitmap hashtable. */
static hash_table <shared_bitmap_hasher> shared_bitmap_table;
/* Lookup a bitmap in the shared bitmap hashtable, and return an already
existing instance if there is one, NULL otherwise. */
static bitmap
shared_bitmap_lookup (bitmap pt_vars)
{
void **slot;
shared_bitmap_info **slot;
struct shared_bitmap_info sbi;
sbi.pt_vars = pt_vars;
sbi.hashcode = bitmap_hash (pt_vars);
slot = htab_find_slot_with_hash (shared_bitmap_table, &sbi,
sbi.hashcode, NO_INSERT);
slot = shared_bitmap_table.find_slot_with_hash (&sbi, sbi.hashcode,
NO_INSERT);
if (!slot)
return NULL;
else
return ((shared_bitmap_info_t) *slot)->pt_vars;
return (*slot)->pt_vars;
}
@ -5947,16 +5960,15 @@ shared_bitmap_lookup (bitmap pt_vars)
static void
shared_bitmap_add (bitmap pt_vars)
{
void **slot;
shared_bitmap_info **slot;
shared_bitmap_info_t sbi = XNEW (struct shared_bitmap_info);
sbi->pt_vars = pt_vars;
sbi->hashcode = bitmap_hash (pt_vars);
slot = htab_find_slot_with_hash (shared_bitmap_table, sbi,
sbi->hashcode, INSERT);
slot = shared_bitmap_table.find_slot_with_hash (sbi, sbi->hashcode, INSERT);
gcc_assert (!*slot);
*slot = (void *) sbi;
*slot = sbi;
}
@ -6612,8 +6624,7 @@ init_alias_vars (void)
call_stmt_vars = pointer_map_create ();
memset (&stats, 0, sizeof (stats));
shared_bitmap_table = htab_create (511, shared_bitmap_hash,
shared_bitmap_eq, free);
shared_bitmap_table.create (511);
init_base_vars ();
gcc_obstack_init (&fake_var_decl_obstack);
@ -6869,7 +6880,7 @@ delete_points_to_sets (void)
{
unsigned int i;
htab_delete (shared_bitmap_table);
shared_bitmap_table.dispose ();
if (dump_file && (dump_flags & TDF_STATS))
fprintf (dump_file, "Points to sets created:%d\n",
stats.points_to_sets_created);

View File

@ -1062,27 +1062,6 @@ vect_get_data_access_cost (struct data_reference *dr,
}
static hashval_t
vect_peeling_hash (const void *elem)
{
const struct _vect_peel_info *peel_info;
peel_info = (const struct _vect_peel_info *) elem;
return (hashval_t) peel_info->npeel;
}
static int
vect_peeling_hash_eq (const void *elem1, const void *elem2)
{
const struct _vect_peel_info *a, *b;
a = (const struct _vect_peel_info *) elem1;
b = (const struct _vect_peel_info *) elem2;
return (a->npeel == b->npeel);
}
/* Insert DR into peeling hash table with NPEEL as key. */
static void
@ -1090,12 +1069,11 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
int npeel)
{
struct _vect_peel_info elem, *slot;
void **new_slot;
_vect_peel_info **new_slot;
bool supportable_dr_alignment = vect_supportable_dr_alignment (dr, true);
elem.npeel = npeel;
slot = (vect_peel_info) htab_find (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
&elem);
slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo).find (&elem);
if (slot)
slot->count++;
else
@ -1104,8 +1082,7 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
slot->npeel = npeel;
slot->dr = dr;
slot->count = 1;
new_slot = htab_find_slot (LOOP_VINFO_PEELING_HTAB (loop_vinfo), slot,
INSERT);
new_slot = LOOP_VINFO_PEELING_HTAB (loop_vinfo).find_slot (slot, INSERT);
*new_slot = slot;
}
@ -1117,11 +1094,11 @@ vect_peeling_hash_insert (loop_vec_info loop_vinfo, struct data_reference *dr,
/* Traverse peeling hash table to find peeling option that aligns maximum
number of data accesses. */
static int
vect_peeling_hash_get_most_frequent (void **slot, void *data)
int
vect_peeling_hash_get_most_frequent (_vect_peel_info **slot,
_vect_peel_extended_info *max)
{
vect_peel_info elem = (vect_peel_info) *slot;
vect_peel_extended_info max = (vect_peel_extended_info) data;
vect_peel_info elem = *slot;
if (elem->count > max->peel_info.count
|| (elem->count == max->peel_info.count
@ -1139,11 +1116,11 @@ vect_peeling_hash_get_most_frequent (void **slot, void *data)
/* Traverse peeling hash table and calculate cost for each peeling option.
Find the one with the lowest cost. */
static int
vect_peeling_hash_get_lowest_cost (void **slot, void *data)
int
vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot,
_vect_peel_extended_info *min)
{
vect_peel_info elem = (vect_peel_info) *slot;
vect_peel_extended_info min = (vect_peel_extended_info) data;
vect_peel_info elem = *slot;
int save_misalignment, dummy;
unsigned int inside_cost = 0, outside_cost = 0, i;
gimple stmt = DR_STMT (elem->dr);
@ -1223,14 +1200,16 @@ vect_peeling_hash_choose_best_peeling (loop_vec_info loop_vinfo,
{
res.inside_cost = INT_MAX;
res.outside_cost = INT_MAX;
htab_traverse (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
vect_peeling_hash_get_lowest_cost, &res);
LOOP_VINFO_PEELING_HTAB (loop_vinfo)
.traverse <_vect_peel_extended_info *,
vect_peeling_hash_get_lowest_cost> (&res);
}
else
{
res.peel_info.count = 0;
htab_traverse (LOOP_VINFO_PEELING_HTAB (loop_vinfo),
vect_peeling_hash_get_most_frequent, &res);
LOOP_VINFO_PEELING_HTAB (loop_vinfo)
.traverse <_vect_peel_extended_info *,
vect_peeling_hash_get_most_frequent> (&res);
}
*npeel = res.peel_info.npeel;
@ -1423,10 +1402,8 @@ vect_enhance_data_refs_alignment (loop_vec_info loop_vinfo)
size_zero_node) < 0;
/* Save info about DR in the hash table. */
if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo))
LOOP_VINFO_PEELING_HTAB (loop_vinfo) =
htab_create (1, vect_peeling_hash,
vect_peeling_hash_eq, free);
if (!LOOP_VINFO_PEELING_HTAB (loop_vinfo).is_created ())
LOOP_VINFO_PEELING_HTAB (loop_vinfo).create (1);
vectype = STMT_VINFO_VECTYPE (stmt_info);
nelements = TYPE_VECTOR_SUBPARTS (vectype);

View File

@ -879,7 +879,6 @@ new_loop_vec_info (struct loop *loop)
LOOP_VINFO_REDUCTION_CHAINS (res).create (10);
LOOP_VINFO_SLP_INSTANCES (res).create (10);
LOOP_VINFO_SLP_UNROLLING_FACTOR (res) = 1;
LOOP_VINFO_PEELING_HTAB (res) = NULL;
LOOP_VINFO_TARGET_COST_DATA (res) = init_cost (loop);
LOOP_VINFO_PEELING_FOR_GAPS (res) = false;
LOOP_VINFO_OPERANDS_SWAPPED (res) = false;
@ -960,8 +959,8 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
LOOP_VINFO_REDUCTIONS (loop_vinfo).release ();
LOOP_VINFO_REDUCTION_CHAINS (loop_vinfo).release ();
if (LOOP_VINFO_PEELING_HTAB (loop_vinfo))
htab_delete (LOOP_VINFO_PEELING_HTAB (loop_vinfo));
if (LOOP_VINFO_PEELING_HTAB (loop_vinfo).is_created ())
LOOP_VINFO_PEELING_HTAB (loop_vinfo).dispose ();
destroy_cost_data (LOOP_VINFO_TARGET_COST_DATA (loop_vinfo));

View File

@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-data-ref.h"
#include "target.h"
#include "hash-table.h"
typedef source_location LOC;
#define UNKNOWN_LOC UNKNOWN_LOCATION
@ -189,6 +190,30 @@ typedef struct _vect_peel_extended_info
stmt_vector_for_cost body_cost_vec;
} *vect_peel_extended_info;
/* Peeling hashtable helpers. */
struct peel_info_hasher : typed_free_remove <_vect_peel_info>
{
typedef _vect_peel_info value_type;
typedef _vect_peel_info compare_type;
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
inline hashval_t
peel_info_hasher::hash (const value_type *peel_info)
{
return (hashval_t) peel_info->npeel;
}
inline bool
peel_info_hasher::equal (const value_type *a, const compare_type *b)
{
return (a->npeel == b->npeel);
}
/*-----------------------------------------------------------------*/
/* Info on vectorized loops. */
/*-----------------------------------------------------------------*/
@ -273,7 +298,7 @@ typedef struct _loop_vec_info {
vec<gimple> reduction_chains;
/* Hash table used to choose the best peeling option. */
htab_t peeling_htab;
hash_table <peel_info_hasher> peeling_htab;
/* Cost data used by the target cost model. */
void *target_cost_data;