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