diff --git a/gcc/ChangeLog b/gcc/ChangeLog index effbb41a945..ebc10025bcd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,34 @@ +2012-08-17 Richard Guenther + + * 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 * params.def (integer-share-limit): Decrease from 256 to 251, diff --git a/gcc/coverage.c b/gcc/coverage.c index 3fea525a08d..b4d22dfd9c6 100644 --- a/gcc/coverage.c +++ b/gcc/coverage.c @@ -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_hash; +static hash_table counts_hash; /* Read in the counts file, if available. */ diff --git a/gcc/hash-table.h b/gcc/hash-table.h index 2c483e2b858..91231a21c33 100644 --- a/gcc/hash-table.h +++ b/gcc/hash-table.h @@ -83,48 +83,55 @@ xcallocator ::data_free (Type *memory) } -/* A common function for hashing a CANDIDATE typed pointer. */ +/* Remove method dispatching to free. */ + +template +struct typed_free_remove +{ + static inline void remove (Element *p) { free (p); } +}; + +/* No-op remove method. */ + +template +struct typed_noop_remove +{ + static inline void remove (Element *) {} +}; + + +/* Pointer hash with a no-op remove method. */ + +template +struct pointer_hash : typed_noop_remove +{ + typedef Element T; + + static inline hashval_t + hash (const T *); + + static inline int + equal (const T *existing, const T * candidate); +}; template inline hashval_t -typed_pointer_hash (const Element *candidate) +pointer_hash::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 inline int -typed_pointer_equal (const Element *existing, const Element * candidate) +pointer_hash::equal (const T *existing, + const T *candidate) { return existing == candidate; } -/* A common function for doing nothing on removing a RETIRED slot. */ - -template -inline void -typed_null_remove (Element *retired ATTRIBUTE_UNUSED) -{ -} - - -/* A common function for using free on removing a RETIRED slot. */ - -template -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 +template 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 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 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 when not freeing objects. Use typed_free_remove when doing a simple object free. @@ -198,59 +205,53 @@ struct hash_table_control */ -template class Allocator = xcallocator> class hash_table { +public: + typedef typename Descr::T T; private: + hash_table_control *htab; - hash_table_control *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 + int (*Callback) (T **slot, Argument argument)> void traverse_noresize (Argument argument); template + int (*Callback) (T **slot, Argument argument)> void traverse (Argument argument); }; /* Construct the hash table. The only useful operation next is create. */ -template class Allocator> inline -hash_table ::hash_table () +hash_table ::hash_table () : htab (NULL) { } @@ -258,13 +259,10 @@ hash_table ::hash_table () /* See if the table has been created, as opposed to constructed. */ -template class Allocator> inline bool -hash_table ::is_created () +hash_table ::is_created () { return htab != NULL; } @@ -272,57 +270,45 @@ hash_table ::is_created () /* Like find_with_hash, but compute the hash value from the element. */ -template class Allocator> -inline Element * -hash_table ::find (Element *comparable) +inline typename Descr::T * +hash_table ::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 class Allocator> -inline Element ** -hash_table -::find_slot (Element *comparable, enum insert_option insert) +inline typename Descr::T ** +hash_table +::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 class Allocator> inline void -hash_table -::remove_elt (Element *comparable) +hash_table +::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 class Allocator> inline size_t -hash_table ::size() +hash_table ::size() { return htab->size; } @@ -330,13 +316,10 @@ hash_table ::size() /* Return the current number of elements in this hash table. */ -template class Allocator> inline size_t -hash_table ::elements() +hash_table ::elements() { return htab->n_elements - htab->n_deleted; } @@ -345,13 +328,10 @@ hash_table ::elements() /* Return the fraction of fixed collisions during all work with given hash table. */ -template class Allocator> inline double -hash_table ::collisions() +hash_table ::collisions() { if (htab->searches == 0) return 0.0; @@ -362,22 +342,19 @@ hash_table ::collisions() /* Create a hash table with at least the given number of INITIAL_SLOTS. */ -template class Allocator> void -hash_table ::create (size_t size) +hash_table ::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 > ::control_alloc (1); + htab = Allocator > ::control_alloc (1); gcc_assert (htab != NULL); - htab->entries = Allocator ::data_alloc (size); + htab->entries = Allocator ::data_alloc (size); gcc_assert (htab->entries != NULL); htab->size = size; htab->size_prime_index = size_prime_index; @@ -387,46 +364,40 @@ hash_table ::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 class Allocator> void -hash_table ::dispose () +hash_table ::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 ::data_free (entries); - Allocator > ::control_free (htab); + Allocator ::data_free (entries); + Allocator > ::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 class Allocator> -Element ** -hash_table +typename Descr::T ** +hash_table ::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 table entries is changed. If memory allocation fails, this function will abort. */ -template class Allocator> void -hash_table ::expand () +hash_table ::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 ::expand () nsize = osize; } - nentries = Allocator ::data_alloc (nsize); + nentries = Allocator ::data_alloc (nsize); gcc_assert (nentries != NULL); htab->entries = nentries; htab->size = nsize; @@ -502,11 +470,11 @@ hash_table ::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 ::expand () } while (p < olimit); - Allocator ::data_free (oentries); + Allocator ::data_free (oentries); } @@ -523,18 +491,15 @@ hash_table ::expand () COMPARABLE element starting with the given HASH value. It cannot be used to insert or delete an element. */ -template class Allocator> -Element * -hash_table -::find_with_hash (Element *comparable, hashval_t hash) +typename Descr::T * +hash_table +::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 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 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 write the value you want into the returned slot. When inserting an entry, NULL may be returned if memory allocation fails. */ -template class Allocator> -Element ** -hash_table -::find_slot_with_hash (Element *comparable, hashval_t hash, +typename Descr::T ** +hash_table +::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 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 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 if (first_deleted_slot) { htab->n_deleted--; - *first_deleted_slot = static_cast (HTAB_EMPTY_ENTRY); + *first_deleted_slot = static_cast (HTAB_EMPTY_ENTRY); return first_deleted_slot; } @@ -642,21 +604,18 @@ hash_table /* This function clears all entries in the given hash table. */ -template class Allocator> void -hash_table ::empty () +hash_table ::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 ::empty () int nindex = hash_table_higher_prime_index (1024 / sizeof (PTR)); int nsize = prime_tab[nindex].prime; - Allocator ::data_free (htab->entries); - htab->entries = Allocator ::data_alloc (nsize); + Allocator ::data_free (htab->entries); + htab->entries = Allocator ::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 ::empty () useful when you've already done the lookup and don't want to do it again. */ -template class Allocator> void -hash_table -::clear_slot (Element **slot) +hash_table +::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 from hash table starting with the given HASH. If there is no matching element in the hash table, this function does nothing. */ -template class Allocator> void -hash_table -::remove_elt_with_hash (Element *comparable, hashval_t hash) +hash_table +::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 (HTAB_DELETED_ENTRY); + *slot = static_cast (HTAB_DELETED_ENTRY); htab->n_deleted++; } @@ -730,26 +683,23 @@ hash_table each live entry. If CALLBACK returns false, the iteration stops. ARGUMENT is passed as CALLBACK's second argument. */ -template class Allocator> template + int (*Callback) (typename Descr::T **slot, Argument argument)> void -hash_table +hash_table ::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 /* Like traverse_noresize, but does resize the table when it is too empty to improve effectivity of subsequent calls. */ -template class Allocator> template + int (*Callback) (typename Descr::T **slot, Argument argument)> void -hash_table +hash_table ::traverse (Argument argument) { size_t size = htab->size; diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c index 4b798b70b5c..ac6ad5da74f 100644 --- a/gcc/tree-ssa-ccp.c +++ b/gcc/tree-ssa-ccp.c @@ -1688,10 +1688,7 @@ evaluate_stmt (gimple stmt) return val; } -typedef hash_table , - typed_pointer_equal, - typed_null_remove > - gimple_htab; +typedef hash_table > 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. */ diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c index c8557ac56ed..dfcd4aad4fa 100644 --- a/gcc/tree-ssa-coalesce.c +++ b/gcc/tree-ssa-coalesce.c @@ -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 +{ + 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 > - ssa_name_hash; + static hash_table ssa_name_hash; cl = create_coalesce_list (); map = create_outofssa_var_map (cl, used_in_copies); diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c index 51d9e02228d..e1135395f65 100644 --- a/gcc/tree-ssa-pre.c +++ b/gcc/tree-ssa-pre.c @@ -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 { 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 > - expression_to_id; +static hash_table 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 { /* 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 > - phi_translate_table; +static hash_table 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; } } diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c index ec644ee3541..372096c344c 100644 --- a/gcc/tree-ssa-tail-merge.c +++ b/gcc/tree-ssa-tail-merge.c @@ -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 - same_succ_htab; +static hash_table 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); } diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c index 3ecb3030d03..86ad74f1bc8 100644 --- a/gcc/tree-ssa-threadupdate.c +++ b/gcc/tree-ssa-threadupdate.c @@ -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 { /* 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 > - redirection_data; +static hash_table redirection_data; /* Given an outgoing edge E lookup and return its entry in our hash table.