[cxx-conversion] Iterator for hash_table, and associated conversions
Lawrence Crowl
crowl@googlers.com
Fri Dec 14 04:08:00 GMT 2012
Add standard-style iterators to hash_table.
Implement gcc-style FOR_EACH on top of those iterators.
* 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.
Convert several uses of htab_t to use hash_table.
Adjust types and calls to match.
These files also use the 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.
* var-tracking.c'emit_note_data_def.vars
* var-tracking.c'shared_hash_def.htab
* var-tracking.c'changed_variables
Fold variable_htab_hash, variable_htab_eq, variable_htab_free
into new struct variable_hasher.
Add typedef variable_table_type.
Add typedef variable_iterator_type.
* trans-mem.c'tm_log
Fold tm_log_hash, tm_log_eq, tm_log_free into new struct log_entry_hasher.
* trans-mem.c'tm_memopt_value_numbers
Fold tm_memop_hash, tm_memop_eq into new struct tm_memop_hasher.
Tested on x86-64.
Okay for branch?
Index: gcc/tree-into-ssa.c
===================================================================
--- gcc/tree-into-ssa.c (revision 194487)
+++ gcc/tree-into-ssa.c (working copy)
@@ -34,7 +34,7 @@ along with GCC; see the file COPYING3.
#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"
@@ -161,9 +161,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. */
@@ -341,17 +364,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;
}
@@ -1039,15 +1062,15 @@ insert_phi_nodes_compare_var_infos (cons
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);
@@ -1622,12 +1645,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 ());
}
@@ -1636,7 +1659,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: ");
@@ -1655,29 +1678,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);
@@ -1698,8 +1704,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);
}
@@ -2200,7 +2206,7 @@ rewrite_blocks (basic_block entry, enum
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);
}
@@ -2280,9 +2286,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);
}
@@ -2293,11 +2298,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);
@@ -3162,7 +3164,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
Index: gcc/var-tracking.c
===================================================================
--- gcc/var-tracking.c (revision 194487)
+++ gcc/var-tracking.c (working copy)
@@ -101,7 +101,7 @@
#include "sbitmap.h"
#include "alloc-pool.h"
#include "fibheap.h"
-#include "hashtab.h"
+#include "hash-table.h"
#include "regs.h"
#include "expr.h"
#include "tree-pass.h"
@@ -197,19 +197,43 @@ typedef struct micro_operation_def
declaration. */
typedef void *decl_or_value;
-/* Structure for passing some other parameters to function
- emit_note_insn_var_location. */
-typedef struct emit_note_data_def
+/* Return true if a decl_or_value DV is a DECL or NULL. */
+static inline bool
+dv_is_decl_p (decl_or_value dv)
{
- /* The instruction which the note will be emitted before/after. */
- rtx insn;
+ return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
+}
- /* Where the note will be emitted (before/after insn)? */
- enum emit_note_where where;
+/* Return true if a decl_or_value is a VALUE rtl. */
+static inline bool
+dv_is_value_p (decl_or_value dv)
+{
+ return dv && !dv_is_decl_p (dv);
+}
+
+/* Return the decl in the decl_or_value. */
+static inline tree
+dv_as_decl (decl_or_value dv)
+{
+ gcc_checking_assert (dv_is_decl_p (dv));
+ return (tree) dv;
+}
+
+/* Return the value in the decl_or_value. */
+static inline rtx
+dv_as_value (decl_or_value dv)
+{
+ gcc_checking_assert (dv_is_value_p (dv));
+ return (rtx)dv;
+}
+
+/* Return the opaque pointer in the decl_or_value. */
+static inline void *
+dv_as_opaque (decl_or_value dv)
+{
+ return dv;
+}
- /* The variables and values active at this point. */
- htab_t vars;
-} emit_note_data;
/* Description of location of a part of a variable. The content of a physical
register is described by a chain of these structures.
@@ -230,58 +254,6 @@ typedef struct attrs_def
HOST_WIDE_INT offset;
} *attrs;
-/* Structure holding a refcounted hash table. If refcount > 1,
- it must be first unshared before modified. */
-typedef struct shared_hash_def
-{
- /* Reference count. */
- int refcount;
-
- /* Actual hash table. */
- htab_t htab;
-} *shared_hash;
-
-/* Structure holding the IN or OUT set for a basic block. */
-typedef struct dataflow_set_def
-{
- /* Adjustment of stack offset. */
- HOST_WIDE_INT stack_adjust;
-
- /* Attributes for registers (lists of attrs). */
- attrs regs[FIRST_PSEUDO_REGISTER];
-
- /* Variable locations. */
- shared_hash vars;
-
- /* Vars that is being traversed. */
- shared_hash traversed_vars;
-} dataflow_set;
-
-/* The structure (one for each basic block) containing the information
- needed for variable tracking. */
-typedef struct variable_tracking_info_def
-{
- /* The vector of micro operations. */
- vec<micro_operation> mos;
-
- /* The IN and OUT set for dataflow analysis. */
- dataflow_set in;
- dataflow_set out;
-
- /* The permanent-in dataflow set for this block. This is used to
- hold values for which we had to compute entry values. ??? This
- should probably be dynamically allocated, to avoid using more
- memory in non-debug builds. */
- dataflow_set *permp;
-
- /* Has the block been visited in DFS? */
- bool visited;
-
- /* Has the block been flooded in VTA? */
- bool flooded;
-
-} *variable_tracking_info;
-
/* Structure for chaining the locations. */
typedef struct location_chain_def
{
@@ -455,6 +427,146 @@ typedef const struct variable_def *const
? &VAR_LOC_1PAUX (var)->deps \
: NULL)
+
+
+typedef unsigned int dvuid;
+
+/* Return the uid of DV. */
+
+static inline dvuid
+dv_uid (decl_or_value dv)
+{
+ if (dv_is_value_p (dv))
+ return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
+ else
+ return DECL_UID (dv_as_decl (dv));
+}
+
+/* Compute the hash from the uid. */
+
+static inline hashval_t
+dv_uid2hash (dvuid uid)
+{
+ return uid;
+}
+
+/* The hash function for a mask table in a shared_htab chain. */
+
+static inline hashval_t
+dv_htab_hash (decl_or_value dv)
+{
+ return dv_uid2hash (dv_uid (dv));
+}
+
+static void variable_htab_free (void *);
+
+/* Variable hashtable helpers. */
+
+struct variable_hasher
+{
+ typedef variable_def value_type;
+ typedef void 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 *);
+};
+
+/* The hash function for variable_htab, computes the hash value
+ from the declaration of variable X. */
+
+inline hashval_t
+variable_hasher::hash (const value_type *v)
+{
+ return dv_htab_hash (v->dv);
+}
+
+/* Compare the declaration of variable X with declaration Y. */
+
+inline bool
+variable_hasher::equal (const value_type *v, const compare_type *y)
+{
+ decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
+
+ return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
+}
+
+/* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
+
+inline void
+variable_hasher::remove (value_type *var)
+{
+ variable_htab_free (var);
+}
+
+typedef hash_table <variable_hasher> variable_table_type;
+typedef variable_table_type::iterator variable_iterator_type;
+
+/* Structure for passing some other parameters to function
+ emit_note_insn_var_location. */
+typedef struct emit_note_data_def
+{
+ /* The instruction which the note will be emitted before/after. */
+ rtx insn;
+
+ /* Where the note will be emitted (before/after insn)? */
+ enum emit_note_where where;
+
+ /* The variables and values active at this point. */
+ variable_table_type vars;
+} emit_note_data;
+
+/* Structure holding a refcounted hash table. If refcount > 1,
+ it must be first unshared before modified. */
+typedef struct shared_hash_def
+{
+ /* Reference count. */
+ int refcount;
+
+ /* Actual hash table. */
+ variable_table_type htab;
+} *shared_hash;
+
+/* Structure holding the IN or OUT set for a basic block. */
+typedef struct dataflow_set_def
+{
+ /* Adjustment of stack offset. */
+ HOST_WIDE_INT stack_adjust;
+
+ /* Attributes for registers (lists of attrs). */
+ attrs regs[FIRST_PSEUDO_REGISTER];
+
+ /* Variable locations. */
+ shared_hash vars;
+
+ /* Vars that is being traversed. */
+ shared_hash traversed_vars;
+} dataflow_set;
+
+/* The structure (one for each basic block) containing the information
+ needed for variable tracking. */
+typedef struct variable_tracking_info_def
+{
+ /* The vector of micro operations. */
+ vec<micro_operation> mos;
+
+ /* The IN and OUT set for dataflow analysis. */
+ dataflow_set in;
+ dataflow_set out;
+
+ /* The permanent-in dataflow set for this block. This is used to
+ hold values for which we had to compute entry values. ??? This
+ should probably be dynamically allocated, to avoid using more
+ memory in non-debug builds. */
+ dataflow_set *permp;
+
+ /* Has the block been visited in DFS? */
+ bool visited;
+
+ /* Has the block been flooded in VTA? */
+ bool flooded;
+
+} *variable_tracking_info;
+
/* Alloc pool for struct attrs_def. */
static alloc_pool attrs_pool;
@@ -474,7 +586,7 @@ static alloc_pool shared_hash_pool;
static alloc_pool loc_exp_dep_pool;
/* Changed variables, notes will be emitted for them. */
-static htab_t changed_variables;
+static variable_table_type changed_variables;
/* Shall notes be emitted? */
static bool emit_notes;
@@ -482,7 +594,7 @@ static bool emit_notes;
/* Values whose dynamic location lists have gone empty, but whose
cselib location lists are still usable. Use this to hold the
current location, the backlinks, etc, during emit_notes. */
-static htab_t dropped_values;
+static variable_table_type dropped_values;
/* Empty shared hashtable. */
static shared_hash empty_shared_hash;
@@ -510,9 +622,6 @@ static void stack_adjust_offset_pre_post
static void insn_stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
HOST_WIDE_INT *);
static bool vt_stack_adjustments (void);
-static hashval_t variable_htab_hash (const void *);
-static int variable_htab_eq (const void *, const void *);
-static void variable_htab_free (void *);
static void init_attrs_list_set (attrs *);
static void attrs_list_clear (attrs *);
@@ -521,9 +630,9 @@ static void attrs_list_insert (attrs *,
static void attrs_list_copy (attrs *, attrs);
static void attrs_list_union (attrs *, attrs);
-static void **unshare_variable (dataflow_set *set, void **slot, variable var,
- enum var_init_status);
-static void vars_copy (htab_t, htab_t);
+static variable_def **unshare_variable (dataflow_set *set, variable_def **slot,
+ variable var, enum var_init_status);
+static void vars_copy (variable_table_type, variable_table_type);
static tree var_debug_decl (tree);
static void var_reg_set (dataflow_set *, rtx, enum var_init_status, rtx);
static void var_reg_delete_and_set (dataflow_set *, rtx, bool,
@@ -540,7 +649,7 @@ static void dataflow_set_clear (dataflow
static void dataflow_set_copy (dataflow_set *, dataflow_set *);
static int variable_union_info_cmp_pos (const void *, const void *);
static void dataflow_set_union (dataflow_set *, dataflow_set *);
-static location_chain find_loc_in_1pdv (rtx, variable, htab_t);
+static location_chain find_loc_in_1pdv (rtx, variable, variable_table_type);
static bool canon_value_cmp (rtx, rtx);
static int loc_cmp (rtx, rtx);
static bool variable_part_different_p (variable_part *, variable_part *);
@@ -559,32 +668,27 @@ static bool compute_bb_dataflow (basic_b
static bool vt_find_locations (void);
static void dump_attrs_list (attrs);
-static int dump_var_slot (void **, void *);
static void dump_var (variable);
-static void dump_vars (htab_t);
+static void dump_vars (variable_table_type);
static void dump_dataflow_set (dataflow_set *);
static void dump_dataflow_sets (void);
static void set_dv_changed (decl_or_value, bool);
static void variable_was_changed (variable, dataflow_set *);
-static void **set_slot_part (dataflow_set *, rtx, void **,
- decl_or_value, HOST_WIDE_INT,
- enum var_init_status, rtx);
+static variable_def **set_slot_part (dataflow_set *, rtx, variable_def **,
+ decl_or_value, HOST_WIDE_INT,
+ enum var_init_status, rtx);
static void set_variable_part (dataflow_set *, rtx,
decl_or_value, HOST_WIDE_INT,
enum var_init_status, rtx, enum insert_option);
-static void **clobber_slot_part (dataflow_set *, rtx,
- void **, HOST_WIDE_INT, rtx);
+static variable_def **clobber_slot_part (dataflow_set *, rtx,
+ variable_def **, HOST_WIDE_INT, rtx);
static void clobber_variable_part (dataflow_set *, rtx,
decl_or_value, HOST_WIDE_INT, rtx);
-static void **delete_slot_part (dataflow_set *, rtx, void **, HOST_WIDE_INT);
+static variable_def **delete_slot_part (dataflow_set *, rtx, variable_def **,
+ HOST_WIDE_INT);
static void delete_variable_part (dataflow_set *, rtx,
decl_or_value, HOST_WIDE_INT);
-static int emit_note_insn_var_location (void **, void *);
-static void emit_notes_for_changes (rtx, enum emit_note_where, shared_hash);
-static int emit_notes_for_differences_1 (void **, void *);
-static int emit_notes_for_differences_2 (void **, void *);
-static void emit_notes_for_differences (rtx, dataflow_set *, dataflow_set *);
static void emit_notes_in_bb (basic_block, dataflow_set *);
static void vt_emit_notes (void);
@@ -1189,36 +1293,6 @@ adjust_insn (basic_block bb, rtx insn)
}
}
-/* Return true if a decl_or_value DV is a DECL or NULL. */
-static inline bool
-dv_is_decl_p (decl_or_value dv)
-{
- return !dv || (int) TREE_CODE ((tree) dv) != (int) VALUE;
-}
-
-/* Return true if a decl_or_value is a VALUE rtl. */
-static inline bool
-dv_is_value_p (decl_or_value dv)
-{
- return dv && !dv_is_decl_p (dv);
-}
-
-/* Return the decl in the decl_or_value. */
-static inline tree
-dv_as_decl (decl_or_value dv)
-{
- gcc_checking_assert (dv_is_decl_p (dv));
- return (tree) dv;
-}
-
-/* Return the value in the decl_or_value. */
-static inline rtx
-dv_as_value (decl_or_value dv)
-{
- gcc_checking_assert (dv_is_value_p (dv));
- return (rtx)dv;
-}
-
/* Return the DEBUG_EXPR of a DEBUG_EXPR_DECL or the VALUE in DV. */
static inline rtx
dv_as_rtx (decl_or_value dv)
@@ -1234,13 +1308,6 @@ dv_as_rtx (decl_or_value dv)
return DECL_RTL_KNOWN_SET (decl);
}
-/* Return the opaque pointer in the decl_or_value. */
-static inline void *
-dv_as_opaque (decl_or_value dv)
-{
- return dv;
-}
-
/* Return nonzero if a decl_or_value must not have more than one
variable part. The returned value discriminates among various
kinds of one-part DVs ccording to enum onepart_enum. */
@@ -1328,57 +1395,6 @@ debug_dv (decl_or_value dv)
debug_generic_stmt (dv_as_decl (dv));
}
-typedef unsigned int dvuid;
-
-/* Return the uid of DV. */
-
-static inline dvuid
-dv_uid (decl_or_value dv)
-{
- if (dv_is_value_p (dv))
- return CSELIB_VAL_PTR (dv_as_value (dv))->uid;
- else
- return DECL_UID (dv_as_decl (dv));
-}
-
-/* Compute the hash from the uid. */
-
-static inline hashval_t
-dv_uid2hash (dvuid uid)
-{
- return uid;
-}
-
-/* The hash function for a mask table in a shared_htab chain. */
-
-static inline hashval_t
-dv_htab_hash (decl_or_value dv)
-{
- return dv_uid2hash (dv_uid (dv));
-}
-
-/* The hash function for variable_htab, computes the hash value
- from the declaration of variable X. */
-
-static hashval_t
-variable_htab_hash (const void *x)
-{
- const_variable const v = (const_variable) x;
-
- return dv_htab_hash (v->dv);
-}
-
-/* Compare the declaration of variable X with declaration Y. */
-
-static int
-variable_htab_eq (const void *x, const void *y)
-{
- const_variable const v = (const_variable) x;
- decl_or_value dv = CONST_CAST2 (decl_or_value, const void *, y);
-
- return (dv_as_opaque (v->dv) == dv_as_opaque (dv));
-}
-
static void loc_exp_dep_clear (variable var);
/* Free the element of VARIABLE_HTAB (its type is struct variable_def). */
@@ -1535,7 +1551,7 @@ shared_hash_shared (shared_hash vars)
/* Return the hash table for VARS. */
-static inline htab_t
+static inline variable_table_type
shared_hash_htab (shared_hash vars)
{
return vars->htab;
@@ -1559,9 +1575,7 @@ shared_hash_unshare (shared_hash vars)
shared_hash new_vars = (shared_hash) pool_alloc (shared_hash_pool);
gcc_assert (vars->refcount > 1);
new_vars->refcount = 1;
- new_vars->htab
- = htab_create (htab_elements (vars->htab) + 3, variable_htab_hash,
- variable_htab_eq, variable_htab_free);
+ new_vars->htab.create (vars->htab.elements () + 3);
vars_copy (new_vars->htab, vars->htab);
vars->refcount--;
return new_vars;
@@ -1585,7 +1599,7 @@ shared_hash_destroy (shared_hash vars)
gcc_checking_assert (vars->refcount > 0);
if (--vars->refcount == 0)
{
- htab_delete (vars->htab);
+ vars->htab.dispose ();
pool_free (shared_hash_pool, vars);
}
}
@@ -1593,16 +1607,16 @@ shared_hash_destroy (shared_hash vars)
/* Unshare *PVARS if shared and return slot for DV. If INS is
INSERT, insert it if not already present. */
-static inline void **
+static inline variable_def **
shared_hash_find_slot_unshare_1 (shared_hash *pvars, decl_or_value dv,
hashval_t dvhash, enum insert_option ins)
{
if (shared_hash_shared (*pvars))
*pvars = shared_hash_unshare (*pvars);
- return htab_find_slot_with_hash (shared_hash_htab (*pvars), dv, dvhash, ins);
+ return shared_hash_htab (*pvars).find_slot_with_hash (dv, dvhash, ins);
}
-static inline void **
+static inline variable_def **
shared_hash_find_slot_unshare (shared_hash *pvars, decl_or_value dv,
enum insert_option ins)
{
@@ -1613,15 +1627,15 @@ shared_hash_find_slot_unshare (shared_ha
If it is not present, insert it only VARS is not shared, otherwise
return NULL. */
-static inline void **
+static inline variable_def **
shared_hash_find_slot_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
{
- return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
- shared_hash_shared (vars)
- ? NO_INSERT : INSERT);
+ return shared_hash_htab (vars).find_slot_with_hash (dv, dvhash,
+ shared_hash_shared (vars)
+ ? NO_INSERT : INSERT);
}
-static inline void **
+static inline variable_def **
shared_hash_find_slot (shared_hash vars, decl_or_value dv)
{
return shared_hash_find_slot_1 (vars, dv, dv_htab_hash (dv));
@@ -1629,15 +1643,14 @@ shared_hash_find_slot (shared_hash vars,
/* Return slot for DV only if it is already present in the hash table. */
-static inline void **
+static inline variable_def **
shared_hash_find_slot_noinsert_1 (shared_hash vars, decl_or_value dv,
hashval_t dvhash)
{
- return htab_find_slot_with_hash (shared_hash_htab (vars), dv, dvhash,
- NO_INSERT);
+ return shared_hash_htab (vars).find_slot_with_hash (dv, dvhash, NO_INSERT);
}
-static inline void **
+static inline variable_def **
shared_hash_find_slot_noinsert (shared_hash vars, decl_or_value dv)
{
return shared_hash_find_slot_noinsert_1 (vars, dv, dv_htab_hash (dv));
@@ -1649,7 +1662,7 @@ shared_hash_find_slot_noinsert (shared_h
static inline variable
shared_hash_find_1 (shared_hash vars, decl_or_value dv, hashval_t dvhash)
{
- return (variable) htab_find_with_hash (shared_hash_htab (vars), dv, dvhash);
+ return shared_hash_htab (vars).find_with_hash (dv, dvhash);
}
static inline variable
@@ -1678,8 +1691,8 @@ static bool dst_can_be_shared;
/* Return a copy of a variable VAR and insert it to dataflow set SET. */
-static void **
-unshare_variable (dataflow_set *set, void **slot, variable var,
+static variable_def **
+unshare_variable (dataflow_set *set, variable_def **slot, variable var,
enum var_init_status initialized)
{
variable new_var;
@@ -1745,8 +1758,8 @@ unshare_variable (dataflow_set *set, voi
*slot = new_var;
if (var->in_changed_variables)
{
- void **cslot
- = htab_find_slot_with_hash (changed_variables, var->dv,
+ variable_def **cslot
+ = changed_variables.find_slot_with_hash (var->dv,
dv_htab_hash (var->dv), NO_INSERT);
gcc_assert (*cslot == (void *) var);
var->in_changed_variables = false;
@@ -1760,18 +1773,16 @@ unshare_variable (dataflow_set *set, voi
/* Copy all variables from hash table SRC to hash table DST. */
static void
-vars_copy (htab_t dst, htab_t src)
+vars_copy (variable_table_type dst, variable_table_type src)
{
- htab_iterator hi;
+ variable_iterator_type hi;
variable var;
- FOR_EACH_HTAB_ELEMENT (src, var, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (src, var, variable, hi)
{
- void **dstp;
+ variable_def **dstp;
var->refcount++;
- dstp = htab_find_slot_with_hash (dst, var->dv,
- dv_htab_hash (var->dv),
- INSERT);
+ dstp = dst.find_slot_with_hash (var->dv, dv_htab_hash (var->dv), INSERT);
*dstp = var;
}
}
@@ -2015,8 +2026,7 @@ vt_canonicalize_addr (dataflow_set *set,
}
dv = dv_from_rtx (x);
- var = (variable) htab_find_with_hash (shared_hash_htab (set->vars),
- dv, dv_htab_hash (dv));
+ var = shared_hash_htab (set->vars).find_with_hash (dv,
dv_htab_hash (dv));
if (!var)
break;
@@ -2101,13 +2111,12 @@ struct overlapping_mems
canonicalized form of COMS->LOC's address, and COMS->LOC must be
canonicalized itself. */
-static int
-drop_overlapping_mem_locs (void **slot, void *data)
+int
+drop_overlapping_mem_locs (variable_def **slot, overlapping_mems *coms)
{
- struct overlapping_mems *coms = (struct overlapping_mems *)data;
dataflow_set *set = coms->set;
rtx mloc = coms->loc, addr = coms->addr;
- variable var = (variable) *slot;
+ variable var = *slot;
if (var->onepart == ONEPART_VALUE)
{
@@ -2127,7 +2136,7 @@ drop_overlapping_mem_locs (void **slot,
return 1;
slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
- var = (variable)*slot;
+ var = *slot;
gcc_assert (var->n_var_parts == 1);
}
@@ -2183,8 +2192,8 @@ clobber_overlapping_mems (dataflow_set *
coms.addr = vt_canonicalize_addr (set, XEXP (loc, 0));
set->traversed_vars = set->vars;
- htab_traverse (shared_hash_htab (set->vars),
- drop_overlapping_mem_locs, &coms);
+ shared_hash_htab (set->vars)
+ .traverse <overlapping_mems*, drop_overlapping_mem_locs> (&coms);
set->traversed_vars = NULL;
}
@@ -2569,7 +2578,7 @@ static int
variable_union (variable src, dataflow_set *set)
{
variable dst;
- void **dstp;
+ variable_def **dstp;
int i, j, k;
dstp = shared_hash_find_slot (set->vars, src->dv);
@@ -2587,7 +2596,7 @@ variable_union (variable src, dataflow_s
return 1;
}
else
- dst = (variable) *dstp;
+ dst = *dstp;
gcc_assert (src->n_var_parts);
gcc_checking_assert (src->onepart == dst->onepart);
@@ -2621,7 +2630,7 @@ variable_union (variable src, dataflow_s
{
dstp = unshare_variable (set, dstp, dst,
VAR_INIT_STATUS_INITIALIZED);
- dst = (variable)*dstp;
+ dst = *dstp;
goto restart_onepart_unshared;
}
@@ -2674,7 +2683,7 @@ variable_union (variable src, dataflow_s
if (dst->n_var_parts != k && shared_var_p (dst, set->vars))
{
dstp = unshare_variable (set, dstp, dst, VAR_INIT_STATUS_UNKNOWN);
- dst = (variable)*dstp;
+ dst = *dstp;
}
i = src->n_var_parts - 1;
@@ -2949,10 +2958,11 @@ dataflow_set_union (dataflow_set *dst, d
}
else
{
- htab_iterator hi;
+ variable_iterator_type hi;
variable var;
- FOR_EACH_HTAB_ELEMENT (shared_hash_htab (src->vars), var, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (src->vars),
+ var, variable, hi)
variable_union (var, dst);
}
}
@@ -3015,7 +3025,7 @@ dv_changed_p (decl_or_value dv)
be in star-canonical form. */
static location_chain
-find_loc_in_1pdv (rtx loc, variable var, htab_t vars)
+find_loc_in_1pdv (rtx loc, variable var, variable_table_type vars)
{
location_chain node;
enum rtx_code loc_code;
@@ -3072,7 +3082,7 @@ find_loc_in_1pdv (rtx loc, variable var,
gcc_checking_assert (!node->next);
dv = dv_from_value (node->loc);
- rvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ rvar = vars.find_with_hash (dv, dv_htab_hash (dv));
return find_loc_in_1pdv (loc, rvar, vars);
}
@@ -3388,10 +3398,11 @@ loc_cmp (rtx x, rtx y)
#if ENABLE_CHECKING
/* Check the order of entries in one-part variables. */
-static int
-canonicalize_loc_order_check (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+canonicalize_loc_order_check (variable_def **slot,
+ dataflow_set *data ATTRIBUTE_UNUSED)
{
- variable var = (variable) *slot;
+ variable var = *slot;
location_chain node, next;
#ifdef ENABLE_RTL_CHECKING
@@ -3423,11 +3434,10 @@ canonicalize_loc_order_check (void **slo
Ensure less likely values can reach more likely neighbors, making
the connections bidirectional. */
-static int
-canonicalize_values_mark (void **slot, void *data)
+int
+canonicalize_values_mark (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *)data;
- variable var = (variable) *slot;
+ variable var = *slot;
decl_or_value dv = var->dv;
rtx val;
location_chain node;
@@ -3447,7 +3457,8 @@ canonicalize_values_mark (void **slot, v
else
{
decl_or_value odv = dv_from_value (node->loc);
- void **oslot = shared_hash_find_slot_noinsert (set->vars, odv);
+ variable_def **oslot;
+ oslot = shared_hash_find_slot_noinsert (set->vars, odv);
set_slot_part (set, val, oslot, odv, 0,
node->init, NULL_RTX);
@@ -3462,16 +3473,15 @@ canonicalize_values_mark (void **slot, v
/* Remove redundant entries from equivalence lists in onepart
variables, canonicalizing equivalence sets into star shapes. */
-static int
-canonicalize_values_star (void **slot, void *data)
+int
+canonicalize_values_star (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *)data;
- variable var = (variable) *slot;
+ variable var = *slot;
decl_or_value dv = var->dv;
location_chain node;
decl_or_value cdv;
rtx val, cval;
- void **cslot;
+ variable_def **cslot;
bool has_value;
bool has_marks;
@@ -3537,7 +3547,7 @@ canonicalize_values_star (void **slot, v
clobber_variable_part (set, NULL, var->dv, 0, NULL);
return 1;
}
- var = (variable)*slot;
+ var = *slot;
gcc_assert (dv_is_value_p (var->dv));
if (var->n_var_parts == 0)
return 1;
@@ -3667,7 +3677,7 @@ canonicalize_values_star (void **slot, v
slot = clobber_slot_part (set, cval, slot, 0, NULL);
/* Variable may have been unshared. */
- var = (variable)*slot;
+ var = *slot;
gcc_checking_assert (var->n_var_parts &&
var->var_part[0].loc_chain->loc == cval
&& var->var_part[0].loc_chain->next == NULL);
@@ -3684,16 +3694,15 @@ canonicalize_values_star (void **slot, v
have determined or even seen the canonical value of a set when we
get to a variable that references another member of the set. */
-static int
-canonicalize_vars_star (void **slot, void *data)
+int
+canonicalize_vars_star (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *)data;
- variable var = (variable) *slot;
+ variable var = *slot;
decl_or_value dv = var->dv;
location_chain node;
rtx cval;
decl_or_value cdv;
- void **cslot;
+ variable_def **cslot;
variable cvar;
location_chain cnode;
@@ -3715,7 +3724,7 @@ canonicalize_vars_star (void **slot, voi
cslot = shared_hash_find_slot_noinsert (set->vars, cdv);
if (!cslot)
return 1;
- cvar = (variable)*cslot;
+ cvar = *cslot;
gcc_assert (cvar->n_var_parts == 1);
cnode = cvar->var_part[0].loc_chain;
@@ -3747,7 +3756,7 @@ static int
variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
{
dataflow_set *dst = dsm->dst;
- void **dstslot;
+ variable_def **dstslot;
variable s2var, dvar = NULL;
decl_or_value dv = s1var->dv;
onepart_enum_t onepart = s1var->onepart;
@@ -3787,7 +3796,7 @@ variable_merge_over_cur (variable s1var,
dstslot = shared_hash_find_slot_noinsert_1 (dst->vars, dv, dvhash);
if (dstslot)
{
- dvar = (variable)*dstslot;
+ dvar = *dstslot;
gcc_assert (dvar->refcount == 1
&& dvar->onepart == onepart
&& dvar->n_var_parts == 1);
@@ -3885,8 +3894,8 @@ variable_merge_over_cur (variable s1var,
nodep = nextp;
}
- if (dvar != (variable)*dstslot)
- dvar = (variable)*dstslot;
+ if (dvar != *dstslot)
+ dvar = *dstslot;
nodep = &dvar->var_part[0].loc_chain;
if (val)
@@ -3908,7 +3917,7 @@ variable_merge_over_cur (variable s1var,
gcc_checking_assert (dstslot
== shared_hash_find_slot_noinsert_1 (dst->vars,
dv, dvhash));
- dvar = (variable)*dstslot;
+ dvar = *dstslot;
}
else
{
@@ -3944,7 +3953,7 @@ variable_merge_over_cur (variable s1var,
if (GET_CODE (node->loc) == VALUE)
{
decl_or_value dv = dv_from_value (node->loc);
- void **slot = NULL;
+ variable_def **slot = NULL;
if (shared_hash_shared (dst->vars))
slot = shared_hash_find_slot_noinsert (dst->vars, dv);
@@ -3976,7 +3985,7 @@ variable_merge_over_cur (variable s1var,
gcc_checking_assert (dstslot
== shared_hash_find_slot_noinsert_1 (dst->vars,
dv, dvhash));
- dvar = (variable)*dstslot;
+ dvar = *dstslot;
}
}
@@ -4012,7 +4021,7 @@ variable_merge_over_src (variable s2var,
if (!s2var->onepart)
{
- void **dstp = shared_hash_find_slot (dst->vars, dv);
+ variable_def **dstp = shared_hash_find_slot (dst->vars, dv);
*dstp = s2var;
s2var->refcount++;
return 1;
@@ -4033,19 +4042,17 @@ dataflow_set_merge (dataflow_set *dst, d
struct dfset_merge dsm;
int i;
size_t src1_elems, src2_elems;
- htab_iterator hi;
+ variable_iterator_type hi;
variable var;
- src1_elems = htab_elements (shared_hash_htab (src1->vars));
- src2_elems = htab_elements (shared_hash_htab (src2->vars));
+ src1_elems = shared_hash_htab (src1->vars).elements ();
+ src2_elems = shared_hash_htab (src2->vars).elements ();
dataflow_set_init (dst);
dst->stack_adjust = cur.stack_adjust;
shared_hash_destroy (dst->vars);
dst->vars = (shared_hash) pool_alloc (shared_hash_pool);
dst->vars->refcount = 1;
- dst->vars->htab
- = htab_create (MAX (src1_elems, src2_elems), variable_htab_hash,
- variable_htab_eq, variable_htab_free);
+ dst->vars->htab.create (MAX (src1_elems, src2_elems));
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
attrs_list_mpdv_union (&dst->regs[i], src1->regs[i], src2->regs[i]);
@@ -4055,9 +4062,11 @@ dataflow_set_merge (dataflow_set *dst, d
dsm.cur = src1;
dsm.src_onepart_cnt = 0;
- FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.src->vars), var, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (dsm.src->vars),
+ var, variable, hi)
variable_merge_over_src (var, &dsm);
- FOR_EACH_HTAB_ELEMENT (shared_hash_htab (dsm.cur->vars), var, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (dsm.cur->vars),
+ var, variable, hi)
variable_merge_over_cur (var, &dsm);
if (dsm.src_onepart_cnt)
@@ -4127,7 +4136,7 @@ dataflow_set_equiv_regs (dataflow_set *s
if (list->offset == 0 && dv_onepart_p (list->dv))
{
rtx cval = canon[(int)GET_MODE (list->loc)];
- void **slot;
+ variable_def **slot;
if (!cval)
continue;
@@ -4198,12 +4207,11 @@ struct dfset_post_merge
/* Create values for incoming expressions associated with one-part
variables that don't have value numbers for them. */
-static int
-variable_post_merge_new_vals (void **slot, void *info)
+int
+variable_post_merge_new_vals (variable_def **slot, dfset_post_merge *dfpm)
{
- struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
dataflow_set *set = dfpm->set;
- variable var = (variable)*slot;
+ variable var = *slot;
location_chain node;
if (!var->onepart || !var->n_var_parts)
@@ -4228,7 +4236,7 @@ variable_post_merge_new_vals (void **slo
{
slot = unshare_variable (set, slot, var,
VAR_INIT_STATUS_INITIALIZED);
- var = (variable)*slot;
+ var = *slot;
goto restart;
}
@@ -4335,12 +4343,11 @@ variable_post_merge_new_vals (void **slo
/* Reset values in the permanent set that are not associated with the
chosen expression. */
-static int
-variable_post_merge_perm_vals (void **pslot, void *info)
+int
+variable_post_merge_perm_vals (variable_def **pslot, dfset_post_merge *dfpm)
{
- struct dfset_post_merge *dfpm = (struct dfset_post_merge *)info;
dataflow_set *set = dfpm->set;
- variable pvar = (variable)*pslot, var;
+ variable pvar = *pslot, var;
location_chain pnode;
decl_or_value dv;
attrs att;
@@ -4404,13 +4411,15 @@ dataflow_post_merge_adjust (dataflow_set
dfpm.set = set;
dfpm.permp = permp;
- htab_traverse (shared_hash_htab (set->vars), variable_post_merge_new_vals,
- &dfpm);
+ shared_hash_htab (set->vars)
+ .traverse <dfset_post_merge*, variable_post_merge_new_vals> (&dfpm);
if (*permp)
- htab_traverse (shared_hash_htab ((*permp)->vars),
- variable_post_merge_perm_vals, &dfpm);
- htab_traverse (shared_hash_htab (set->vars), canonicalize_values_star, set);
- htab_traverse (shared_hash_htab (set->vars), canonicalize_vars_star, set);
+ shared_hash_htab ((*permp)->vars)
+ .traverse <dfset_post_merge*, variable_post_merge_perm_vals> (&dfpm);
+ shared_hash_htab (set->vars)
+ .traverse <dataflow_set *, canonicalize_values_star> (set);
+ shared_hash_htab (set->vars)
+ .traverse <dataflow_set *, canonicalize_vars_star> (set);
}
/* Return a node whose loc is a MEM that refers to EXPR in the
@@ -4418,7 +4427,7 @@ dataflow_post_merge_adjust (dataflow_set
any values recursively mentioned in the location lists. */
static location_chain
-find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
+find_mem_expr_in_1pdv (tree expr, rtx val, variable_table_type vars)
{
location_chain node;
decl_or_value dv;
@@ -4432,7 +4441,7 @@ find_mem_expr_in_1pdv (tree expr, rtx va
&& !VALUE_RECURSED_INTO (val));
dv = dv_from_value (val);
- var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ var = vars.find_with_hash (dv, dv_htab_hash (dv));
if (!var)
return NULL;
@@ -4489,11 +4498,10 @@ mem_dies_at_call (rtx mem)
one-part variable, except those whose MEM attributes map back to
the variable itself, directly or within a VALUE. */
-static int
-dataflow_set_preserve_mem_locs (void **slot, void *data)
+int
+dataflow_set_preserve_mem_locs (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *) data;
- variable var = (variable) *slot;
+ variable var = *slot;
if (var->onepart == ONEPART_VDECL || var->onepart == ONEPART_DEXPR)
{
@@ -4527,7 +4535,7 @@ dataflow_set_preserve_mem_locs (void **s
return 1;
slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
- var = (variable)*slot;
+ var = *slot;
gcc_assert (var->n_var_parts == 1);
}
@@ -4599,11 +4607,10 @@ dataflow_set_preserve_mem_locs (void **s
/* Remove all MEMs from the location list of a hash table entry for a
value. */
-static int
-dataflow_set_remove_mem_locs (void **slot, void *data)
+int
+dataflow_set_remove_mem_locs (variable_def **slot, dataflow_set *set)
{
- dataflow_set *set = (dataflow_set *) data;
- variable var = (variable) *slot;
+ variable var = *slot;
if (var->onepart == ONEPART_VALUE)
{
@@ -4624,7 +4631,7 @@ dataflow_set_remove_mem_locs (void **slo
return 1;
slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
- var = (variable)*slot;
+ var = *slot;
gcc_assert (var->n_var_parts == 1);
}
@@ -4684,11 +4691,11 @@ dataflow_set_clear_at_call (dataflow_set
if (MAY_HAVE_DEBUG_INSNS)
{
set->traversed_vars = set->vars;
- htab_traverse (shared_hash_htab (set->vars),
- dataflow_set_preserve_mem_locs, set);
+ shared_hash_htab (set->vars)
+ .traverse <dataflow_set *, dataflow_set_preserve_mem_locs> (set);
set->traversed_vars = set->vars;
- htab_traverse (shared_hash_htab (set->vars),
dataflow_set_remove_mem_locs,
- set);
+ shared_hash_htab (set->vars)
+ .traverse <dataflow_set *, dataflow_set_remove_mem_locs> (set);
set->traversed_vars = NULL;
}
}
@@ -4787,21 +4794,21 @@ variable_different_p (variable var1, var
static bool
dataflow_set_different (dataflow_set *old_set, dataflow_set *new_set)
{
- htab_iterator hi;
+ variable_iterator_type hi;
variable var1;
if (old_set->vars == new_set->vars)
return false;
- if (htab_elements (shared_hash_htab (old_set->vars))
- != htab_elements (shared_hash_htab (new_set->vars)))
+ if (shared_hash_htab (old_set->vars).elements ()
+ != shared_hash_htab (new_set->vars).elements ())
return true;
- FOR_EACH_HTAB_ELEMENT (shared_hash_htab (old_set->vars), var1, variable, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (shared_hash_htab (old_set->vars),
+ var1, variable, hi)
{
- htab_t htab = shared_hash_htab (new_set->vars);
- variable var2 = (variable) htab_find_with_hash (htab, var1->dv,
- dv_htab_hash (var1->dv));
+ variable_table_type htab = shared_hash_htab (new_set->vars);
+ variable var2 = htab.find_with_hash (var1->dv, dv_htab_hash (var1->dv));
if (!var2)
{
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -6698,13 +6705,13 @@ compute_bb_dataflow (basic_block bb)
if (MAY_HAVE_DEBUG_INSNS)
{
dataflow_set_equiv_regs (out);
- htab_traverse (shared_hash_htab (out->vars), canonicalize_values_mark,
- out);
- htab_traverse (shared_hash_htab (out->vars), canonicalize_values_star,
- out);
+ shared_hash_htab (out->vars)
+ .traverse <dataflow_set *, canonicalize_values_mark> (out);
+ shared_hash_htab (out->vars)
+ .traverse <dataflow_set *, canonicalize_values_star> (out);
#if ENABLE_CHECKING
- htab_traverse (shared_hash_htab (out->vars),
- canonicalize_loc_order_check, out);
+ shared_hash_htab (out->vars)
+ .traverse <dataflow_set *, canonicalize_loc_order_check> (out);
#endif
}
changed = dataflow_set_different (&old_out, out);
@@ -6776,12 +6783,10 @@ vt_find_locations (void)
if (VTI (bb)->in.vars)
{
htabsz
- -= (htab_size (shared_hash_htab (VTI (bb)->in.vars))
- + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
- oldinsz
- = htab_elements (shared_hash_htab (VTI (bb)->in.vars));
- oldoutsz
- = htab_elements (shared_hash_htab (VTI (bb)->out.vars));
+ -= shared_hash_htab (VTI (bb)->in.vars).size ()
+ + shared_hash_htab (VTI (bb)->out.vars).size ();
+ oldinsz = shared_hash_htab (VTI (bb)->in.vars).elements ();
+ oldoutsz = shared_hash_htab (VTI (bb)->out.vars).elements ();
}
else
oldinsz = oldoutsz = 0;
@@ -6819,9 +6824,9 @@ vt_find_locations (void)
#if ENABLE_CHECKING
/* Merge and merge_adjust should keep entries in
canonical order. */
- htab_traverse (shared_hash_htab (in->vars),
- canonicalize_loc_order_check,
- in);
+ shared_hash_htab (in->vars)
+ .traverse <dataflow_set *,
+ canonicalize_loc_order_check> (in);
#endif
if (dst_can_be_shared)
{
@@ -6841,8 +6846,8 @@ vt_find_locations (void)
}
changed = compute_bb_dataflow (bb);
- htabsz += (htab_size (shared_hash_htab (VTI (bb)->in.vars))
- + htab_size (shared_hash_htab (VTI (bb)->out.vars)));
+ htabsz += shared_hash_htab (VTI (bb)->in.vars).size ()
+ + shared_hash_htab (VTI (bb)->out.vars).size ();
if (htabmax && htabsz > htabmax)
{
@@ -6889,9 +6894,9 @@ vt_find_locations (void)
fprintf (dump_file,
"BB %i: in %i (was %i), out %i (was %i), rem %i + %i, tsz %i\n",
bb->index,
- (int)htab_elements (shared_hash_htab (VTI (bb)->in.vars)),
+ (int)shared_hash_htab (VTI (bb)->in.vars).size (),
oldinsz,
- (int)htab_elements (shared_hash_htab (VTI (bb)->out.vars)),
+ (int)shared_hash_htab (VTI (bb)->out.vars).size (),
oldoutsz,
(int)worklist->nodes, (int)pending->nodes, htabsz);
@@ -6939,10 +6944,10 @@ dump_attrs_list (attrs list)
/* Print the information about variable *SLOT to dump file. */
-static int
-dump_var_slot (void **slot, void *data ATTRIBUTE_UNUSED)
+int
+dump_var_tracking_slot (variable_def **slot, void *data ATTRIBUTE_UNUSED)
{
- variable var = (variable) *slot;
+ variable var = *slot;
dump_var (var);
@@ -6998,12 +7003,12 @@ dump_var (variable var)
/* Print the information about variables from hash table VARS to dump file. */
static void
-dump_vars (htab_t vars)
+dump_vars (variable_table_type vars)
{
- if (htab_elements (vars) > 0)
+ if (vars.elements () > 0)
{
fprintf (dump_file, "Variables:\n");
- htab_traverse (vars, dump_var_slot, NULL);
+ vars.traverse <void *, dump_var_tracking_slot> (NULL);
}
}
@@ -7051,18 +7056,17 @@ dump_dataflow_sets (void)
static inline variable
variable_from_dropped (decl_or_value dv, enum insert_option insert)
{
- void **slot;
+ variable_def **slot;
variable empty_var;
onepart_enum_t onepart;
- slot = htab_find_slot_with_hash (dropped_values, dv, dv_htab_hash (dv),
- insert);
+ slot = dropped_values.find_slot_with_hash (dv, dv_htab_hash (dv), insert);
if (!slot)
return NULL;
if (*slot)
- return (variable) *slot;
+ return *slot;
gcc_checking_assert (insert == INSERT);
@@ -7122,18 +7126,16 @@ variable_was_changed (variable var, data
if (emit_notes)
{
- void **slot;
+ variable_def **slot;
/* Remember this decl or VALUE has been added to changed_variables. */
set_dv_changed (var->dv, true);
- slot = htab_find_slot_with_hash (changed_variables,
- var->dv,
- hash, INSERT);
+ slot = changed_variables.find_slot_with_hash (var->dv, hash, INSERT);
if (*slot)
{
- variable old_var = (variable) *slot;
+ variable old_var = *slot;
gcc_assert (old_var->in_changed_variables);
old_var->in_changed_variables = false;
if (var != old_var && var->onepart)
@@ -7152,14 +7154,14 @@ variable_was_changed (variable var, data
{
onepart_enum_t onepart = var->onepart;
variable empty_var = NULL;
- void **dslot = NULL;
+ variable_def **dslot = NULL;
if (onepart == ONEPART_VALUE || onepart == ONEPART_DEXPR)
{
- dslot = htab_find_slot_with_hash (dropped_values, var->dv,
+ dslot = dropped_values.find_slot_with_hash (var->dv,
dv_htab_hash (var->dv),
INSERT);
- empty_var = (variable) *dslot;
+ empty_var = *dslot;
if (empty_var)
{
@@ -7214,7 +7216,7 @@ variable_was_changed (variable var, data
gcc_assert (set);
if (var->n_var_parts == 0)
{
- void **slot;
+ variable_def **slot;
drop_var:
slot = shared_hash_find_slot_noinsert (set->vars, var->dv);
@@ -7223,7 +7225,7 @@ variable_was_changed (variable var, data
if (shared_hash_shared (set->vars))
slot = shared_hash_find_slot_unshare (&set->vars, var->dv,
NO_INSERT);
- htab_clear_slot (shared_hash_htab (set->vars), slot);
+ shared_hash_htab (set->vars).clear_slot (slot);
}
}
}
@@ -7273,8 +7275,8 @@ find_variable_location_part (variable va
return -1;
}
-static void **
-set_slot_part (dataflow_set *set, rtx loc, void **slot,
+static variable_def **
+set_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
decl_or_value dv, HOST_WIDE_INT offset,
enum var_init_status initialized, rtx set_src)
{
@@ -7284,7 +7286,7 @@ set_slot_part (dataflow_set *set, rtx lo
variable var;
onepart_enum_t onepart;
- var = (variable) *slot;
+ var = *slot;
if (var)
onepart = var->onepart;
@@ -7407,7 +7409,7 @@ set_slot_part (dataflow_set *set, rtx lo
if (shared_var_p (var, set->vars))
{
slot = unshare_variable (set, slot, var, initialized);
- var = (variable)*slot;
+ var = *slot;
for (nextp = &var->var_part[0].loc_chain; c;
nextp = &(*nextp)->next)
c--;
@@ -7446,7 +7448,7 @@ set_slot_part (dataflow_set *set, rtx lo
if (shared_var_p (var, set->vars))
{
slot = unshare_variable (set, slot, var, initialized);
- var = (variable)*slot;
+ var = *slot;
}
}
}
@@ -7458,7 +7460,7 @@ set_slot_part (dataflow_set *set, rtx lo
if (shared_var_p (var, set->vars))
{
slot = unshare_variable (set, slot, var, initialized);
- var = (variable)*slot;
+ var = *slot;
}
/* We track only variables whose size is <= MAX_VAR_PARTS bytes
@@ -7533,7 +7535,7 @@ set_variable_part (dataflow_set *set, rt
enum var_init_status initialized, rtx set_src,
enum insert_option iopt)
{
- void **slot;
+ variable_def **slot;
if (iopt == NO_INSERT)
slot = shared_hash_find_slot_noinsert (set->vars, dv);
@@ -7551,11 +7553,11 @@ set_variable_part (dataflow_set *set, rt
The variable part is specified by variable's declaration or value
DV and offset OFFSET. */
-static void **
-clobber_slot_part (dataflow_set *set, rtx loc, void **slot,
+static variable_def **
+clobber_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
HOST_WIDE_INT offset, rtx set_src)
{
- variable var = (variable) *slot;
+ variable var = *slot;
int pos = find_variable_location_part (var, offset, NULL);
if (pos >= 0)
@@ -7614,7 +7616,7 @@ static void
clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
HOST_WIDE_INT offset, rtx set_src)
{
- void **slot;
+ variable_def **slot;
if (!dv_as_opaque (dv)
|| (!dv_is_value_p (dv) && ! DECL_P (dv_as_decl (dv))))
@@ -7631,11 +7633,11 @@ clobber_variable_part (dataflow_set *set
variable part is specified by its SET->vars slot SLOT and offset
OFFSET and the part's location by LOC. */
-static void **
-delete_slot_part (dataflow_set *set, rtx loc, void **slot,
+static variable_def **
+delete_slot_part (dataflow_set *set, rtx loc, variable_def **slot,
HOST_WIDE_INT offset)
{
- variable var = (variable) *slot;
+ variable var = *slot;
int pos = find_variable_location_part (var, offset, NULL);
if (pos >= 0)
@@ -7658,7 +7660,7 @@ delete_slot_part (dataflow_set *set, rtx
{
slot = unshare_variable (set, slot, var,
VAR_INIT_STATUS_UNKNOWN);
- var = (variable)*slot;
+ var = *slot;
break;
}
}
@@ -7722,7 +7724,7 @@ static void
delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
HOST_WIDE_INT offset)
{
- void **slot = shared_hash_find_slot_noinsert (set->vars, dv);
+ variable_def **slot = shared_hash_find_slot_noinsert (set->vars, dv);
if (!slot)
return;
@@ -7735,7 +7737,7 @@ delete_variable_part (dataflow_set *set,
struct expand_loc_callback_data
{
/* The variables and values active at this point. */
- htab_t vars;
+ variable_table_type vars;
/* Stack of values and debug_exprs under expansion, and their
children. */
@@ -7824,7 +7826,7 @@ loc_exp_dep_clear (variable var)
back-links in VARS. */
static void
-loc_exp_insert_dep (variable var, rtx x, htab_t vars)
+loc_exp_insert_dep (variable var, rtx x, variable_table_type vars)
{
decl_or_value dv;
variable xvar;
@@ -7834,7 +7836,7 @@ loc_exp_insert_dep (variable var, rtx x,
/* ??? Build a vector of variables parallel to EXPANDING, to avoid
an additional look up? */
- xvar = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ xvar = vars.find_with_hash (dv, dv_htab_hash (dv));
if (!xvar)
{
@@ -7874,7 +7876,8 @@ loc_exp_insert_dep (variable var, rtx x,
true if we found any pending-recursion results. */
static bool
-loc_exp_dep_set (variable var, rtx result, rtx *value, int count, htab_t vars)
+loc_exp_dep_set (variable var, rtx result, rtx *value, int count,
+ variable_table_type vars)
{
bool pending_recursion = false;
@@ -7903,7 +7906,7 @@ loc_exp_dep_set (variable var, rtx resul
attempt to compute a current location. */
static void
-notify_dependents_of_resolved_value (variable ivar, htab_t vars)
+notify_dependents_of_resolved_value (variable ivar, variable_table_type vars)
{
loc_exp_dep *led, *next;
@@ -7941,7 +7944,7 @@ notify_dependents_of_resolved_value (var
continue;
}
- var = (variable) htab_find_with_hash (vars, dv, dv_htab_hash (dv));
+ var = vars.find_with_hash (dv, dv_htab_hash (dv));
if (!var)
var = variable_from_dropped (dv, NO_INSERT);
@@ -8185,7 +8188,7 @@ vt_expand_loc_callback (rtx x, bitmap re
return NULL;
}
- var = (variable) htab_find_with_hash (elcd->vars, dv, dv_htab_hash (dv));
+ var = elcd->vars.find_with_hash (dv, dv_htab_hash (dv));
if (!var)
{
@@ -8294,7 +8297,7 @@ resolve_expansions_pending_recursion (ve
equivalences in VARS, updating their CUR_LOCs in the process. */
static rtx
-vt_expand_loc (rtx loc, htab_t vars)
+vt_expand_loc (rtx loc, variable_table_type vars)
{
struct expand_loc_callback_data data;
rtx result;
@@ -8316,7 +8319,7 @@ vt_expand_loc (rtx loc, htab_t vars)
in VARS, updating their CUR_LOCs in the process. */
static rtx
-vt_expand_1pvar (variable var, htab_t vars)
+vt_expand_1pvar (variable var, variable_table_type vars)
{
struct expand_loc_callback_data data;
rtx loc;
@@ -8341,13 +8344,13 @@ vt_expand_1pvar (variable var, htab_t va
additional parameters: WHERE specifies whether the note shall be emitted
before or after instruction INSN. */
-static int
-emit_note_insn_var_location (void **varp, void *data)
+int
+emit_note_insn_var_location (variable_def **varp, emit_note_data *data)
{
- variable var = (variable) *varp;
- rtx insn = ((emit_note_data *)data)->insn;
- enum emit_note_where where = ((emit_note_data *)data)->where;
- htab_t vars = ((emit_note_data *)data)->vars;
+ variable var = *varp;
+ rtx insn = data->insn;
+ enum emit_note_where where = data->where;
+ variable_table_type vars = data->vars;
rtx note, note_vl;
int i, j, n_var_parts;
bool complete;
@@ -8585,7 +8588,7 @@ emit_note_insn_var_location (void **varp
set_dv_changed (var->dv, false);
gcc_assert (var->in_changed_variables);
var->in_changed_variables = false;
- htab_clear_slot (changed_variables, varp);
+ changed_variables.clear_slot (varp);
/* Continue traversing the hash table. */
return 1;
@@ -8594,11 +8597,11 @@ emit_note_insn_var_location (void **varp
/* While traversing changed_variables, push onto DATA (a stack of RTX
values) entries that aren't user variables. */
-static int
-values_to_stack (void **slot, void *data)
+int
+var_track_values_to_stack (variable_def **slot,
+ vec<rtx, va_stack> *changed_values_stack)
{
- vec<rtx, va_stack> *changed_values_stack = (vec<rtx, va_stack> *) data;
- variable var = (variable) *slot;
+ variable var = *slot;
if (var->onepart == ONEPART_VALUE)
changed_values_stack->safe_push (dv_as_value (var->dv));
@@ -8614,14 +8617,14 @@ static void
remove_value_from_changed_variables (rtx val)
{
decl_or_value dv = dv_from_rtx (val);
- void **slot;
+ variable_def **slot;
variable var;
- slot = htab_find_slot_with_hash (changed_variables,
- dv, dv_htab_hash (dv), NO_INSERT);
- var = (variable) *slot;
+ slot = changed_variables.find_slot_with_hash (dv, dv_htab_hash (dv),
+ NO_INSERT);
+ var = *slot;
var->in_changed_variables = false;
- htab_clear_slot (changed_variables, slot);
+ changed_variables.clear_slot (slot);
}
/* If VAL (a value or debug_expr) has backlinks to variables actively
@@ -8630,23 +8633,22 @@ remove_value_from_changed_variables (rtx
have dependencies of their own to notify. */
static void
-notify_dependents_of_changed_value (rtx val, htab_t htab,
+notify_dependents_of_changed_value (rtx val, variable_table_type htab,
vec<rtx, va_stack> *changed_values_stack)
{
- void **slot;
+ variable_def **slot;
variable var;
loc_exp_dep *led;
decl_or_value dv = dv_from_rtx (val);
- slot = htab_find_slot_with_hash (changed_variables,
- dv, dv_htab_hash (dv), NO_INSERT);
+ slot = changed_variables.find_slot_with_hash (dv, dv_htab_hash (dv),
+ NO_INSERT);
if (!slot)
- slot = htab_find_slot_with_hash (htab,
- dv, dv_htab_hash (dv), NO_INSERT);
+ slot = htab.find_slot_with_hash (dv, dv_htab_hash (dv), NO_INSERT);
if (!slot)
- slot = htab_find_slot_with_hash (dropped_values,
- dv, dv_htab_hash (dv), NO_INSERT);
- var = (variable) *slot;
+ slot = dropped_values.find_slot_with_hash (dv, dv_htab_hash (dv),
+ NO_INSERT);
+ var = *slot;
while ((led = VAR_LOC_DEP_LST (var)))
{
@@ -8676,14 +8678,14 @@ notify_dependents_of_changed_value (rtx
break;
case ONEPART_VDECL:
- ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv));
+ ivar = htab.find_with_hash (ldv, dv_htab_hash (ldv));
gcc_checking_assert (!VAR_LOC_DEP_LST (ivar));
variable_was_changed (ivar, NULL);
break;
case NOT_ONEPART:
pool_free (loc_exp_dep_pool, led);
- ivar = (variable) htab_find_with_hash (htab, ldv, dv_htab_hash (ldv));
+ ivar = htab.find_with_hash (ldv, dv_htab_hash (ldv));
if (ivar)
{
int i = ivar->n_var_parts;
@@ -8713,7 +8715,7 @@ notify_dependents_of_changed_value (rtx
CHANGED_VARIABLES. */
static void
-process_changed_values (htab_t htab)
+process_changed_values (variable_table_type htab)
{
int i, n;
rtx val;
@@ -8722,7 +8724,9 @@ process_changed_values (htab_t htab)
vec_stack_alloc (rtx, changed_values_stack, 20);
/* Move values from changed_variables to changed_values_stack. */
- htab_traverse (changed_variables, values_to_stack, &changed_values_stack);
+ changed_variables
+ .traverse <vec<rtx, va_stack>*, var_track_values_to_stack>
+ (&changed_values_stack);
/* Back-propagate change notifications in values while popping
them from the stack. */
@@ -8755,9 +8759,9 @@ emit_notes_for_changes (rtx insn, enum e
shared_hash vars)
{
emit_note_data data;
- htab_t htab = shared_hash_htab (vars);
+ variable_table_type htab = shared_hash_htab (vars);
- if (!htab_elements (changed_variables))
+ if (!changed_variables.elements ())
return;
if (MAY_HAVE_DEBUG_INSNS)
@@ -8767,21 +8771,20 @@ emit_notes_for_changes (rtx insn, enum e
data.where = where;
data.vars = htab;
- htab_traverse (changed_variables, emit_note_insn_var_location, &data);
+ changed_variables
+ .traverse <emit_note_data*, emit_note_insn_var_location> (&data);
}
/* Add variable *SLOT to the chain CHANGED_VARIABLES if it differs from the
same variable in hash table DATA or is not there at all. */
-static int
-emit_notes_for_differences_1 (void **slot, void *data)
+int
+emit_notes_for_differences_1 (variable_def **slot,
variable_table_type new_vars)
{
- htab_t new_vars = (htab_t) data;
variable old_var, new_var;
- old_var = (variable) *slot;
- new_var = (variable) htab_find_with_hash (new_vars, old_var->dv,
- dv_htab_hash (old_var->dv));
+ old_var = *slot;
+ new_var = new_vars.find_with_hash (old_var->dv, dv_htab_hash (old_var->dv));
if (!new_var)
{
@@ -8847,15 +8850,13 @@ emit_notes_for_differences_1 (void **slo
/* Add variable *SLOT to the chain CHANGED_VARIABLES if it is not in hash
table DATA. */
-static int
-emit_notes_for_differences_2 (void **slot, void *data)
+int
+emit_notes_for_differences_2 (variable_def **slot,
variable_table_type old_vars)
{
- htab_t old_vars = (htab_t) data;
variable old_var, new_var;
- new_var = (variable) *slot;
- old_var = (variable) htab_find_with_hash (old_vars, new_var->dv,
- dv_htab_hash (new_var->dv));
+ new_var = *slot;
+ old_var = old_vars.find_with_hash (new_var->dv, dv_htab_hash (new_var->dv));
if (!old_var)
{
int i;
@@ -8875,12 +8876,12 @@ static void
emit_notes_for_differences (rtx insn, dataflow_set *old_set,
dataflow_set *new_set)
{
- htab_traverse (shared_hash_htab (old_set->vars),
- emit_notes_for_differences_1,
- shared_hash_htab (new_set->vars));
- htab_traverse (shared_hash_htab (new_set->vars),
- emit_notes_for_differences_2,
- shared_hash_htab (old_set->vars));
+ shared_hash_htab (old_set->vars)
+ .traverse <variable_table_type, emit_notes_for_differences_1>
+ (shared_hash_htab (new_set->vars));
+ shared_hash_htab (new_set->vars)
+ .traverse <variable_table_type, emit_notes_for_differences_2>
+ (shared_hash_htab (old_set->vars));
emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, new_set->vars);
}
@@ -9240,7 +9241,7 @@ vt_emit_notes (void)
basic_block bb;
dataflow_set cur;
- gcc_assert (!htab_elements (changed_variables));
+ gcc_assert (!changed_variables.elements ());
/* Free memory occupied by the out hash tables, as they aren't used
anymore. */
@@ -9253,9 +9254,7 @@ vt_emit_notes (void)
if (MAY_HAVE_DEBUG_INSNS)
{
- dropped_values = htab_create (cselib_get_next_uid () * 2,
- variable_htab_hash, variable_htab_eq,
- variable_htab_free);
+ dropped_values.create (cselib_get_next_uid () * 2);
loc_exp_dep_pool = create_alloc_pool ("loc_exp_dep pool",
sizeof (loc_exp_dep), 64);
}
@@ -9276,14 +9275,14 @@ vt_emit_notes (void)
dataflow_set_clear (&VTI (bb)->in);
}
#ifdef ENABLE_CHECKING
- htab_traverse (shared_hash_htab (cur.vars),
- emit_notes_for_differences_1,
- shared_hash_htab (empty_shared_hash));
+ shared_hash_htab (cur.vars)
+ .traverse <variable_table_type, emit_notes_for_differences_1>
+ (shared_hash_htab (empty_shared_hash));
#endif
dataflow_set_destroy (&cur);
if (MAY_HAVE_DEBUG_INSNS)
- htab_delete (dropped_values);
+ dropped_values.dispose ();
emit_notes = false;
}
@@ -9616,11 +9615,8 @@ vt_initialize (void)
sizeof (struct shared_hash_def), 256);
empty_shared_hash = (shared_hash) pool_alloc (shared_hash_pool);
empty_shared_hash->refcount = 1;
- empty_shared_hash->htab
- = htab_create (1, variable_htab_hash, variable_htab_eq,
- variable_htab_free);
- changed_variables = htab_create (10, variable_htab_hash, variable_htab_eq,
- variable_htab_free);
+ empty_shared_hash->htab.create (1);
+ changed_variables.create (10);
/* Init the IN and OUT sets. */
FOR_ALL_BB (bb)
@@ -9971,8 +9967,8 @@ vt_finalize (void)
}
}
free_aux_for_blocks ();
- htab_delete (empty_shared_hash->htab);
- htab_delete (changed_variables);
+ empty_shared_hash->htab.dispose ();
+ changed_variables.dispose ();
free_alloc_pool (attrs_pool);
free_alloc_pool (var_pool);
free_alloc_pool (loc_chain_pool);
Index: gcc/trans-mem.c
===================================================================
--- gcc/trans-mem.c (revision 194487)
+++ gcc/trans-mem.c (working copy)
@@ -880,8 +880,62 @@ typedef struct tm_log_entry
tree save_var;
} *tm_log_entry_t;
+
+/* Log entry hashtable helpers. */
+
+struct log_entry_hasher
+{
+ typedef tm_log_entry value_type;
+ typedef tm_log_entry 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 *);
+};
+
+/* Htab support. Return hash value for a `tm_log_entry'. */
+inline hashval_t
+log_entry_hasher::hash (const value_type *log)
+{
+ return iterative_hash_expr (log->addr, 0);
+}
+
+/* Htab support. Return true if two log entries are the same. */
+inline bool
+log_entry_hasher::equal (const value_type *log1, const compare_type *log2)
+{
+ /* FIXME:
+
+ rth: I suggest that we get rid of the component refs etc.
+ I.e. resolve the reference to base + offset.
+
+ We may need to actually finish a merge with mainline for this,
+ since we'd like to be presented with Richi's MEM_REF_EXPRs more
+ often than not. But in the meantime your tm_log_entry could save
+ the results of get_inner_reference.
+
+ See: g++.dg/tm/pr46653.C
+ */
+
+ /* Special case plain equality because operand_equal_p() below will
+ return FALSE if the addresses are equal but they have
+ side-effects (e.g. a volatile address). */
+ if (log1->addr == log2->addr)
+ return true;
+
+ return operand_equal_p (log1->addr, log2->addr, 0);
+}
+
+/* Htab support. Free one tm_log_entry. */
+inline void
+log_entry_hasher::remove (value_type *lp)
+{
+ lp->stmts.release ();
+ free (lp);
+}
+
+
/* The actual log. */
-static htab_t tm_log;
+static hash_table <log_entry_hasher> tm_log;
/* Addresses to log with a save/restore sequence. These should be in
dominator order. */
@@ -928,57 +982,11 @@ tm_mem_map_hasher::equal (const value_ty
of memory (malloc, alloc, etc). */
static hash_table <tm_mem_map_hasher> tm_new_mem_hash;
-/* Htab support. Return hash value for a `tm_log_entry'. */
-static hashval_t
-tm_log_hash (const void *p)
-{
- const struct tm_log_entry *log = (const struct tm_log_entry *) p;
- return iterative_hash_expr (log->addr, 0);
-}
-
-/* Htab support. Return true if two log entries are the same. */
-static int
-tm_log_eq (const void *p1, const void *p2)
-{
- const struct tm_log_entry *log1 = (const struct tm_log_entry *) p1;
- const struct tm_log_entry *log2 = (const struct tm_log_entry *) p2;
-
- /* FIXME:
-
- rth: I suggest that we get rid of the component refs etc.
- I.e. resolve the reference to base + offset.
-
- We may need to actually finish a merge with mainline for this,
- since we'd like to be presented with Richi's MEM_REF_EXPRs more
- often than not. But in the meantime your tm_log_entry could save
- the results of get_inner_reference.
-
- See: g++.dg/tm/pr46653.C
- */
-
- /* Special case plain equality because operand_equal_p() below will
- return FALSE if the addresses are equal but they have
- side-effects (e.g. a volatile address). */
- if (log1->addr == log2->addr)
- return true;
-
- return operand_equal_p (log1->addr, log2->addr, 0);
-}
-
-/* Htab support. Free one tm_log_entry. */
-static void
-tm_log_free (void *p)
-{
- struct tm_log_entry *lp = (struct tm_log_entry *) p;
- lp->stmts.release ();
- free (lp);
-}
-
/* Initialize logging data structures. */
static void
tm_log_init (void)
{
- tm_log = htab_create (10, tm_log_hash, tm_log_eq, tm_log_free);
+ tm_log.create (10);
tm_new_mem_hash.create (5);
tm_log_save_addresses.create (5);
}
@@ -987,7 +995,7 @@ tm_log_init (void)
static void
tm_log_delete (void)
{
- htab_delete (tm_log);
+ tm_log.dispose ();
tm_new_mem_hash.dispose ();
tm_log_save_addresses.release ();
}
@@ -1029,11 +1037,11 @@ transaction_invariant_address_p (const_t
static void
tm_log_add (basic_block entry_block, tree addr, gimple stmt)
{
- void **slot;
+ tm_log_entry **slot;
struct tm_log_entry l, *lp;
l.addr = addr;
- slot = htab_find_slot (tm_log, &l, INSERT);
+ slot = tm_log.find_slot (&l, INSERT);
if (!*slot)
{
tree type = TREE_TYPE (addr);
@@ -1074,7 +1082,7 @@ tm_log_add (basic_block entry_block, tre
size_t i;
gimple oldstmt;
- lp = (struct tm_log_entry *) *slot;
+ lp = *slot;
/* If we're generating a save/restore sequence, we don't care
about statements. */
@@ -1176,10 +1184,10 @@ tm_log_emit_stmt (tree addr, gimple stmt
static void
tm_log_emit (void)
{
- htab_iterator hi;
+ hash_table <log_entry_hasher>::iterator hi;
struct tm_log_entry *lp;
- FOR_EACH_HTAB_ELEMENT (tm_log, lp, tm_log_entry_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (tm_log, lp, tm_log_entry_t, hi)
{
size_t i;
gimple stmt;
@@ -1221,7 +1229,7 @@ tm_log_emit_saves (basic_block entry_blo
for (i = 0; i < tm_log_save_addresses.length (); ++i)
{
l.addr = tm_log_save_addresses[i];
- lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
+ lp = *(tm_log.find_slot (&l, NO_INSERT));
gcc_assert (lp->save_var != NULL);
/* We only care about variables in the current transaction. */
@@ -1257,7 +1265,7 @@ tm_log_emit_restores (basic_block entry_
for (i = tm_log_save_addresses.length () - 1; i >= 0; i--)
{
l.addr = tm_log_save_addresses[i];
- lp = (struct tm_log_entry *) *htab_find_slot (tm_log, &l, NO_INSERT);
+ lp = *(tm_log.find_slot (&l, NO_INSERT));
gcc_assert (lp->save_var != NULL);
/* We only care about variables in the current transaction. */
@@ -3153,6 +3161,35 @@ typedef struct tm_memop
tree addr;
} *tm_memop_t;
+/* TM memory operation hashtable helpers. */
+
+struct tm_memop_hasher : typed_free_remove <tm_memop>
+{
+ typedef tm_memop value_type;
+ typedef tm_memop compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Htab support. Return a hash value for a `tm_memop'. */
+inline hashval_t
+tm_memop_hasher::hash (const value_type *mem)
+{
+ tree addr = mem->addr;
+ /* We drill down to the SSA_NAME/DECL for the hash, but equality is
+ actually done with operand_equal_p (see tm_memop_eq). */
+ if (TREE_CODE (addr) == ADDR_EXPR)
+ addr = TREE_OPERAND (addr, 0);
+ return iterative_hash_expr (addr, 0);
+}
+
+/* Htab support. Return true if two tm_memop's are the same. */
+inline bool
+tm_memop_hasher::equal (const value_type *mem1, const compare_type *mem2)
+{
+ return operand_equal_p (mem1->addr, mem2->addr, 0);
+}
+
/* Sets for solving data flow equations in the memory optimization pass. */
struct tm_memopt_bitmaps
{
@@ -3185,7 +3222,7 @@ static bitmap_obstack tm_memopt_obstack;
/* Unique counter for TM loads and stores. Loads and stores of the
same address get the same ID. */
static unsigned int tm_memopt_value_id;
-static htab_t tm_memopt_value_numbers;
+static hash_table <tm_memop_hasher> tm_memopt_value_numbers;
#define STORE_AVAIL_IN(BB) \
((struct tm_memopt_bitmaps *) ((BB)->aux))->store_avail_in
@@ -3208,29 +3245,6 @@ static htab_t tm_memopt_value_numbers;
#define BB_VISITED_P(BB) \
((struct tm_memopt_bitmaps *) ((BB)->aux))->visited_p
-/* Htab support. Return a hash value for a `tm_memop'. */
-static hashval_t
-tm_memop_hash (const void *p)
-{
- const struct tm_memop *mem = (const struct tm_memop *) p;
- tree addr = mem->addr;
- /* We drill down to the SSA_NAME/DECL for the hash, but equality is
- actually done with operand_equal_p (see tm_memop_eq). */
- if (TREE_CODE (addr) == ADDR_EXPR)
- addr = TREE_OPERAND (addr, 0);
- return iterative_hash_expr (addr, 0);
-}
-
-/* Htab support. Return true if two tm_memop's are the same. */
-static int
-tm_memop_eq (const void *p1, const void *p2)
-{
- const struct tm_memop *mem1 = (const struct tm_memop *) p1;
- const struct tm_memop *mem2 = (const struct tm_memop *) p2;
-
- return operand_equal_p (mem1->addr, mem2->addr, 0);
-}
-
/* Given a TM load/store in STMT, return the value number for the address
it accesses. */
@@ -3238,13 +3252,13 @@ static unsigned int
tm_memopt_value_number (gimple stmt, enum insert_option op)
{
struct tm_memop tmpmem, *mem;
- void **slot;
+ tm_memop **slot;
gcc_assert (is_tm_load (stmt) || is_tm_store (stmt));
tmpmem.addr = gimple_call_arg (stmt, 0);
- slot = htab_find_slot (tm_memopt_value_numbers, &tmpmem, op);
+ slot = tm_memopt_value_numbers.find_slot (&tmpmem, op);
if (*slot)
- mem = (struct tm_memop *) *slot;
+ mem = *slot;
else if (op == INSERT)
{
mem = XNEW (struct tm_memop);
@@ -3302,11 +3316,11 @@ dump_tm_memopt_set (const char *set_name
fprintf (dump_file, "TM memopt: %s: [", set_name);
EXECUTE_IF_SET_IN_BITMAP (bits, 0, i, bi)
{
- htab_iterator hi;
- struct tm_memop *mem;
+ hash_table <tm_memop_hasher>::iterator hi;
+ struct tm_memop *mem = NULL;
/* Yeah, yeah, yeah. Whatever. This is just for debugging. */
- FOR_EACH_HTAB_ELEMENT (tm_memopt_value_numbers, mem, tm_memop_t, hi)
+ FOR_EACH_HASH_TABLE_ELEMENT (tm_memopt_value_numbers, mem,
tm_memop_t, hi)
if (mem->value_id == i)
break;
gcc_assert (mem->value_id == i);
@@ -3741,7 +3755,7 @@ execute_tm_memopt (void)
vec<basic_block> bbs;
tm_memopt_value_id = 0;
- tm_memopt_value_numbers = htab_create (10, tm_memop_hash, tm_memop_eq, free);
+ tm_memopt_value_numbers.create (10);
for (region = all_tm_regions; region; region = region->next)
{
@@ -3775,10 +3789,10 @@ execute_tm_memopt (void)
tm_memopt_free_sets (bbs);
bbs.release ();
bitmap_obstack_release (&tm_memopt_obstack);
- htab_empty (tm_memopt_value_numbers);
+ tm_memopt_value_numbers.empty ();
}
- htab_delete (tm_memopt_value_numbers);
+ tm_memopt_value_numbers.dispose ();
return 0;
}
Index: gcc/tree-ssa-sccvn.c
===================================================================
--- gcc/tree-ssa-sccvn.c (revision 194487)
+++ gcc/tree-ssa-sccvn.c (working copy)
@@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.
#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"
@@ -97,19 +97,187 @@ along with GCC; see the file COPYING3.
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;
@@ -339,62 +507,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;
}
@@ -404,22 +530,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;
}
@@ -432,26 +557,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
@@ -467,15 +572,6 @@ vn_reference_op_compute_hash (const vn_r
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
@@ -525,16 +621,14 @@ vn_reference_compute_hash (const vn_refe
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;
@@ -1347,15 +1441,13 @@ valueize_shared_reference_ops_from_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)
@@ -1378,7 +1470,7 @@ vn_reference_lookup_2 (ao_ref *op ATTRIB
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
@@ -1398,11 +1490,9 @@ vn_reference_lookup_2 (ao_ref *op ATTRIB
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;
@@ -2005,7 +2095,7 @@ vn_reference_lookup (tree op, tree vuse,
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);
@@ -2021,8 +2111,8 @@ vn_reference_insert (tree op, tree resul
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),
@@ -2050,7 +2140,7 @@ vn_reference_insert_pieces (tree vuse, a
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);
@@ -2064,8 +2154,8 @@ vn_reference_insert_pieces (tree vuse, a
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
@@ -2106,23 +2196,12 @@ vn_nary_op_compute_hash (const vn_nary_o
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)
@@ -2239,22 +2318,20 @@ init_vn_nary_op_from_stmt (vn_nary_op_t
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
@@ -2332,14 +2409,15 @@ alloc_vn_nary_op (unsigned int length, t
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;
@@ -2417,23 +2495,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;
@@ -2472,7 +2538,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;
@@ -2488,14 +2554,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
@@ -2504,7 +2568,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;
@@ -2522,8 +2586,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.*/
@@ -2731,7 +2794,7 @@ visit_reference_op_call (tree lhs, gimpl
}
else
{
- void **slot;
+ vn_reference_s **slot;
vn_reference_t vr2;
if (vdef)
changed |= set_ssa_val_to (vdef, vdef);
@@ -2745,8 +2808,8 @@ visit_reference_op_call (tree lhs, gimpl
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;
@@ -3566,10 +3629,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;
}
@@ -3580,12 +3643,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;
@@ -3600,7 +3662,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;
@@ -3637,9 +3701,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);
@@ -3654,11 +3718,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;
@@ -3818,10 +3883,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",
@@ -3837,9 +3901,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);
@@ -3854,8 +3918,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);
@@ -3911,7 +3974,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 ();
@@ -3953,7 +4016,9 @@ set_value_id_for_result (tree result, un
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;
@@ -3961,16 +4026,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);
}
Index: gcc/tree-ssa-sccvn.h
===================================================================
--- gcc/tree-ssa-sccvn.h (revision 194487)
+++ gcc/tree-ssa-sccvn.h (working copy)
@@ -207,10 +207,11 @@ vn_reference_t vn_reference_insert_piece
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);
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in (revision 194487)
+++ gcc/Makefile.in (working copy)
@@ -2269,7 +2269,7 @@ tree-into-ssa.o : tree-into-ssa.c $(TREE
$(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 \
@@ -2367,7 +2367,7 @@ tree-ssa-pre.o : tree-ssa-pre.c $(TREE_F
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) \
@@ -3077,7 +3077,7 @@ valtrack.o : valtrack.c $(VALTRACK_H) $(
coretypes.h $(TM_H) $(FUNCTION_H) $(REGS_H) $(EMIT_RTL_H)
var-tracking.o : var-tracking.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) hard-reg-set.h insn-config.h reload.h $(FLAGS_H) \
- $(BASIC_BLOCK_H) bitmap.h alloc-pool.h $(FIBHEAP_H) $(HASHTAB_H) \
+ $(BASIC_BLOCK_H) bitmap.h alloc-pool.h $(FIBHEAP_H) $(HASH_TABLE_H) \
$(REGS_H) $(EXPR_H) $(TREE_PASS_H) $(TREE_FLOW_H) \
cselib.h $(TARGET_H) $(DIAGNOSTIC_CORE_H) $(PARAMS_H) $(DIAGNOSTIC_H) \
pointer-set.h $(RECOG_H) $(TM_P_H) $(TREE_PRETTY_PRINT_H) $(ALIAS_H)
Index: gcc/hash-table.h
===================================================================
--- gcc/hash-table.h (revision 194487)
+++ gcc/hash-table.h (working copy)
@@ -156,6 +156,47 @@ along with GCC; see the file COPYING3.
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);
+
*/
@@ -369,6 +410,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;
@@ -401,6 +456,9 @@ public:
template <typename Argument,
int (*Callback) (value_type **slot, Argument argument)>
void traverse (Argument argument);
+
+ iterator begin();
+ iterator end();
};
@@ -893,4 +951,114 @@ hash_table <Descriptor, Allocator>::trav
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 */
--
Lawrence Crowl
More information about the Gcc-patches
mailing list