This patch is part of a consolodation of the hash_table patches to the...
authorLawrence Crowl <crowl@google.com>
Fri, 26 Apr 2013 00:30:32 +0000 (00:30 +0000)
committerLawrence Crowl <crowl@gcc.gnu.org>
Fri, 26 Apr 2013 00:30:32 +0000 (00:30 +0000)
This patch is part of a consolodation of the hash_table patches to
the cxx-conversion branch for files not under gcc/config.

Update various hash tables from htab_t to hash_table.
Modify types and calls to match.

* 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.

Tested on x86_64.

Index: gcc/ChangeLog

* var-tracking.c (shared_hash_def::htab):
Change type to hash_table.  Update dependent calls and types.

2013-04-25  Lawrence Crowl  <crowl@google.com>

From-SVN: r198330

gcc/ChangeLog
gcc/Makefile.in
gcc/var-tracking.c

index c63c9e08f7c2ec9c3aac92e9b685a12397250409..1768ae8b7ade0ee68d1044e319cc83df9488d7d9 100644 (file)
@@ -1,3 +1,8 @@
+2013-04-25  Lawrence Crowl  <crowl@google.com>
+
+       * var-tracking.c (shared_hash_def::htab):
+       Change type to hash_table.  Update dependent calls and types.
+
 2013-04-25  Lawrence Crowl  <crowl@google.com>
 
        * Makefile.in: Update as needed below.
index a3105b1ab86ad0977ed436028161e3f7a1fef124..adb7d0c0b6b642b3294bf086b5e68958c93c8100 100644 (file)
@@ -3095,7 +3095,7 @@ valtrack.o : valtrack.c $(VALTRACK_H) $(CONFIG_H) $(SYSTEM_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 337af5a5fdc7658d3d0f21670ffe751704753e9b..8108413ea72c1066a6935a8c27c569c79bd5ed53 100644 (file)
 #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"
@@ -196,19 +196,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.
@@ -229,58 +253,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
 {
@@ -454,6 +426,146 @@ typedef const struct variable_def *const_variable;
                              ? &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;
 
@@ -473,7 +585,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;
@@ -481,7 +593,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;
@@ -509,9 +621,6 @@ static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
 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 *);
@@ -520,9 +629,9 @@ static void attrs_list_insert (attrs *, decl_or_value, HOST_WIDE_INT, rtx);
 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,
@@ -539,7 +648,7 @@ static void dataflow_set_clear (dataflow_set *);
 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 *);
@@ -558,32 +667,27 @@ static bool compute_bb_dataflow (basic_block);
 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);
 
@@ -1188,36 +1292,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)
@@ -1233,13 +1307,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.  */
@@ -1327,57 +1394,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).  */
@@ -1534,7 +1550,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;
@@ -1558,9 +1574,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;
@@ -1584,7 +1598,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);
     }
 }
@@ -1592,16 +1606,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)
 {
@@ -1612,15 +1626,15 @@ shared_hash_find_slot_unshare (shared_hash *pvars, decl_or_value dv,
    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));
@@ -1628,15 +1642,14 @@ shared_hash_find_slot (shared_hash vars, decl_or_value dv)
 
 /* 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));
@@ -1648,7 +1661,7 @@ shared_hash_find_slot_noinsert (shared_hash vars, decl_or_value dv)
 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
@@ -1677,8 +1690,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;
@@ -1744,8 +1757,8 @@ unshare_variable (dataflow_set *set, void **slot, variable var,
   *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;
@@ -1759,18 +1772,16 @@ unshare_variable (dataflow_set *set, void **slot, variable var,
 /* 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;
     }
 }
@@ -2057,8 +2068,7 @@ get_addr_from_local_cache (dataflow_set *set, rtx const loc)
     }
 
   dv = dv_from_rtx (x);
-  var = (variable) htab_find_with_hash (shared_hash_htab (set->vars),
-                                       dv, dv_htab_hash (dv));
+  var = shared_hash_find (set->vars, dv);
   if (!var)
     return x;
 
@@ -2198,13 +2208,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)
     {
@@ -2224,7 +2233,7 @@ drop_overlapping_mem_locs (void **slot, void *data)
            return 1;
 
          slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
-         var = (variable)*slot;
+         var = *slot;
          gcc_assert (var->n_var_parts == 1);
        }
 
@@ -2282,8 +2291,8 @@ clobber_overlapping_mems (dataflow_set *set, rtx loc)
   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;
 }
 
@@ -2701,7 +2710,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);
@@ -2719,7 +2728,7 @@ variable_union (variable src, dataflow_set *set)
       return 1;
     }
   else
-    dst = (variable) *dstp;
+    dst = *dstp;
 
   gcc_assert (src->n_var_parts);
   gcc_checking_assert (src->onepart == dst->onepart);
@@ -2753,7 +2762,7 @@ variable_union (variable src, dataflow_set *set)
                {
                  dstp = unshare_variable (set, dstp, dst,
                                           VAR_INIT_STATUS_INITIALIZED);
-                 dst = (variable)*dstp;
+                 dst = *dstp;
                  goto restart_onepart_unshared;
                }
 
@@ -2806,7 +2815,7 @@ variable_union (variable src, dataflow_set *set)
   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;
@@ -3081,10 +3090,11 @@ dataflow_set_union (dataflow_set *dst, dataflow_set *src)
     }
   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);
     }
 }
@@ -3147,7 +3157,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;
@@ -3204,7 +3214,7 @@ find_loc_in_1pdv (rtx loc, variable var, htab_t vars)
       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);
     }
 
@@ -3520,10 +3530,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
@@ -3555,11 +3566,10 @@ canonicalize_loc_order_check (void **slot, void *data ATTRIBUTE_UNUSED)
    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;
@@ -3579,7 +3589,8 @@ canonicalize_values_mark (void **slot, void *data)
        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);
@@ -3594,16 +3605,15 @@ canonicalize_values_mark (void **slot, void *data)
 /* 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;
 
@@ -3669,7 +3679,7 @@ canonicalize_values_star (void **slot, void *data)
                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;
@@ -3799,7 +3809,7 @@ canonicalize_values_star (void **slot, void *data)
   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);
 
@@ -3816,16 +3826,15 @@ canonicalize_values_star (void **slot, void *data)
    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;
 
@@ -3847,7 +3856,7 @@ canonicalize_vars_star (void **slot, void *data)
   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;
@@ -3879,7 +3888,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;
@@ -3919,7 +3928,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
   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);
@@ -4017,8 +4026,8 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
       nodep = nextp;
     }
 
-  if (dvar != (variable)*dstslot)
-    dvar = (variable)*dstslot;
+  if (dvar != *dstslot)
+    dvar = *dstslot;
   nodep = &dvar->var_part[0].loc_chain;
 
   if (val)
@@ -4040,7 +4049,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
       gcc_checking_assert (dstslot
                           == shared_hash_find_slot_noinsert_1 (dst->vars,
                                                                dv, dvhash));
-      dvar = (variable)*dstslot;
+      dvar = *dstslot;
     }
   else
     {
@@ -4076,7 +4085,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
              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);
@@ -4108,7 +4117,7 @@ variable_merge_over_cur (variable s1var, struct dfset_merge *dsm)
          gcc_checking_assert (dstslot
                               == shared_hash_find_slot_noinsert_1 (dst->vars,
                                                                    dv, dvhash));
-         dvar = (variable)*dstslot;
+         dvar = *dstslot;
        }
     }
 
@@ -4144,7 +4153,7 @@ variable_merge_over_src (variable s2var, struct dfset_merge *dsm)
 
   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;
@@ -4165,19 +4174,17 @@ dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
   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]);
@@ -4187,9 +4194,11 @@ dataflow_set_merge (dataflow_set *dst, dataflow_set *src2)
   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)
@@ -4259,7 +4268,7 @@ dataflow_set_equiv_regs (dataflow_set *set)
        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;
@@ -4330,12 +4339,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)
@@ -4360,7 +4368,7 @@ variable_post_merge_new_vals (void **slot, void *info)
                {
                  slot = unshare_variable (set, slot, var,
                                           VAR_INIT_STATUS_INITIALIZED);
-                 var = (variable)*slot;
+                 var = *slot;
                  goto restart;
                }
 
@@ -4467,12 +4475,11 @@ variable_post_merge_new_vals (void **slot, void *info)
 /* 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;
@@ -4536,13 +4543,15 @@ dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
   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
@@ -4550,7 +4559,7 @@ dataflow_post_merge_adjust (dataflow_set *set, dataflow_set **permp)
    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;
@@ -4564,7 +4573,7 @@ find_mem_expr_in_1pdv (tree expr, rtx val, htab_t vars)
              && !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;
@@ -4621,11 +4630,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)
     {
@@ -4659,7 +4667,7 @@ dataflow_set_preserve_mem_locs (void **slot, void *data)
            return 1;
 
          slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
-         var = (variable)*slot;
+         var = *slot;
          gcc_assert (var->n_var_parts == 1);
        }
 
@@ -4731,11 +4739,10 @@ dataflow_set_preserve_mem_locs (void **slot, void *data)
 /* 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)
     {
@@ -4756,7 +4763,7 @@ dataflow_set_remove_mem_locs (void **slot, void *data)
            return 1;
 
          slot = unshare_variable (set, slot, var, VAR_INIT_STATUS_UNKNOWN);
-         var = (variable)*slot;
+         var = *slot;
          gcc_assert (var->n_var_parts == 1);
        }
 
@@ -4816,11 +4823,11 @@ dataflow_set_clear_at_call (dataflow_set *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;
     }
 }
@@ -4919,21 +4926,21 @@ variable_different_p (variable var1, variable var2)
 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))
@@ -6843,13 +6850,13 @@ compute_bb_dataflow (basic_block bb)
       local_get_addr_cache = NULL;
 
       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);
@@ -6921,12 +6928,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;
@@ -6964,9 +6969,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)
                        {
@@ -6986,8 +6991,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)
                {
@@ -7034,9 +7039,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);
 
@@ -7084,10 +7089,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);
 
@@ -7143,12 +7148,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);
     }
 }
 
@@ -7196,18 +7201,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);
 
@@ -7267,18 +7271,16 @@ variable_was_changed (variable var, dataflow_set *set)
 
   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)
@@ -7297,14 +7299,14 @@ variable_was_changed (variable var, dataflow_set *set)
        {
          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)
                {
@@ -7359,7 +7361,7 @@ variable_was_changed (variable var, dataflow_set *set)
       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);
@@ -7368,7 +7370,7 @@ variable_was_changed (variable var, dataflow_set *set)
              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);
            }
        }
     }
@@ -7418,8 +7420,8 @@ find_variable_location_part (variable var, HOST_WIDE_INT offset,
   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)
 {
@@ -7429,7 +7431,7 @@ set_slot_part (dataflow_set *set, rtx loc, void **slot,
   variable var;
   onepart_enum_t onepart;
 
-  var = (variable) *slot;
+  var = *slot;
 
   if (var)
     onepart = var->onepart;
@@ -7552,7 +7554,7 @@ set_slot_part (dataflow_set *set, rtx loc, void **slot,
       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--;
@@ -7591,7 +7593,7 @@ set_slot_part (dataflow_set *set, rtx loc, void **slot,
              if (shared_var_p (var, set->vars))
                {
                  slot = unshare_variable (set, slot, var, initialized);
-                 var = (variable)*slot;
+                 var = *slot;
                }
            }
        }
@@ -7603,7 +7605,7 @@ set_slot_part (dataflow_set *set, rtx loc, void **slot,
          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
@@ -7678,7 +7680,7 @@ set_variable_part (dataflow_set *set, rtx loc,
                   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);
@@ -7696,11 +7698,11 @@ set_variable_part (dataflow_set *set, rtx loc,
    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)
@@ -7759,7 +7761,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))))
@@ -7776,11 +7778,11 @@ clobber_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
    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)
@@ -7803,7 +7805,7 @@ delete_slot_part (dataflow_set *set, rtx loc, void **slot,
                {
                  slot = unshare_variable (set, slot, var,
                                           VAR_INIT_STATUS_UNKNOWN);
-                 var = (variable)*slot;
+                 var = *slot;
                  break;
                }
            }
@@ -7867,7 +7869,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;
 
@@ -7880,7 +7882,7 @@ delete_variable_part (dataflow_set *set, rtx loc, decl_or_value dv,
 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.  */
@@ -7969,7 +7971,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;
@@ -7979,7 +7981,7 @@ loc_exp_insert_dep (variable var, rtx x, htab_t vars)
 
   /* ??? 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)
     {
@@ -8019,7 +8021,8 @@ loc_exp_insert_dep (variable var, rtx x, htab_t vars)
    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;
 
@@ -8048,7 +8051,7 @@ loc_exp_dep_set (variable var, rtx result, rtx *value, int count, htab_t vars)
    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;
 
@@ -8086,7 +8089,7 @@ notify_dependents_of_resolved_value (variable ivar, htab_t vars)
            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);
@@ -8330,7 +8333,7 @@ vt_expand_loc_callback (rtx x, bitmap regs,
       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)
     {
@@ -8439,7 +8442,7 @@ resolve_expansions_pending_recursion (vec<rtx, va_stack> pending)
    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;
@@ -8461,7 +8464,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;
@@ -8486,13 +8489,13 @@ vt_expand_1pvar (variable var, htab_t vars)
    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;
@@ -8709,7 +8712,7 @@ emit_note_insn_var_location (void **varp, void *data)
   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;
@@ -8718,11 +8721,11 @@ emit_note_insn_var_location (void **varp, void *data)
 /* 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));
@@ -8738,14 +8741,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
@@ -8754,23 +8757,22 @@ remove_value_from_changed_variables (rtx val)
    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)))
     {
@@ -8800,14 +8802,14 @@ notify_dependents_of_changed_value (rtx val, htab_t htab,
          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;
@@ -8837,7 +8839,7 @@ notify_dependents_of_changed_value (rtx val, htab_t htab,
    CHANGED_VARIABLES.  */
 
 static void
-process_changed_values (htab_t htab)
+process_changed_values (variable_table_type htab)
 {
   int i, n;
   rtx val;
@@ -8846,7 +8848,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.  */
@@ -8879,9 +8883,9 @@ emit_notes_for_changes (rtx insn, enum emit_note_where where,
                        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)
@@ -8891,21 +8895,20 @@ emit_notes_for_changes (rtx insn, enum emit_note_where where,
   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)
     {
@@ -8971,15 +8974,13 @@ emit_notes_for_differences_1 (void **slot, void *data)
 /* 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;
@@ -8999,12 +9000,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);
 }
 
@@ -9359,7 +9360,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.  */
@@ -9372,9 +9373,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);
     }
@@ -9402,14 +9401,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;
 }
@@ -9745,11 +9744,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)
@@ -10102,8 +10098,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);