Patchwork [cxx-conversion] Change uses of htab_t in gcc/config to hash_table.

login
register
mail settings
Submitter Lawrence Crowl
Date Dec. 19, 2012, 4:02 a.m.
Message ID <CAGqM8fZB-fLe7PddPzfZBs_NuO1mzyqUFBGYDgOu_HW46vkhQA@mail.gmail.com>
Download mbox | patch
Permalink /patch/207240/
State New
Headers show

Comments

Lawrence Crowl - Dec. 19, 2012, 4:02 a.m.
Update various config htab_t uses to hash_table.

Modify types and calls to match.

* config/arm/arm.c'arm_libcall_uses_aapcs_base::libcall_htab

Fold libcall_eq and libcall_hash into new struct libcall_hasher.

* config/ia64/ia64.c'bundle_state_table

Fold bundle_state_hash and bundle_state_eq_p into new struct
bundle_state_hasher.

* config/mips/mips.c'mips_offset_table

Fold mips_lo_sum_offset_hash and mips_lo_sum_offset_eq into new
struct mips_lo_sum_offset_hasher.

In mips_reorg_process_insns, change call to for_each_rtx to pass
a pointer to the hash_table rather than a htab_t.  This change
requires then dereferencing that pointer in mips_record_lo_sum to
obtain the hash_table.

* config/sol2.c'solaris_comdat_htab

Fold comdat_hash and comdat_eq into new struct comdat_entry_hasher.

* config/i386/winnt.c'i386_pe_section_type_flags::htab

* config/i386/winnt.c'i386_find_on_wrapper_list::wrappers

Fold wrapper_strcmp into new struct wrapped_symbol_hasher.


Tested on x86-64.
Tested with contrib/config-list.mk.


Okay for branch?
Diego Novillo - Dec. 19, 2012, 2:53 p.m.
On Tue, Dec 18, 2012 at 11:02 PM, Lawrence Crowl <crowl@googlers.com> wrote:

> Tested on x86-64.
> Tested with contrib/config-list.mk.
>
>
> Okay for branch?

OK.


Diego.
Xinliang David Li - Jan. 6, 2013, 5:55 a.m.
I noticed that the traverse and traverse_noresize method takes
Argument as the first template parameter. It should be moved to be the
second after the callback. In most of the cases, the type of the
Argument can be deduced from the callsite, so that the user only need
to specify the callback:

ht->traverse_noresize<the_call_back_function>(&arg);

In the current way, user has to do this:

ht->traverse_noresize<arg_type, the_call_back_function> (&arg);

which is not as friendly.

David


On Tue, Dec 18, 2012 at 8:02 PM, Lawrence Crowl <crowl@googlers.com> wrote:
> Update various config htab_t uses to hash_table.
>
> Modify types and calls to match.
>
> * config/arm/arm.c'arm_libcall_uses_aapcs_base::libcall_htab
>
> Fold libcall_eq and libcall_hash into new struct libcall_hasher.
>
> * config/ia64/ia64.c'bundle_state_table
>
> Fold bundle_state_hash and bundle_state_eq_p into new struct
> bundle_state_hasher.
>
> * config/mips/mips.c'mips_offset_table
>
> Fold mips_lo_sum_offset_hash and mips_lo_sum_offset_eq into new
> struct mips_lo_sum_offset_hasher.
>
> In mips_reorg_process_insns, change call to for_each_rtx to pass
> a pointer to the hash_table rather than a htab_t.  This change
> requires then dereferencing that pointer in mips_record_lo_sum to
> obtain the hash_table.
>
> * config/sol2.c'solaris_comdat_htab
>
> Fold comdat_hash and comdat_eq into new struct comdat_entry_hasher.
>
> * config/i386/winnt.c'i386_pe_section_type_flags::htab
>
> * config/i386/winnt.c'i386_find_on_wrapper_list::wrappers
>
> Fold wrapper_strcmp into new struct wrapped_symbol_hasher.
>
>
> Tested on x86-64.
> Tested with contrib/config-list.mk.
>
>
> Okay for branch?
>
>
> Index: gcc/config/arm/arm.c
> ===================================================================
> --- gcc/config/arm/arm.c        (revision 194511)
> +++ gcc/config/arm/arm.c        (working copy)
> @@ -25,6 +25,7 @@
>  #include "config.h"
>  #include "system.h"
>  #include "coretypes.h"
> +#include "hash-table.h"
>  #include "tm.h"
>  #include "rtl.h"
>  #include "tree.h"
> @@ -3716,36 +3717,48 @@ arm_function_value(const_tree type, cons
>    return arm_libcall_value_1 (mode);
>  }
>
> -static int
> -libcall_eq (const void *p1, const void *p2)
> +/* libcall hashtable helpers.  */
> +
> +struct libcall_hasher : typed_noop_remove <rtx_def>
>  {
> -  return rtx_equal_p ((const_rtx) p1, (const_rtx) p2);
> +  typedef rtx_def value_type;
> +  typedef rtx_def 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 *);
> +};
> +
> +inline bool
> +libcall_hasher::equal (const value_type *p1, const compare_type *p2)
> +{
> +  return rtx_equal_p (p1, p2);
>  }
>
> -static hashval_t
> -libcall_hash (const void *p1)
> +inline hashval_t
> +libcall_hasher::hash (const value_type *p1)
>  {
> -  return hash_rtx ((const_rtx) p1, VOIDmode, NULL, NULL, FALSE);
> +  return hash_rtx (p1, VOIDmode, NULL, NULL, FALSE);
>  }
>
> +typedef hash_table <libcall_hasher> libcall_table_type;
> +
>  static void
> -add_libcall (htab_t htab, rtx libcall)
> +add_libcall (libcall_table_type htab, rtx libcall)
>  {
> -  *htab_find_slot (htab, libcall, INSERT) = libcall;
> +  *htab.find_slot (libcall, INSERT) = libcall;
>  }
>
>  static bool
>  arm_libcall_uses_aapcs_base (const_rtx libcall)
>  {
>    static bool init_done = false;
> -  static htab_t libcall_htab;
> +  static libcall_table_type libcall_htab;
>
>    if (!init_done)
>      {
>        init_done = true;
>
> -      libcall_htab = htab_create (31, libcall_hash, libcall_eq,
> -                                 NULL);
> +      libcall_htab.create (31);
>        add_libcall (libcall_htab,
>                    convert_optab_libfunc (sfloat_optab, SFmode, SImode));
>        add_libcall (libcall_htab,
> @@ -3804,7 +3817,7 @@ arm_libcall_uses_aapcs_base (const_rtx l
>                                                         DFmode));
>      }
>
> -  return libcall && htab_find (libcall_htab, libcall) != NULL;
> +  return libcall && libcall_htab.find (libcall) != NULL;
>  }
>
>  static rtx
> Index: gcc/config/arm/t-arm
> ===================================================================
> --- gcc/config/arm/t-arm        (revision 194511)
> +++ gcc/config/arm/t-arm        (working copy)
> @@ -73,8 +73,8 @@ $(srcdir)/config/arm/arm-tables.opt: $(s
>         $(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
>                 $(srcdir)/config/arm/arm-tables.opt
>
> -arm.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
> -  $(RTL_H) $(TREE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
> +arm.o: $(srcdir)/config/arm/arm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
> +  $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
>    insn-config.h conditions.h output.h dumpfile.h \
>    $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \
>    $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \
> Index: gcc/config/i386/winnt.c
> ===================================================================
> --- gcc/config/i386/winnt.c     (revision 194511)
> +++ gcc/config/i386/winnt.c     (working copy)
> @@ -31,7 +31,7 @@ along with GCC; see the file COPYING3.
>  #include "flags.h"
>  #include "tm_p.h"
>  #include "diagnostic-core.h"
> -#include "hashtab.h"
> +#include "hash-table.h"
>  #include "langhooks.h"
>  #include "ggc.h"
>  #include "target.h"
> @@ -449,7 +449,7 @@ i386_pe_reloc_rw_mask (void)
>  unsigned int
>  i386_pe_section_type_flags (tree decl, const char *name, int reloc)
>  {
> -  static htab_t htab;
> +  static hash_table <pointer_hash <unsigned int> > htab;
>    unsigned int flags;
>    unsigned int **slot;
>
> @@ -460,8 +460,8 @@ i386_pe_section_type_flags (tree decl, c
>    /* The names we put in the hashtable will always be the unique
>       versions given to us by the stringtable, so we can just use
>       their addresses as the keys.  */
> -  if (!htab)
> -    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
> +  if (!htab.is_created ())
> +    htab.create (31);
>
>    if (decl && TREE_CODE (decl) == FUNCTION_DECL)
>      flags = SECTION_CODE;
> @@ -480,7 +480,7 @@ i386_pe_section_type_flags (tree decl, c
>      flags |= SECTION_LINKONCE;
>
>    /* See if we already have an entry for this section.  */
> -  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
> +  slot = htab.find_slot ((unsigned int *)name, INSERT);
>    if (!*slot)
>      {
>        *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
> @@ -680,12 +680,29 @@ i386_pe_maybe_record_exported_symbol (tr
>
>  #ifdef CXX_WRAP_SPEC_LIST
>
> +/* Hashtable helpers.  */
> +
> +struct wrapped_symbol_hasher : typed_noop_remove <char>
> +{
> +  typedef char value_type;
> +  typedef char 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 *);
> +};
> +
> +inline hashval_t
> +wrapped_symbol_hasher::hash (const value_type *v)
> +{
> +  return htab_hash_string (v);
> +}
> +
>  /*  Hash table equality helper function.  */
>
> -static int
> -wrapper_strcmp (const void *x, const void *y)
> +inline bool
> +wrapped_symbol_hasher::equal (const value_type *x, const compare_type *y)
>  {
> -  return !strcmp ((const char *) x, (const char *) y);
> +  return !strcmp (x, y);
>  }
>
>  /* Search for a function named TARGET in the list of library wrappers
> @@ -699,7 +716,7 @@ static const char *
>  i386_find_on_wrapper_list (const char *target)
>  {
>    static char first_time = 1;
> -  static htab_t wrappers;
> +  static hash_table <wrapped_symbol_hasher> wrappers;
>
>    if (first_time)
>      {
> @@ -712,8 +729,7 @@ i386_find_on_wrapper_list (const char *t
>        char *bufptr;
>        /* Breaks up the char array into separated strings
>           strings and enter them into the hash table.  */
> -      wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
> -       0, xcalloc, free);
> +      wrappers.create (8);
>        for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
>         {
>           char *found = NULL;
> @@ -726,12 +742,12 @@ i386_find_on_wrapper_list (const char *t
>           if (*bufptr)
>             *bufptr = 0;
>           if (found)
> -           *htab_find_slot (wrappers, found, INSERT) = found;
> +           *wrappers.find_slot (found, INSERT) = found;
>         }
>        first_time = 0;
>      }
>
> -  return (const char *) htab_find (wrappers, target);
> +  return wrappers.find (target);
>  }
>
>  #endif /* CXX_WRAP_SPEC_LIST */
> Index: gcc/config/i386/t-interix
> ===================================================================
> --- gcc/config/i386/t-interix   (revision 194511)
> +++ gcc/config/i386/t-interix   (working copy)
> @@ -19,7 +19,7 @@
>
>  winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>    $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
> -  $(TM_P_H) $(HASHTAB_H) $(GGC_H)
> +  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H)
>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
>                 $(srcdir)/config/i386/winnt.c
>
> Index: gcc/config/i386/t-cygming
> ===================================================================
> --- gcc/config/i386/t-cygming   (revision 194511)
> +++ gcc/config/i386/t-cygming   (working copy)
> @@ -23,7 +23,7 @@ LIMITS_H_TEST = true
>
>  winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>    $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
> -  $(TM_P_H) $(HASHTAB_H) $(GGC_H) $(LTO_STREAMER_H)
> +  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H) $(LTO_STREAMER_H)
>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
>         $(srcdir)/config/i386/winnt.c
>
> Index: gcc/config/sol2.c
> ===================================================================
> --- gcc/config/sol2.c   (revision 194511)
> +++ gcc/config/sol2.c   (working copy)
> @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.
>  #include "tm_p.h"
>  #include "diagnostic-core.h"
>  #include "ggc.h"
> -#include "hashtab.h"
> +#include "hash-table.h"
>
>  tree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;
>
> @@ -158,10 +158,6 @@ solaris_assemble_visibility (tree decl A
>  #endif
>  }
>
> -/* Hash table of group signature symbols.  */
> -
> -static htab_t solaris_comdat_htab;
> -
>  /* Group section information entry stored in solaris_comdat_htab.  */
>
>  typedef struct comdat_entry
> @@ -172,25 +168,34 @@ typedef struct comdat_entry
>    const char *sig;
>  } comdat_entry;
>
> -/* Helper routines for maintaining solaris_comdat_htab.  */
> +/* Helpers for maintaining solaris_comdat_htab.  */
>
> -static hashval_t
> -comdat_hash (const void *p)
> +struct comdat_entry_hasher : typed_noop_remove <comdat_entry>
>  {
> -  const comdat_entry *entry = (const comdat_entry *) p;
> +  typedef comdat_entry value_type;
> +  typedef comdat_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 *);
> +};
>
> +inline hashval_t
> +comdat_entry_hasher::hash (const value_type *entry)
> +{
>    return htab_hash_string (entry->sig);
>  }
>
> -static int
> -comdat_eq (const void *p1, const void *p2)
> +inline bool
> +comdat_entry_hasher::equal (const value_type *entry1,
> +                           const compare_type *entry2)
>  {
> -  const comdat_entry *entry1 = (const comdat_entry *) p1;
> -  const comdat_entry *entry2 = (const comdat_entry *) p2;
> -
>    return strcmp (entry1->sig, entry2->sig) == 0;
>  }
>
> +/* Hash table of group signature symbols.  */
> +
> +static hash_table <comdat_entry_hasher> solaris_comdat_htab;
> +
>  /* Output assembly to switch to COMDAT group section NAME with attributes
>     FLAGS and group signature symbol DECL, using Sun as syntax.  */
>
> @@ -230,12 +235,11 @@ solaris_elf_asm_comdat_section (const ch
>       identify the missing ones without changing the affected frontents,
>       remember the signature symbols and emit those not marked
>       TREE_SYMBOL_REFERENCED in solaris_file_end.  */
> -  if (solaris_comdat_htab == NULL)
> -    solaris_comdat_htab = htab_create_alloc (37, comdat_hash, comdat_eq, NULL,
> -                                            xcalloc, free);
> +  if (!solaris_comdat_htab.is_created ())
> +    solaris_comdat_htab.create (37);
>
>    entry.sig = signature;
> -  slot = (comdat_entry **) htab_find_slot (solaris_comdat_htab,
> &entry, INSERT);
> +  slot = solaris_comdat_htab.find_slot (&entry, INSERT);
>
>    if (*slot == NULL)
>      {
> @@ -251,10 +255,11 @@ solaris_elf_asm_comdat_section (const ch
>
>  /* Define unreferenced COMDAT group signature symbol corresponding to SLOT.  */
>
> -static int
> -solaris_define_comdat_signature (void **slot, void *aux ATTRIBUTE_UNUSED)
> +int
> +solaris_define_comdat_signature (comdat_entry **slot,
> +                                void *aux ATTRIBUTE_UNUSED)
>  {
> -  comdat_entry *entry = *(comdat_entry **) slot;
> +  comdat_entry *entry = *slot;
>    tree decl = entry->decl;
>
>    if (TREE_CODE (decl) != IDENTIFIER_NODE)
> @@ -278,10 +283,10 @@ solaris_define_comdat_signature (void **
>  void
>  solaris_file_end (void)
>  {
> -  if (solaris_comdat_htab == NULL)
> +  if (!solaris_comdat_htab.is_created ())
>      return;
>
> -  htab_traverse (solaris_comdat_htab, solaris_define_comdat_signature, NULL);
> +  solaris_comdat_htab.traverse <void *,
> solaris_define_comdat_signature> (NULL);
>  }
>
>  void
> Index: gcc/config/ia64/t-ia64
> ===================================================================
> --- gcc/config/ia64/t-ia64      (revision 194511)
> +++ gcc/config/ia64/t-ia64      (working copy)
> @@ -26,4 +26,5 @@ ia64-c.o: $(srcdir)/config/ia64/ia64-c.c
>  # genattrtab generates very long string literals.
>  insn-attrtab.o-warn = -Wno-error
>
> -ia64.o: debug.h $(PARAMS_H) sel-sched.h reload.h $(OPTS_H) dumpfile.h
> +ia64.o: $(srcdir)/config/ia64/ia64.c debug.h $(PARAMS_H) sel-sched.h reload.h \
> +       $(OPTS_H) dumpfile.h $(HASH_TABLE_H)
> Index: gcc/config/ia64/ia64.c
> ===================================================================
> --- gcc/config/ia64/ia64.c      (revision 194511)
> +++ gcc/config/ia64/ia64.c      (working copy)
> @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3.
>  #include "target-def.h"
>  #include "common/common-target.h"
>  #include "tm_p.h"
> -#include "hashtab.h"
> +#include "hash-table.h"
>  #include "langhooks.h"
>  #include "gimple.h"
>  #include "intl.h"
> @@ -259,8 +259,6 @@ static struct bundle_state *get_free_bun
>  static void free_bundle_state (struct bundle_state *);
>  static void initiate_bundle_states (void);
>  static void finish_bundle_states (void);
> -static unsigned bundle_state_hash (const void *);
> -static int bundle_state_eq_p (const void *, const void *);
>  static int insert_bundle_state (struct bundle_state *);
>  static void initiate_bundle_state_table (void);
>  static void finish_bundle_state_table (void);
> @@ -8536,18 +8534,21 @@ finish_bundle_states (void)
>      }
>  }
>
> -/* Hash table of the bundle states.  The key is dfa_state and insn_num
> -   of the bundle states.  */
> +/* Hashtable helpers.  */
>
> -static htab_t bundle_state_table;
> +struct bundle_state_hasher : typed_noop_remove <bundle_state>
> +{
> +  typedef bundle_state value_type;
> +  typedef bundle_state compare_type;
> +  static inline hashval_t hash (const value_type *);
> +  static inline bool equal (const value_type *, const compare_type *);
> +};
>
>  /* The function returns hash of BUNDLE_STATE.  */
>
> -static unsigned
> -bundle_state_hash (const void *bundle_state)
> +inline hashval_t
> +bundle_state_hasher::hash (const value_type *state)
>  {
> -  const struct bundle_state *const state
> -    = (const struct bundle_state *) bundle_state;
>    unsigned result, i;
>
>    for (result = i = 0; i < dfa_state_size; i++)
> @@ -8558,19 +8559,20 @@ bundle_state_hash (const void *bundle_st
>
>  /* The function returns nonzero if the bundle state keys are equal.  */
>
> -static int
> -bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
> +inline bool
> +bundle_state_hasher::equal (const value_type *state1,
> +                           const compare_type *state2)
>  {
> -  const struct bundle_state *const state1
> -    = (const struct bundle_state *) bundle_state_1;
> -  const struct bundle_state *const state2
> -    = (const struct bundle_state *) bundle_state_2;
> -
>    return (state1->insn_num == state2->insn_num
>           && memcmp (state1->dfa_state, state2->dfa_state,
>                      dfa_state_size) == 0);
>  }
>
> +/* Hash table of the bundle states.  The key is dfa_state and insn_num
> +   of the bundle states.  */
> +
> +static hash_table <bundle_state_hasher> bundle_state_table;
> +
>  /* The function inserts the BUNDLE_STATE into the hash table.  The
>     function returns nonzero if the bundle has been inserted into the
>     table.  The table contains the best bundle state with given key.  */
> @@ -8578,39 +8580,35 @@ bundle_state_eq_p (const void *bundle_st
>  static int
>  insert_bundle_state (struct bundle_state *bundle_state)
>  {
> -  void **entry_ptr;
> +  struct bundle_state **entry_ptr;
>
> -  entry_ptr = htab_find_slot (bundle_state_table, bundle_state, INSERT);
> +  entry_ptr = bundle_state_table.find_slot (bundle_state, INSERT);
>    if (*entry_ptr == NULL)
>      {
>        bundle_state->next = index_to_bundle_states [bundle_state->insn_num];
>        index_to_bundle_states [bundle_state->insn_num] = bundle_state;
> -      *entry_ptr = (void *) bundle_state;
> +      *entry_ptr = bundle_state;
>        return TRUE;
>      }
> -  else if (bundle_state->cost < ((struct bundle_state *) *entry_ptr)->cost
> -          || (bundle_state->cost == ((struct bundle_state *) *entry_ptr)->cost
> -              && (((struct bundle_state *)*entry_ptr)->accumulated_insns_num
> +  else if (bundle_state->cost < (*entry_ptr)->cost
> +          || (bundle_state->cost == (*entry_ptr)->cost
> +              && ((*entry_ptr)->accumulated_insns_num
>                    > bundle_state->accumulated_insns_num
> -                  || (((struct bundle_state *)
> -                       *entry_ptr)->accumulated_insns_num
> +                  || ((*entry_ptr)->accumulated_insns_num
>                        == bundle_state->accumulated_insns_num
> -                      && (((struct bundle_state *)
> -                           *entry_ptr)->branch_deviation
> +                      && ((*entry_ptr)->branch_deviation
>                            > bundle_state->branch_deviation
> -                          || (((struct bundle_state *)
> -                               *entry_ptr)->branch_deviation
> +                          || ((*entry_ptr)->branch_deviation
>                                == bundle_state->branch_deviation
> -                              && ((struct bundle_state *)
> -                                  *entry_ptr)->middle_bundle_stops
> +                              && (*entry_ptr)->middle_bundle_stops
>                                > bundle_state->middle_bundle_stops))))))
>
>      {
>        struct bundle_state temp;
>
> -      temp = *(struct bundle_state *) *entry_ptr;
> -      *(struct bundle_state *) *entry_ptr = *bundle_state;
> -      ((struct bundle_state *) *entry_ptr)->next = temp.next;
> +      temp = **entry_ptr;
> +      **entry_ptr = *bundle_state;
> +      (*entry_ptr)->next = temp.next;
>        *bundle_state = temp;
>      }
>    return FALSE;
> @@ -8621,8 +8619,7 @@ insert_bundle_state (struct bundle_state
>  static void
>  initiate_bundle_state_table (void)
>  {
> -  bundle_state_table = htab_create (50, bundle_state_hash, bundle_state_eq_p,
> -                                   (htab_del) 0);
> +  bundle_state_table.create (50);
>  }
>
>  /* Finish work with the hash table.  */
> @@ -8630,7 +8627,7 @@ initiate_bundle_state_table (void)
>  static void
>  finish_bundle_state_table (void)
>  {
> -  htab_delete (bundle_state_table);
> +  bundle_state_table.dispose ();
>  }
>
>
> Index: gcc/config/t-sol2
> ===================================================================
> --- gcc/config/t-sol2   (revision 194511)
> +++ gcc/config/t-sol2   (working copy)
> @@ -34,5 +34,5 @@ sol2-stubs.o: $(srcdir)/config/sol2-stub
>
>  # Solaris-specific attributes
>  sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
> -  tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H)
> +  tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H) $(HASH_TABLE_H)
>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
> Index: gcc/config/mips/mips.c
> ===================================================================
> --- gcc/config/mips/mips.c      (revision 194511)
> +++ gcc/config/mips/mips.c      (working copy)
> @@ -46,7 +46,7 @@ along with GCC; see the file COPYING3.
>  #include "tm_p.h"
>  #include "ggc.h"
>  #include "gstab.h"
> -#include "hashtab.h"
> +#include "hash-table.h"
>  #include "debug.h"
>  #include "target.h"
>  #include "target-def.h"
> @@ -15592,30 +15592,43 @@ mips_hash_base (rtx base)
>    return hash_rtx (base, GET_MODE (base), &do_not_record_p, NULL, false);
>  }
>
> +/* Hashtable helpers.  */
> +
> +struct mips_lo_sum_offset_hasher : typed_free_remove <mips_lo_sum_offset>
> +{
> +  typedef mips_lo_sum_offset value_type;
> +  typedef rtx_def compare_type;
> +  static inline hashval_t hash (const value_type *);
> +  static inline bool equal (const value_type *, const compare_type *);
> +};
> +
>  /* Hash-table callbacks for mips_lo_sum_offsets.  */
>
> -static hashval_t
> -mips_lo_sum_offset_hash (const void *entry)
> +inline hashval_t
> +mips_lo_sum_offset_hasher::hash (const value_type *entry)
>  {
> -  return mips_hash_base (((const struct mips_lo_sum_offset *) entry)->base);
> +  return mips_hash_base (entry->base);
>  }
>
> -static int
> -mips_lo_sum_offset_eq (const void *entry, const void *value)
> +inline bool
> +mips_lo_sum_offset_hasher::equal (const value_type *entry,
> +                                 const compare_type *value)
>  {
> -  return rtx_equal_p (((const struct mips_lo_sum_offset *) entry)->base,
> -                     (const_rtx) value);
> +  return rtx_equal_p (entry->base, value);
>  }
>
> +typedef hash_table <mips_lo_sum_offset_hasher> mips_offset_table;
> +
>  /* Look up symbolic constant X in HTAB, which is a hash table of
>     mips_lo_sum_offsets.  If OPTION is NO_INSERT, return true if X can be
>     paired with a recorded LO_SUM, otherwise record X in the table.  */
>
>  static bool
> -mips_lo_sum_offset_lookup (htab_t htab, rtx x, enum insert_option option)
> +mips_lo_sum_offset_lookup (mips_offset_table htab, rtx x,
> +                          enum insert_option option)
>  {
>    rtx base, offset;
> -  void **slot;
> +  mips_lo_sum_offset **slot;
>    struct mips_lo_sum_offset *entry;
>
>    /* Split X into a base and offset.  */
> @@ -15624,7 +15637,7 @@ mips_lo_sum_offset_lookup (htab_t htab,
>      base = UNSPEC_ADDRESS (base);
>
>    /* Look up the base in the hash table.  */
> -  slot = htab_find_slot_with_hash (htab, base, mips_hash_base (base), option);
> +  slot = htab.find_slot_with_hash (base, mips_hash_base (base), option);
>    if (slot == NULL)
>      return false;
>
> @@ -15654,7 +15667,8 @@ static int
>  mips_record_lo_sum (rtx *loc, void *data)
>  {
>    if (GET_CODE (*loc) == LO_SUM)
> -    mips_lo_sum_offset_lookup ((htab_t) data, XEXP (*loc, 1), INSERT);
> +    mips_lo_sum_offset_lookup (*(mips_offset_table*)data,
> +                              XEXP (*loc, 1), INSERT);
>    return 0;
>  }
>
> @@ -15663,7 +15677,7 @@ mips_record_lo_sum (rtx *loc, void *data
>     LO_SUMs in the current function.  */
>
>  static bool
> -mips_orphaned_high_part_p (htab_t htab, rtx insn)
> +mips_orphaned_high_part_p (mips_offset_table htab, rtx insn)
>  {
>    enum mips_symbol_type type;
>    rtx x, set;
> @@ -15771,7 +15785,7 @@ mips_reorg_process_insns (void)
>  {
>    rtx insn, last_insn, subinsn, next_insn, lo_reg, delayed_reg;
>    int hilo_delay;
> -  htab_t htab;
> +  mips_offset_table htab;
>
>    /* Force all instructions to be split into their final form.  */
>    split_all_insns_noflow ();
> @@ -15808,14 +15822,13 @@ mips_reorg_process_insns (void)
>    if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
>      cfun->machine->all_noreorder_p = false;
>
> -  htab = htab_create (37, mips_lo_sum_offset_hash,
> -                     mips_lo_sum_offset_eq, free);
> +  htab.create (37);
>
>    /* Make a first pass over the instructions, recording all the LO_SUMs.  */
>    for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
>      FOR_EACH_SUBINSN (subinsn, insn)
>        if (USEFUL_INSN_P (subinsn))
> -       for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, htab);
> +       for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, &htab);
>
>    last_insn = 0;
>    hilo_delay = 2;
> @@ -15872,7 +15885,7 @@ mips_reorg_process_insns (void)
>         }
>      }
>
> -  htab_delete (htab);
> +  htab.dispose ();
>  }
>
>  /* Return true if the function has a long branch instruction.  */
>
> --
> Lawrence Crowl
Richard Guenther - Jan. 6, 2013, 11:38 a.m.
On Sun, Jan 6, 2013 at 6:55 AM, Xinliang David Li <davidxl@google.com> wrote:
> I noticed that the traverse and traverse_noresize method takes
> Argument as the first template parameter. It should be moved to be the
> second after the callback. In most of the cases, the type of the
> Argument can be deduced from the callsite, so that the user only need
> to specify the callback:
>
> ht->traverse_noresize<the_call_back_function>(&arg);
>
> In the current way, user has to do this:
>
> ht->traverse_noresize<arg_type, the_call_back_function> (&arg);
>
> which is not as friendly.

Agreed.

> David
>
>
> On Tue, Dec 18, 2012 at 8:02 PM, Lawrence Crowl <crowl@googlers.com> wrote:
>> Update various config htab_t uses to hash_table.
>>
>> Modify types and calls to match.
>>
>> * config/arm/arm.c'arm_libcall_uses_aapcs_base::libcall_htab
>>
>> Fold libcall_eq and libcall_hash into new struct libcall_hasher.
>>
>> * config/ia64/ia64.c'bundle_state_table
>>
>> Fold bundle_state_hash and bundle_state_eq_p into new struct
>> bundle_state_hasher.
>>
>> * config/mips/mips.c'mips_offset_table
>>
>> Fold mips_lo_sum_offset_hash and mips_lo_sum_offset_eq into new
>> struct mips_lo_sum_offset_hasher.
>>
>> In mips_reorg_process_insns, change call to for_each_rtx to pass
>> a pointer to the hash_table rather than a htab_t.  This change
>> requires then dereferencing that pointer in mips_record_lo_sum to
>> obtain the hash_table.
>>
>> * config/sol2.c'solaris_comdat_htab
>>
>> Fold comdat_hash and comdat_eq into new struct comdat_entry_hasher.
>>
>> * config/i386/winnt.c'i386_pe_section_type_flags::htab
>>
>> * config/i386/winnt.c'i386_find_on_wrapper_list::wrappers
>>
>> Fold wrapper_strcmp into new struct wrapped_symbol_hasher.
>>
>>
>> Tested on x86-64.
>> Tested with contrib/config-list.mk.
>>
>>
>> Okay for branch?
>>
>>
>> Index: gcc/config/arm/arm.c
>> ===================================================================
>> --- gcc/config/arm/arm.c        (revision 194511)
>> +++ gcc/config/arm/arm.c        (working copy)
>> @@ -25,6 +25,7 @@
>>  #include "config.h"
>>  #include "system.h"
>>  #include "coretypes.h"
>> +#include "hash-table.h"
>>  #include "tm.h"
>>  #include "rtl.h"
>>  #include "tree.h"
>> @@ -3716,36 +3717,48 @@ arm_function_value(const_tree type, cons
>>    return arm_libcall_value_1 (mode);
>>  }
>>
>> -static int
>> -libcall_eq (const void *p1, const void *p2)
>> +/* libcall hashtable helpers.  */
>> +
>> +struct libcall_hasher : typed_noop_remove <rtx_def>
>>  {
>> -  return rtx_equal_p ((const_rtx) p1, (const_rtx) p2);
>> +  typedef rtx_def value_type;
>> +  typedef rtx_def 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 *);
>> +};
>> +
>> +inline bool
>> +libcall_hasher::equal (const value_type *p1, const compare_type *p2)
>> +{
>> +  return rtx_equal_p (p1, p2);
>>  }
>>
>> -static hashval_t
>> -libcall_hash (const void *p1)
>> +inline hashval_t
>> +libcall_hasher::hash (const value_type *p1)
>>  {
>> -  return hash_rtx ((const_rtx) p1, VOIDmode, NULL, NULL, FALSE);
>> +  return hash_rtx (p1, VOIDmode, NULL, NULL, FALSE);
>>  }
>>
>> +typedef hash_table <libcall_hasher> libcall_table_type;
>> +
>>  static void
>> -add_libcall (htab_t htab, rtx libcall)
>> +add_libcall (libcall_table_type htab, rtx libcall)
>>  {
>> -  *htab_find_slot (htab, libcall, INSERT) = libcall;
>> +  *htab.find_slot (libcall, INSERT) = libcall;
>>  }
>>
>>  static bool
>>  arm_libcall_uses_aapcs_base (const_rtx libcall)
>>  {
>>    static bool init_done = false;
>> -  static htab_t libcall_htab;
>> +  static libcall_table_type libcall_htab;
>>
>>    if (!init_done)
>>      {
>>        init_done = true;
>>
>> -      libcall_htab = htab_create (31, libcall_hash, libcall_eq,
>> -                                 NULL);
>> +      libcall_htab.create (31);
>>        add_libcall (libcall_htab,
>>                    convert_optab_libfunc (sfloat_optab, SFmode, SImode));
>>        add_libcall (libcall_htab,
>> @@ -3804,7 +3817,7 @@ arm_libcall_uses_aapcs_base (const_rtx l
>>                                                         DFmode));
>>      }
>>
>> -  return libcall && htab_find (libcall_htab, libcall) != NULL;
>> +  return libcall && libcall_htab.find (libcall) != NULL;
>>  }
>>
>>  static rtx
>> Index: gcc/config/arm/t-arm
>> ===================================================================
>> --- gcc/config/arm/t-arm        (revision 194511)
>> +++ gcc/config/arm/t-arm        (working copy)
>> @@ -73,8 +73,8 @@ $(srcdir)/config/arm/arm-tables.opt: $(s
>>         $(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
>>                 $(srcdir)/config/arm/arm-tables.opt
>>
>> -arm.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>> -  $(RTL_H) $(TREE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
>> +arm.o: $(srcdir)/config/arm/arm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>> +  $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
>>    insn-config.h conditions.h output.h dumpfile.h \
>>    $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \
>>    $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \
>> Index: gcc/config/i386/winnt.c
>> ===================================================================
>> --- gcc/config/i386/winnt.c     (revision 194511)
>> +++ gcc/config/i386/winnt.c     (working copy)
>> @@ -31,7 +31,7 @@ along with GCC; see the file COPYING3.
>>  #include "flags.h"
>>  #include "tm_p.h"
>>  #include "diagnostic-core.h"
>> -#include "hashtab.h"
>> +#include "hash-table.h"
>>  #include "langhooks.h"
>>  #include "ggc.h"
>>  #include "target.h"
>> @@ -449,7 +449,7 @@ i386_pe_reloc_rw_mask (void)
>>  unsigned int
>>  i386_pe_section_type_flags (tree decl, const char *name, int reloc)
>>  {
>> -  static htab_t htab;
>> +  static hash_table <pointer_hash <unsigned int> > htab;
>>    unsigned int flags;
>>    unsigned int **slot;
>>
>> @@ -460,8 +460,8 @@ i386_pe_section_type_flags (tree decl, c
>>    /* The names we put in the hashtable will always be the unique
>>       versions given to us by the stringtable, so we can just use
>>       their addresses as the keys.  */
>> -  if (!htab)
>> -    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
>> +  if (!htab.is_created ())
>> +    htab.create (31);
>>
>>    if (decl && TREE_CODE (decl) == FUNCTION_DECL)
>>      flags = SECTION_CODE;
>> @@ -480,7 +480,7 @@ i386_pe_section_type_flags (tree decl, c
>>      flags |= SECTION_LINKONCE;
>>
>>    /* See if we already have an entry for this section.  */
>> -  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
>> +  slot = htab.find_slot ((unsigned int *)name, INSERT);
>>    if (!*slot)
>>      {
>>        *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
>> @@ -680,12 +680,29 @@ i386_pe_maybe_record_exported_symbol (tr
>>
>>  #ifdef CXX_WRAP_SPEC_LIST
>>
>> +/* Hashtable helpers.  */
>> +
>> +struct wrapped_symbol_hasher : typed_noop_remove <char>
>> +{
>> +  typedef char value_type;
>> +  typedef char 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 *);
>> +};
>> +
>> +inline hashval_t
>> +wrapped_symbol_hasher::hash (const value_type *v)
>> +{
>> +  return htab_hash_string (v);
>> +}
>> +
>>  /*  Hash table equality helper function.  */
>>
>> -static int
>> -wrapper_strcmp (const void *x, const void *y)
>> +inline bool
>> +wrapped_symbol_hasher::equal (const value_type *x, const compare_type *y)
>>  {
>> -  return !strcmp ((const char *) x, (const char *) y);
>> +  return !strcmp (x, y);
>>  }
>>
>>  /* Search for a function named TARGET in the list of library wrappers
>> @@ -699,7 +716,7 @@ static const char *
>>  i386_find_on_wrapper_list (const char *target)
>>  {
>>    static char first_time = 1;
>> -  static htab_t wrappers;
>> +  static hash_table <wrapped_symbol_hasher> wrappers;
>>
>>    if (first_time)
>>      {
>> @@ -712,8 +729,7 @@ i386_find_on_wrapper_list (const char *t
>>        char *bufptr;
>>        /* Breaks up the char array into separated strings
>>           strings and enter them into the hash table.  */
>> -      wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
>> -       0, xcalloc, free);
>> +      wrappers.create (8);
>>        for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
>>         {
>>           char *found = NULL;
>> @@ -726,12 +742,12 @@ i386_find_on_wrapper_list (const char *t
>>           if (*bufptr)
>>             *bufptr = 0;
>>           if (found)
>> -           *htab_find_slot (wrappers, found, INSERT) = found;
>> +           *wrappers.find_slot (found, INSERT) = found;
>>         }
>>        first_time = 0;
>>      }
>>
>> -  return (const char *) htab_find (wrappers, target);
>> +  return wrappers.find (target);
>>  }
>>
>>  #endif /* CXX_WRAP_SPEC_LIST */
>> Index: gcc/config/i386/t-interix
>> ===================================================================
>> --- gcc/config/i386/t-interix   (revision 194511)
>> +++ gcc/config/i386/t-interix   (working copy)
>> @@ -19,7 +19,7 @@
>>
>>  winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>>    $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
>> -  $(TM_P_H) $(HASHTAB_H) $(GGC_H)
>> +  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H)
>>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
>>                 $(srcdir)/config/i386/winnt.c
>>
>> Index: gcc/config/i386/t-cygming
>> ===================================================================
>> --- gcc/config/i386/t-cygming   (revision 194511)
>> +++ gcc/config/i386/t-cygming   (working copy)
>> @@ -23,7 +23,7 @@ LIMITS_H_TEST = true
>>
>>  winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>>    $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
>> -  $(TM_P_H) $(HASHTAB_H) $(GGC_H) $(LTO_STREAMER_H)
>> +  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H) $(LTO_STREAMER_H)
>>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
>>         $(srcdir)/config/i386/winnt.c
>>
>> Index: gcc/config/sol2.c
>> ===================================================================
>> --- gcc/config/sol2.c   (revision 194511)
>> +++ gcc/config/sol2.c   (working copy)
>> @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.
>>  #include "tm_p.h"
>>  #include "diagnostic-core.h"
>>  #include "ggc.h"
>> -#include "hashtab.h"
>> +#include "hash-table.h"
>>
>>  tree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;
>>
>> @@ -158,10 +158,6 @@ solaris_assemble_visibility (tree decl A
>>  #endif
>>  }
>>
>> -/* Hash table of group signature symbols.  */
>> -
>> -static htab_t solaris_comdat_htab;
>> -
>>  /* Group section information entry stored in solaris_comdat_htab.  */
>>
>>  typedef struct comdat_entry
>> @@ -172,25 +168,34 @@ typedef struct comdat_entry
>>    const char *sig;
>>  } comdat_entry;
>>
>> -/* Helper routines for maintaining solaris_comdat_htab.  */
>> +/* Helpers for maintaining solaris_comdat_htab.  */
>>
>> -static hashval_t
>> -comdat_hash (const void *p)
>> +struct comdat_entry_hasher : typed_noop_remove <comdat_entry>
>>  {
>> -  const comdat_entry *entry = (const comdat_entry *) p;
>> +  typedef comdat_entry value_type;
>> +  typedef comdat_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 *);
>> +};
>>
>> +inline hashval_t
>> +comdat_entry_hasher::hash (const value_type *entry)
>> +{
>>    return htab_hash_string (entry->sig);
>>  }
>>
>> -static int
>> -comdat_eq (const void *p1, const void *p2)
>> +inline bool
>> +comdat_entry_hasher::equal (const value_type *entry1,
>> +                           const compare_type *entry2)
>>  {
>> -  const comdat_entry *entry1 = (const comdat_entry *) p1;
>> -  const comdat_entry *entry2 = (const comdat_entry *) p2;
>> -
>>    return strcmp (entry1->sig, entry2->sig) == 0;
>>  }
>>
>> +/* Hash table of group signature symbols.  */
>> +
>> +static hash_table <comdat_entry_hasher> solaris_comdat_htab;
>> +
>>  /* Output assembly to switch to COMDAT group section NAME with attributes
>>     FLAGS and group signature symbol DECL, using Sun as syntax.  */
>>
>> @@ -230,12 +235,11 @@ solaris_elf_asm_comdat_section (const ch
>>       identify the missing ones without changing the affected frontents,
>>       remember the signature symbols and emit those not marked
>>       TREE_SYMBOL_REFERENCED in solaris_file_end.  */
>> -  if (solaris_comdat_htab == NULL)
>> -    solaris_comdat_htab = htab_create_alloc (37, comdat_hash, comdat_eq, NULL,
>> -                                            xcalloc, free);
>> +  if (!solaris_comdat_htab.is_created ())
>> +    solaris_comdat_htab.create (37);
>>
>>    entry.sig = signature;
>> -  slot = (comdat_entry **) htab_find_slot (solaris_comdat_htab,
>> &entry, INSERT);
>> +  slot = solaris_comdat_htab.find_slot (&entry, INSERT);
>>
>>    if (*slot == NULL)
>>      {
>> @@ -251,10 +255,11 @@ solaris_elf_asm_comdat_section (const ch
>>
>>  /* Define unreferenced COMDAT group signature symbol corresponding to SLOT.  */
>>
>> -static int
>> -solaris_define_comdat_signature (void **slot, void *aux ATTRIBUTE_UNUSED)
>> +int
>> +solaris_define_comdat_signature (comdat_entry **slot,
>> +                                void *aux ATTRIBUTE_UNUSED)
>>  {
>> -  comdat_entry *entry = *(comdat_entry **) slot;
>> +  comdat_entry *entry = *slot;
>>    tree decl = entry->decl;
>>
>>    if (TREE_CODE (decl) != IDENTIFIER_NODE)
>> @@ -278,10 +283,10 @@ solaris_define_comdat_signature (void **
>>  void
>>  solaris_file_end (void)
>>  {
>> -  if (solaris_comdat_htab == NULL)
>> +  if (!solaris_comdat_htab.is_created ())
>>      return;
>>
>> -  htab_traverse (solaris_comdat_htab, solaris_define_comdat_signature, NULL);
>> +  solaris_comdat_htab.traverse <void *,
>> solaris_define_comdat_signature> (NULL);
>>  }
>>
>>  void
>> Index: gcc/config/ia64/t-ia64
>> ===================================================================
>> --- gcc/config/ia64/t-ia64      (revision 194511)
>> +++ gcc/config/ia64/t-ia64      (working copy)
>> @@ -26,4 +26,5 @@ ia64-c.o: $(srcdir)/config/ia64/ia64-c.c
>>  # genattrtab generates very long string literals.
>>  insn-attrtab.o-warn = -Wno-error
>>
>> -ia64.o: debug.h $(PARAMS_H) sel-sched.h reload.h $(OPTS_H) dumpfile.h
>> +ia64.o: $(srcdir)/config/ia64/ia64.c debug.h $(PARAMS_H) sel-sched.h reload.h \
>> +       $(OPTS_H) dumpfile.h $(HASH_TABLE_H)
>> Index: gcc/config/ia64/ia64.c
>> ===================================================================
>> --- gcc/config/ia64/ia64.c      (revision 194511)
>> +++ gcc/config/ia64/ia64.c      (working copy)
>> @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3.
>>  #include "target-def.h"
>>  #include "common/common-target.h"
>>  #include "tm_p.h"
>> -#include "hashtab.h"
>> +#include "hash-table.h"
>>  #include "langhooks.h"
>>  #include "gimple.h"
>>  #include "intl.h"
>> @@ -259,8 +259,6 @@ static struct bundle_state *get_free_bun
>>  static void free_bundle_state (struct bundle_state *);
>>  static void initiate_bundle_states (void);
>>  static void finish_bundle_states (void);
>> -static unsigned bundle_state_hash (const void *);
>> -static int bundle_state_eq_p (const void *, const void *);
>>  static int insert_bundle_state (struct bundle_state *);
>>  static void initiate_bundle_state_table (void);
>>  static void finish_bundle_state_table (void);
>> @@ -8536,18 +8534,21 @@ finish_bundle_states (void)
>>      }
>>  }
>>
>> -/* Hash table of the bundle states.  The key is dfa_state and insn_num
>> -   of the bundle states.  */
>> +/* Hashtable helpers.  */
>>
>> -static htab_t bundle_state_table;
>> +struct bundle_state_hasher : typed_noop_remove <bundle_state>
>> +{
>> +  typedef bundle_state value_type;
>> +  typedef bundle_state compare_type;
>> +  static inline hashval_t hash (const value_type *);
>> +  static inline bool equal (const value_type *, const compare_type *);
>> +};
>>
>>  /* The function returns hash of BUNDLE_STATE.  */
>>
>> -static unsigned
>> -bundle_state_hash (const void *bundle_state)
>> +inline hashval_t
>> +bundle_state_hasher::hash (const value_type *state)
>>  {
>> -  const struct bundle_state *const state
>> -    = (const struct bundle_state *) bundle_state;
>>    unsigned result, i;
>>
>>    for (result = i = 0; i < dfa_state_size; i++)
>> @@ -8558,19 +8559,20 @@ bundle_state_hash (const void *bundle_st
>>
>>  /* The function returns nonzero if the bundle state keys are equal.  */
>>
>> -static int
>> -bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
>> +inline bool
>> +bundle_state_hasher::equal (const value_type *state1,
>> +                           const compare_type *state2)
>>  {
>> -  const struct bundle_state *const state1
>> -    = (const struct bundle_state *) bundle_state_1;
>> -  const struct bundle_state *const state2
>> -    = (const struct bundle_state *) bundle_state_2;
>> -
>>    return (state1->insn_num == state2->insn_num
>>           && memcmp (state1->dfa_state, state2->dfa_state,
>>                      dfa_state_size) == 0);
>>  }
>>
>> +/* Hash table of the bundle states.  The key is dfa_state and insn_num
>> +   of the bundle states.  */
>> +
>> +static hash_table <bundle_state_hasher> bundle_state_table;
>> +
>>  /* The function inserts the BUNDLE_STATE into the hash table.  The
>>     function returns nonzero if the bundle has been inserted into the
>>     table.  The table contains the best bundle state with given key.  */
>> @@ -8578,39 +8580,35 @@ bundle_state_eq_p (const void *bundle_st
>>  static int
>>  insert_bundle_state (struct bundle_state *bundle_state)
>>  {
>> -  void **entry_ptr;
>> +  struct bundle_state **entry_ptr;
>>
>> -  entry_ptr = htab_find_slot (bundle_state_table, bundle_state, INSERT);
>> +  entry_ptr = bundle_state_table.find_slot (bundle_state, INSERT);
>>    if (*entry_ptr == NULL)
>>      {
>>        bundle_state->next = index_to_bundle_states [bundle_state->insn_num];
>>        index_to_bundle_states [bundle_state->insn_num] = bundle_state;
>> -      *entry_ptr = (void *) bundle_state;
>> +      *entry_ptr = bundle_state;
>>        return TRUE;
>>      }
>> -  else if (bundle_state->cost < ((struct bundle_state *) *entry_ptr)->cost
>> -          || (bundle_state->cost == ((struct bundle_state *) *entry_ptr)->cost
>> -              && (((struct bundle_state *)*entry_ptr)->accumulated_insns_num
>> +  else if (bundle_state->cost < (*entry_ptr)->cost
>> +          || (bundle_state->cost == (*entry_ptr)->cost
>> +              && ((*entry_ptr)->accumulated_insns_num
>>                    > bundle_state->accumulated_insns_num
>> -                  || (((struct bundle_state *)
>> -                       *entry_ptr)->accumulated_insns_num
>> +                  || ((*entry_ptr)->accumulated_insns_num
>>                        == bundle_state->accumulated_insns_num
>> -                      && (((struct bundle_state *)
>> -                           *entry_ptr)->branch_deviation
>> +                      && ((*entry_ptr)->branch_deviation
>>                            > bundle_state->branch_deviation
>> -                          || (((struct bundle_state *)
>> -                               *entry_ptr)->branch_deviation
>> +                          || ((*entry_ptr)->branch_deviation
>>                                == bundle_state->branch_deviation
>> -                              && ((struct bundle_state *)
>> -                                  *entry_ptr)->middle_bundle_stops
>> +                              && (*entry_ptr)->middle_bundle_stops
>>                                > bundle_state->middle_bundle_stops))))))
>>
>>      {
>>        struct bundle_state temp;
>>
>> -      temp = *(struct bundle_state *) *entry_ptr;
>> -      *(struct bundle_state *) *entry_ptr = *bundle_state;
>> -      ((struct bundle_state *) *entry_ptr)->next = temp.next;
>> +      temp = **entry_ptr;
>> +      **entry_ptr = *bundle_state;
>> +      (*entry_ptr)->next = temp.next;
>>        *bundle_state = temp;
>>      }
>>    return FALSE;
>> @@ -8621,8 +8619,7 @@ insert_bundle_state (struct bundle_state
>>  static void
>>  initiate_bundle_state_table (void)
>>  {
>> -  bundle_state_table = htab_create (50, bundle_state_hash, bundle_state_eq_p,
>> -                                   (htab_del) 0);
>> +  bundle_state_table.create (50);
>>  }
>>
>>  /* Finish work with the hash table.  */
>> @@ -8630,7 +8627,7 @@ initiate_bundle_state_table (void)
>>  static void
>>  finish_bundle_state_table (void)
>>  {
>> -  htab_delete (bundle_state_table);
>> +  bundle_state_table.dispose ();
>>  }
>>
>>
>> Index: gcc/config/t-sol2
>> ===================================================================
>> --- gcc/config/t-sol2   (revision 194511)
>> +++ gcc/config/t-sol2   (working copy)
>> @@ -34,5 +34,5 @@ sol2-stubs.o: $(srcdir)/config/sol2-stub
>>
>>  # Solaris-specific attributes
>>  sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>> -  tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H)
>> +  tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H) $(HASH_TABLE_H)
>>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
>> Index: gcc/config/mips/mips.c
>> ===================================================================
>> --- gcc/config/mips/mips.c      (revision 194511)
>> +++ gcc/config/mips/mips.c      (working copy)
>> @@ -46,7 +46,7 @@ along with GCC; see the file COPYING3.
>>  #include "tm_p.h"
>>  #include "ggc.h"
>>  #include "gstab.h"
>> -#include "hashtab.h"
>> +#include "hash-table.h"
>>  #include "debug.h"
>>  #include "target.h"
>>  #include "target-def.h"
>> @@ -15592,30 +15592,43 @@ mips_hash_base (rtx base)
>>    return hash_rtx (base, GET_MODE (base), &do_not_record_p, NULL, false);
>>  }
>>
>> +/* Hashtable helpers.  */
>> +
>> +struct mips_lo_sum_offset_hasher : typed_free_remove <mips_lo_sum_offset>
>> +{
>> +  typedef mips_lo_sum_offset value_type;
>> +  typedef rtx_def compare_type;
>> +  static inline hashval_t hash (const value_type *);
>> +  static inline bool equal (const value_type *, const compare_type *);
>> +};
>> +
>>  /* Hash-table callbacks for mips_lo_sum_offsets.  */
>>
>> -static hashval_t
>> -mips_lo_sum_offset_hash (const void *entry)
>> +inline hashval_t
>> +mips_lo_sum_offset_hasher::hash (const value_type *entry)
>>  {
>> -  return mips_hash_base (((const struct mips_lo_sum_offset *) entry)->base);
>> +  return mips_hash_base (entry->base);
>>  }
>>
>> -static int
>> -mips_lo_sum_offset_eq (const void *entry, const void *value)
>> +inline bool
>> +mips_lo_sum_offset_hasher::equal (const value_type *entry,
>> +                                 const compare_type *value)
>>  {
>> -  return rtx_equal_p (((const struct mips_lo_sum_offset *) entry)->base,
>> -                     (const_rtx) value);
>> +  return rtx_equal_p (entry->base, value);
>>  }
>>
>> +typedef hash_table <mips_lo_sum_offset_hasher> mips_offset_table;
>> +
>>  /* Look up symbolic constant X in HTAB, which is a hash table of
>>     mips_lo_sum_offsets.  If OPTION is NO_INSERT, return true if X can be
>>     paired with a recorded LO_SUM, otherwise record X in the table.  */
>>
>>  static bool
>> -mips_lo_sum_offset_lookup (htab_t htab, rtx x, enum insert_option option)
>> +mips_lo_sum_offset_lookup (mips_offset_table htab, rtx x,
>> +                          enum insert_option option)
>>  {
>>    rtx base, offset;
>> -  void **slot;
>> +  mips_lo_sum_offset **slot;
>>    struct mips_lo_sum_offset *entry;
>>
>>    /* Split X into a base and offset.  */
>> @@ -15624,7 +15637,7 @@ mips_lo_sum_offset_lookup (htab_t htab,
>>      base = UNSPEC_ADDRESS (base);
>>
>>    /* Look up the base in the hash table.  */
>> -  slot = htab_find_slot_with_hash (htab, base, mips_hash_base (base), option);
>> +  slot = htab.find_slot_with_hash (base, mips_hash_base (base), option);
>>    if (slot == NULL)
>>      return false;
>>
>> @@ -15654,7 +15667,8 @@ static int
>>  mips_record_lo_sum (rtx *loc, void *data)
>>  {
>>    if (GET_CODE (*loc) == LO_SUM)
>> -    mips_lo_sum_offset_lookup ((htab_t) data, XEXP (*loc, 1), INSERT);
>> +    mips_lo_sum_offset_lookup (*(mips_offset_table*)data,
>> +                              XEXP (*loc, 1), INSERT);
>>    return 0;
>>  }
>>
>> @@ -15663,7 +15677,7 @@ mips_record_lo_sum (rtx *loc, void *data
>>     LO_SUMs in the current function.  */
>>
>>  static bool
>> -mips_orphaned_high_part_p (htab_t htab, rtx insn)
>> +mips_orphaned_high_part_p (mips_offset_table htab, rtx insn)
>>  {
>>    enum mips_symbol_type type;
>>    rtx x, set;
>> @@ -15771,7 +15785,7 @@ mips_reorg_process_insns (void)
>>  {
>>    rtx insn, last_insn, subinsn, next_insn, lo_reg, delayed_reg;
>>    int hilo_delay;
>> -  htab_t htab;
>> +  mips_offset_table htab;
>>
>>    /* Force all instructions to be split into their final form.  */
>>    split_all_insns_noflow ();
>> @@ -15808,14 +15822,13 @@ mips_reorg_process_insns (void)
>>    if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
>>      cfun->machine->all_noreorder_p = false;
>>
>> -  htab = htab_create (37, mips_lo_sum_offset_hash,
>> -                     mips_lo_sum_offset_eq, free);
>> +  htab.create (37);
>>
>>    /* Make a first pass over the instructions, recording all the LO_SUMs.  */
>>    for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
>>      FOR_EACH_SUBINSN (subinsn, insn)
>>        if (USEFUL_INSN_P (subinsn))
>> -       for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, htab);
>> +       for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, &htab);
>>
>>    last_insn = 0;
>>    hilo_delay = 2;
>> @@ -15872,7 +15885,7 @@ mips_reorg_process_insns (void)
>>         }
>>      }
>>
>> -  htab_delete (htab);
>> +  htab.dispose ();
>>  }
>>
>>  /* Return true if the function has a long branch instruction.  */
>>
>> --
>> Lawrence Crowl
Lawrence Crowl - Jan. 6, 2013, 10:47 p.m.
On 1/6/13, Richard Biener <richard.guenther@gmail.com> wrote:
> On Sun, Jan 6, 2013 at 6:55 AM, Xinliang David Li <davidxl@google.com> wrote:
>> I noticed that the traverse and traverse_noresize method takes
>> Argument as the first template parameter. It should be moved to be the
>> second after the callback. In most of the cases, the type of the
>> Argument can be deduced from the callsite, so that the user only need
>> to specify the callback:
>>
>> ht->traverse_noresize<the_call_back_function>(&arg);
>>
>> In the current way, user has to do this:
>>
>> ht->traverse_noresize<arg_type, the_call_back_function> (&arg);
>>
>> which is not as friendly.
>
> Agreed.

Agreed.  The current structure was handy in the conversion process.
Now that the conversion is done, we could change the order.

>> David
>>
>>
>> On Tue, Dec 18, 2012 at 8:02 PM, Lawrence Crowl <crowl@googlers.com>
>> wrote:
>>> Update various config htab_t uses to hash_table.
>>>
>>> Modify types and calls to match.
>>>
>>> * config/arm/arm.c'arm_libcall_uses_aapcs_base::libcall_htab
>>>
>>> Fold libcall_eq and libcall_hash into new struct libcall_hasher.
>>>
>>> * config/ia64/ia64.c'bundle_state_table
>>>
>>> Fold bundle_state_hash and bundle_state_eq_p into new struct
>>> bundle_state_hasher.
>>>
>>> * config/mips/mips.c'mips_offset_table
>>>
>>> Fold mips_lo_sum_offset_hash and mips_lo_sum_offset_eq into new
>>> struct mips_lo_sum_offset_hasher.
>>>
>>> In mips_reorg_process_insns, change call to for_each_rtx to pass
>>> a pointer to the hash_table rather than a htab_t.  This change
>>> requires then dereferencing that pointer in mips_record_lo_sum to
>>> obtain the hash_table.
>>>
>>> * config/sol2.c'solaris_comdat_htab
>>>
>>> Fold comdat_hash and comdat_eq into new struct comdat_entry_hasher.
>>>
>>> * config/i386/winnt.c'i386_pe_section_type_flags::htab
>>>
>>> * config/i386/winnt.c'i386_find_on_wrapper_list::wrappers
>>>
>>> Fold wrapper_strcmp into new struct wrapped_symbol_hasher.
>>>
>>>
>>> Tested on x86-64.
>>> Tested with contrib/config-list.mk.
>>>
>>>
>>> Okay for branch?
>>>
>>>
>>> Index: gcc/config/arm/arm.c
>>> ===================================================================
>>> --- gcc/config/arm/arm.c        (revision 194511)
>>> +++ gcc/config/arm/arm.c        (working copy)
>>> @@ -25,6 +25,7 @@
>>>  #include "config.h"
>>>  #include "system.h"
>>>  #include "coretypes.h"
>>> +#include "hash-table.h"
>>>  #include "tm.h"
>>>  #include "rtl.h"
>>>  #include "tree.h"
>>> @@ -3716,36 +3717,48 @@ arm_function_value(const_tree type, cons
>>>    return arm_libcall_value_1 (mode);
>>>  }
>>>
>>> -static int
>>> -libcall_eq (const void *p1, const void *p2)
>>> +/* libcall hashtable helpers.  */
>>> +
>>> +struct libcall_hasher : typed_noop_remove <rtx_def>
>>>  {
>>> -  return rtx_equal_p ((const_rtx) p1, (const_rtx) p2);
>>> +  typedef rtx_def value_type;
>>> +  typedef rtx_def 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 *);
>>> +};
>>> +
>>> +inline bool
>>> +libcall_hasher::equal (const value_type *p1, const compare_type *p2)
>>> +{
>>> +  return rtx_equal_p (p1, p2);
>>>  }
>>>
>>> -static hashval_t
>>> -libcall_hash (const void *p1)
>>> +inline hashval_t
>>> +libcall_hasher::hash (const value_type *p1)
>>>  {
>>> -  return hash_rtx ((const_rtx) p1, VOIDmode, NULL, NULL, FALSE);
>>> +  return hash_rtx (p1, VOIDmode, NULL, NULL, FALSE);
>>>  }
>>>
>>> +typedef hash_table <libcall_hasher> libcall_table_type;
>>> +
>>>  static void
>>> -add_libcall (htab_t htab, rtx libcall)
>>> +add_libcall (libcall_table_type htab, rtx libcall)
>>>  {
>>> -  *htab_find_slot (htab, libcall, INSERT) = libcall;
>>> +  *htab.find_slot (libcall, INSERT) = libcall;
>>>  }
>>>
>>>  static bool
>>>  arm_libcall_uses_aapcs_base (const_rtx libcall)
>>>  {
>>>    static bool init_done = false;
>>> -  static htab_t libcall_htab;
>>> +  static libcall_table_type libcall_htab;
>>>
>>>    if (!init_done)
>>>      {
>>>        init_done = true;
>>>
>>> -      libcall_htab = htab_create (31, libcall_hash, libcall_eq,
>>> -                                 NULL);
>>> +      libcall_htab.create (31);
>>>        add_libcall (libcall_htab,
>>>                    convert_optab_libfunc (sfloat_optab, SFmode,
>>> SImode));
>>>        add_libcall (libcall_htab,
>>> @@ -3804,7 +3817,7 @@ arm_libcall_uses_aapcs_base (const_rtx l
>>>                                                         DFmode));
>>>      }
>>>
>>> -  return libcall && htab_find (libcall_htab, libcall) != NULL;
>>> +  return libcall && libcall_htab.find (libcall) != NULL;
>>>  }
>>>
>>>  static rtx
>>> Index: gcc/config/arm/t-arm
>>> ===================================================================
>>> --- gcc/config/arm/t-arm        (revision 194511)
>>> +++ gcc/config/arm/t-arm        (working copy)
>>> @@ -73,8 +73,8 @@ $(srcdir)/config/arm/arm-tables.opt: $(s
>>>         $(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
>>>                 $(srcdir)/config/arm/arm-tables.opt
>>>
>>> -arm.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
>>> -  $(RTL_H) $(TREE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
>>> +arm.o: $(srcdir)/config/arm/arm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h
>>> $(TM_H) \
>>> +  $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H)
>>> hard-reg-set.h \
>>>    insn-config.h conditions.h output.h dumpfile.h \
>>>    $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \
>>>    $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \
>>> Index: gcc/config/i386/winnt.c
>>> ===================================================================
>>> --- gcc/config/i386/winnt.c     (revision 194511)
>>> +++ gcc/config/i386/winnt.c     (working copy)
>>> @@ -31,7 +31,7 @@ along with GCC; see the file COPYING3.
>>>  #include "flags.h"
>>>  #include "tm_p.h"
>>>  #include "diagnostic-core.h"
>>> -#include "hashtab.h"
>>> +#include "hash-table.h"
>>>  #include "langhooks.h"
>>>  #include "ggc.h"
>>>  #include "target.h"
>>> @@ -449,7 +449,7 @@ i386_pe_reloc_rw_mask (void)
>>>  unsigned int
>>>  i386_pe_section_type_flags (tree decl, const char *name, int reloc)
>>>  {
>>> -  static htab_t htab;
>>> +  static hash_table <pointer_hash <unsigned int> > htab;
>>>    unsigned int flags;
>>>    unsigned int **slot;
>>>
>>> @@ -460,8 +460,8 @@ i386_pe_section_type_flags (tree decl, c
>>>    /* The names we put in the hashtable will always be the unique
>>>       versions given to us by the stringtable, so we can just use
>>>       their addresses as the keys.  */
>>> -  if (!htab)
>>> -    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
>>> +  if (!htab.is_created ())
>>> +    htab.create (31);
>>>
>>>    if (decl && TREE_CODE (decl) == FUNCTION_DECL)
>>>      flags = SECTION_CODE;
>>> @@ -480,7 +480,7 @@ i386_pe_section_type_flags (tree decl, c
>>>      flags |= SECTION_LINKONCE;
>>>
>>>    /* See if we already have an entry for this section.  */
>>> -  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
>>> +  slot = htab.find_slot ((unsigned int *)name, INSERT);
>>>    if (!*slot)
>>>      {
>>>        *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
>>> @@ -680,12 +680,29 @@ i386_pe_maybe_record_exported_symbol (tr
>>>
>>>  #ifdef CXX_WRAP_SPEC_LIST
>>>
>>> +/* Hashtable helpers.  */
>>> +
>>> +struct wrapped_symbol_hasher : typed_noop_remove <char>
>>> +{
>>> +  typedef char value_type;
>>> +  typedef char 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 *);
>>> +};
>>> +
>>> +inline hashval_t
>>> +wrapped_symbol_hasher::hash (const value_type *v)
>>> +{
>>> +  return htab_hash_string (v);
>>> +}
>>> +
>>>  /*  Hash table equality helper function.  */
>>>
>>> -static int
>>> -wrapper_strcmp (const void *x, const void *y)
>>> +inline bool
>>> +wrapped_symbol_hasher::equal (const value_type *x, const compare_type
>>> *y)
>>>  {
>>> -  return !strcmp ((const char *) x, (const char *) y);
>>> +  return !strcmp (x, y);
>>>  }
>>>
>>>  /* Search for a function named TARGET in the list of library wrappers
>>> @@ -699,7 +716,7 @@ static const char *
>>>  i386_find_on_wrapper_list (const char *target)
>>>  {
>>>    static char first_time = 1;
>>> -  static htab_t wrappers;
>>> +  static hash_table <wrapped_symbol_hasher> wrappers;
>>>
>>>    if (first_time)
>>>      {
>>> @@ -712,8 +729,7 @@ i386_find_on_wrapper_list (const char *t
>>>        char *bufptr;
>>>        /* Breaks up the char array into separated strings
>>>           strings and enter them into the hash table.  */
>>> -      wrappers = htab_create_alloc (8, htab_hash_string,
>>> wrapper_strcmp,
>>> -       0, xcalloc, free);
>>> +      wrappers.create (8);
>>>        for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
>>>         {
>>>           char *found = NULL;
>>> @@ -726,12 +742,12 @@ i386_find_on_wrapper_list (const char *t
>>>           if (*bufptr)
>>>             *bufptr = 0;
>>>           if (found)
>>> -           *htab_find_slot (wrappers, found, INSERT) = found;
>>> +           *wrappers.find_slot (found, INSERT) = found;
>>>         }
>>>        first_time = 0;
>>>      }
>>>
>>> -  return (const char *) htab_find (wrappers, target);
>>> +  return wrappers.find (target);
>>>  }
>>>
>>>  #endif /* CXX_WRAP_SPEC_LIST */
>>> Index: gcc/config/i386/t-interix
>>> ===================================================================
>>> --- gcc/config/i386/t-interix   (revision 194511)
>>> +++ gcc/config/i386/t-interix   (working copy)
>>> @@ -19,7 +19,7 @@
>>>
>>>  winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H)
>>> coretypes.h \
>>>    $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h
>>> \
>>> -  $(TM_P_H) $(HASHTAB_H) $(GGC_H)
>>> +  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H)
>>>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES)
>>> \
>>>                 $(srcdir)/config/i386/winnt.c
>>>
>>> Index: gcc/config/i386/t-cygming
>>> ===================================================================
>>> --- gcc/config/i386/t-cygming   (revision 194511)
>>> +++ gcc/config/i386/t-cygming   (working copy)
>>> @@ -23,7 +23,7 @@ LIMITS_H_TEST = true
>>>
>>>  winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H)
>>> coretypes.h \
>>>    $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h
>>> \
>>> -  $(TM_P_H) $(HASHTAB_H) $(GGC_H) $(LTO_STREAMER_H)
>>> +  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H) $(LTO_STREAMER_H)
>>>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES)
>>> \
>>>         $(srcdir)/config/i386/winnt.c
>>>
>>> Index: gcc/config/sol2.c
>>> ===================================================================
>>> --- gcc/config/sol2.c   (revision 194511)
>>> +++ gcc/config/sol2.c   (working copy)
>>> @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.
>>>  #include "tm_p.h"
>>>  #include "diagnostic-core.h"
>>>  #include "ggc.h"
>>> -#include "hashtab.h"
>>> +#include "hash-table.h"
>>>
>>>  tree solaris_pending_aligns, solaris_pending_inits,
>>> solaris_pending_finis;
>>>
>>> @@ -158,10 +158,6 @@ solaris_assemble_visibility (tree decl A
>>>  #endif
>>>  }
>>>
>>> -/* Hash table of group signature symbols.  */
>>> -
>>> -static htab_t solaris_comdat_htab;
>>> -
>>>  /* Group section information entry stored in solaris_comdat_htab.  */
>>>
>>>  typedef struct comdat_entry
>>> @@ -172,25 +168,34 @@ typedef struct comdat_entry
>>>    const char *sig;
>>>  } comdat_entry;
>>>
>>> -/* Helper routines for maintaining solaris_comdat_htab.  */
>>> +/* Helpers for maintaining solaris_comdat_htab.  */
>>>
>>> -static hashval_t
>>> -comdat_hash (const void *p)
>>> +struct comdat_entry_hasher : typed_noop_remove <comdat_entry>
>>>  {
>>> -  const comdat_entry *entry = (const comdat_entry *) p;
>>> +  typedef comdat_entry value_type;
>>> +  typedef comdat_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 *);
>>> +};
>>>
>>> +inline hashval_t
>>> +comdat_entry_hasher::hash (const value_type *entry)
>>> +{
>>>    return htab_hash_string (entry->sig);
>>>  }
>>>
>>> -static int
>>> -comdat_eq (const void *p1, const void *p2)
>>> +inline bool
>>> +comdat_entry_hasher::equal (const value_type *entry1,
>>> +                           const compare_type *entry2)
>>>  {
>>> -  const comdat_entry *entry1 = (const comdat_entry *) p1;
>>> -  const comdat_entry *entry2 = (const comdat_entry *) p2;
>>> -
>>>    return strcmp (entry1->sig, entry2->sig) == 0;
>>>  }
>>>
>>> +/* Hash table of group signature symbols.  */
>>> +
>>> +static hash_table <comdat_entry_hasher> solaris_comdat_htab;
>>> +
>>>  /* Output assembly to switch to COMDAT group section NAME with
>>> attributes
>>>     FLAGS and group signature symbol DECL, using Sun as syntax.  */
>>>
>>> @@ -230,12 +235,11 @@ solaris_elf_asm_comdat_section (const ch
>>>       identify the missing ones without changing the affected frontents,
>>>       remember the signature symbols and emit those not marked
>>>       TREE_SYMBOL_REFERENCED in solaris_file_end.  */
>>> -  if (solaris_comdat_htab == NULL)
>>> -    solaris_comdat_htab = htab_create_alloc (37, comdat_hash, comdat_eq,
>>> NULL,
>>> -                                            xcalloc, free);
>>> +  if (!solaris_comdat_htab.is_created ())
>>> +    solaris_comdat_htab.create (37);
>>>
>>>    entry.sig = signature;
>>> -  slot = (comdat_entry **) htab_find_slot (solaris_comdat_htab,
>>> &entry, INSERT);
>>> +  slot = solaris_comdat_htab.find_slot (&entry, INSERT);
>>>
>>>    if (*slot == NULL)
>>>      {
>>> @@ -251,10 +255,11 @@ solaris_elf_asm_comdat_section (const ch
>>>
>>>  /* Define unreferenced COMDAT group signature symbol corresponding to
>>> SLOT.  */
>>>
>>> -static int
>>> -solaris_define_comdat_signature (void **slot, void *aux
>>> ATTRIBUTE_UNUSED)
>>> +int
>>> +solaris_define_comdat_signature (comdat_entry **slot,
>>> +                                void *aux ATTRIBUTE_UNUSED)
>>>  {
>>> -  comdat_entry *entry = *(comdat_entry **) slot;
>>> +  comdat_entry *entry = *slot;
>>>    tree decl = entry->decl;
>>>
>>>    if (TREE_CODE (decl) != IDENTIFIER_NODE)
>>> @@ -278,10 +283,10 @@ solaris_define_comdat_signature (void **
>>>  void
>>>  solaris_file_end (void)
>>>  {
>>> -  if (solaris_comdat_htab == NULL)
>>> +  if (!solaris_comdat_htab.is_created ())
>>>      return;
>>>
>>> -  htab_traverse (solaris_comdat_htab, solaris_define_comdat_signature,
>>> NULL);
>>> +  solaris_comdat_htab.traverse <void *,
>>> solaris_define_comdat_signature> (NULL);
>>>  }
>>>
>>>  void
>>> Index: gcc/config/ia64/t-ia64
>>> ===================================================================
>>> --- gcc/config/ia64/t-ia64      (revision 194511)
>>> +++ gcc/config/ia64/t-ia64      (working copy)
>>> @@ -26,4 +26,5 @@ ia64-c.o: $(srcdir)/config/ia64/ia64-c.c
>>>  # genattrtab generates very long string literals.
>>>  insn-attrtab.o-warn = -Wno-error
>>>
>>> -ia64.o: debug.h $(PARAMS_H) sel-sched.h reload.h $(OPTS_H) dumpfile.h
>>> +ia64.o: $(srcdir)/config/ia64/ia64.c debug.h $(PARAMS_H) sel-sched.h
>>> reload.h \
>>> +       $(OPTS_H) dumpfile.h $(HASH_TABLE_H)
>>> Index: gcc/config/ia64/ia64.c
>>> ===================================================================
>>> --- gcc/config/ia64/ia64.c      (revision 194511)
>>> +++ gcc/config/ia64/ia64.c      (working copy)
>>> @@ -49,7 +49,7 @@ along with GCC; see the file COPYING3.
>>>  #include "target-def.h"
>>>  #include "common/common-target.h"
>>>  #include "tm_p.h"
>>> -#include "hashtab.h"
>>> +#include "hash-table.h"
>>>  #include "langhooks.h"
>>>  #include "gimple.h"
>>>  #include "intl.h"
>>> @@ -259,8 +259,6 @@ static struct bundle_state *get_free_bun
>>>  static void free_bundle_state (struct bundle_state *);
>>>  static void initiate_bundle_states (void);
>>>  static void finish_bundle_states (void);
>>> -static unsigned bundle_state_hash (const void *);
>>> -static int bundle_state_eq_p (const void *, const void *);
>>>  static int insert_bundle_state (struct bundle_state *);
>>>  static void initiate_bundle_state_table (void);
>>>  static void finish_bundle_state_table (void);
>>> @@ -8536,18 +8534,21 @@ finish_bundle_states (void)
>>>      }
>>>  }
>>>
>>> -/* Hash table of the bundle states.  The key is dfa_state and insn_num
>>> -   of the bundle states.  */
>>> +/* Hashtable helpers.  */
>>>
>>> -static htab_t bundle_state_table;
>>> +struct bundle_state_hasher : typed_noop_remove <bundle_state>
>>> +{
>>> +  typedef bundle_state value_type;
>>> +  typedef bundle_state compare_type;
>>> +  static inline hashval_t hash (const value_type *);
>>> +  static inline bool equal (const value_type *, const compare_type *);
>>> +};
>>>
>>>  /* The function returns hash of BUNDLE_STATE.  */
>>>
>>> -static unsigned
>>> -bundle_state_hash (const void *bundle_state)
>>> +inline hashval_t
>>> +bundle_state_hasher::hash (const value_type *state)
>>>  {
>>> -  const struct bundle_state *const state
>>> -    = (const struct bundle_state *) bundle_state;
>>>    unsigned result, i;
>>>
>>>    for (result = i = 0; i < dfa_state_size; i++)
>>> @@ -8558,19 +8559,20 @@ bundle_state_hash (const void *bundle_st
>>>
>>>  /* The function returns nonzero if the bundle state keys are equal.  */
>>>
>>> -static int
>>> -bundle_state_eq_p (const void *bundle_state_1, const void
>>> *bundle_state_2)
>>> +inline bool
>>> +bundle_state_hasher::equal (const value_type *state1,
>>> +                           const compare_type *state2)
>>>  {
>>> -  const struct bundle_state *const state1
>>> -    = (const struct bundle_state *) bundle_state_1;
>>> -  const struct bundle_state *const state2
>>> -    = (const struct bundle_state *) bundle_state_2;
>>> -
>>>    return (state1->insn_num == state2->insn_num
>>>           && memcmp (state1->dfa_state, state2->dfa_state,
>>>                      dfa_state_size) == 0);
>>>  }
>>>
>>> +/* Hash table of the bundle states.  The key is dfa_state and insn_num
>>> +   of the bundle states.  */
>>> +
>>> +static hash_table <bundle_state_hasher> bundle_state_table;
>>> +
>>>  /* The function inserts the BUNDLE_STATE into the hash table.  The
>>>     function returns nonzero if the bundle has been inserted into the
>>>     table.  The table contains the best bundle state with given key.  */
>>> @@ -8578,39 +8580,35 @@ bundle_state_eq_p (const void *bundle_st
>>>  static int
>>>  insert_bundle_state (struct bundle_state *bundle_state)
>>>  {
>>> -  void **entry_ptr;
>>> +  struct bundle_state **entry_ptr;
>>>
>>> -  entry_ptr = htab_find_slot (bundle_state_table, bundle_state,
>>> INSERT);
>>> +  entry_ptr = bundle_state_table.find_slot (bundle_state, INSERT);
>>>    if (*entry_ptr == NULL)
>>>      {
>>>        bundle_state->next = index_to_bundle_states
>>> [bundle_state->insn_num];
>>>        index_to_bundle_states [bundle_state->insn_num] = bundle_state;
>>> -      *entry_ptr = (void *) bundle_state;
>>> +      *entry_ptr = bundle_state;
>>>        return TRUE;
>>>      }
>>> -  else if (bundle_state->cost < ((struct bundle_state *)
>>> *entry_ptr)->cost
>>> -          || (bundle_state->cost == ((struct bundle_state *)
>>> *entry_ptr)->cost
>>> -              && (((struct bundle_state
>>> *)*entry_ptr)->accumulated_insns_num
>>> +  else if (bundle_state->cost < (*entry_ptr)->cost
>>> +          || (bundle_state->cost == (*entry_ptr)->cost
>>> +              && ((*entry_ptr)->accumulated_insns_num
>>>                    > bundle_state->accumulated_insns_num
>>> -                  || (((struct bundle_state *)
>>> -                       *entry_ptr)->accumulated_insns_num
>>> +                  || ((*entry_ptr)->accumulated_insns_num
>>>                        == bundle_state->accumulated_insns_num
>>> -                      && (((struct bundle_state *)
>>> -                           *entry_ptr)->branch_deviation
>>> +                      && ((*entry_ptr)->branch_deviation
>>>                            > bundle_state->branch_deviation
>>> -                          || (((struct bundle_state *)
>>> -                               *entry_ptr)->branch_deviation
>>> +                          || ((*entry_ptr)->branch_deviation
>>>                                == bundle_state->branch_deviation
>>> -                              && ((struct bundle_state *)
>>> -                                  *entry_ptr)->middle_bundle_stops
>>> +                              && (*entry_ptr)->middle_bundle_stops
>>>                                > bundle_state->middle_bundle_stops))))))
>>>
>>>      {
>>>        struct bundle_state temp;
>>>
>>> -      temp = *(struct bundle_state *) *entry_ptr;
>>> -      *(struct bundle_state *) *entry_ptr = *bundle_state;
>>> -      ((struct bundle_state *) *entry_ptr)->next = temp.next;
>>> +      temp = **entry_ptr;
>>> +      **entry_ptr = *bundle_state;
>>> +      (*entry_ptr)->next = temp.next;
>>>        *bundle_state = temp;
>>>      }
>>>    return FALSE;
>>> @@ -8621,8 +8619,7 @@ insert_bundle_state (struct bundle_state
>>>  static void
>>>  initiate_bundle_state_table (void)
>>>  {
>>> -  bundle_state_table = htab_create (50, bundle_state_hash,
>>> bundle_state_eq_p,
>>> -                                   (htab_del) 0);
>>> +  bundle_state_table.create (50);
>>>  }
>>>
>>>  /* Finish work with the hash table.  */
>>> @@ -8630,7 +8627,7 @@ initiate_bundle_state_table (void)
>>>  static void
>>>  finish_bundle_state_table (void)
>>>  {
>>> -  htab_delete (bundle_state_table);
>>> +  bundle_state_table.dispose ();
>>>  }
>>>
>>>
>>> Index: gcc/config/t-sol2
>>> ===================================================================
>>> --- gcc/config/t-sol2   (revision 194511)
>>> +++ gcc/config/t-sol2   (working copy)
>>> @@ -34,5 +34,5 @@ sol2-stubs.o: $(srcdir)/config/sol2-stub
>>>
>>>  # Solaris-specific attributes
>>>  sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>>> -  tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H)
>>> +  tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H)
>>> $(HASH_TABLE_H)
>>>         $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES)
>>> $<
>>> Index: gcc/config/mips/mips.c
>>> ===================================================================
>>> --- gcc/config/mips/mips.c      (revision 194511)
>>> +++ gcc/config/mips/mips.c      (working copy)
>>> @@ -46,7 +46,7 @@ along with GCC; see the file COPYING3.
>>>  #include "tm_p.h"
>>>  #include "ggc.h"
>>>  #include "gstab.h"
>>> -#include "hashtab.h"
>>> +#include "hash-table.h"
>>>  #include "debug.h"
>>>  #include "target.h"
>>>  #include "target-def.h"
>>> @@ -15592,30 +15592,43 @@ mips_hash_base (rtx base)
>>>    return hash_rtx (base, GET_MODE (base), &do_not_record_p, NULL,
>>> false);
>>>  }
>>>
>>> +/* Hashtable helpers.  */
>>> +
>>> +struct mips_lo_sum_offset_hasher : typed_free_remove
>>> <mips_lo_sum_offset>
>>> +{
>>> +  typedef mips_lo_sum_offset value_type;
>>> +  typedef rtx_def compare_type;
>>> +  static inline hashval_t hash (const value_type *);
>>> +  static inline bool equal (const value_type *, const compare_type *);
>>> +};
>>> +
>>>  /* Hash-table callbacks for mips_lo_sum_offsets.  */
>>>
>>> -static hashval_t
>>> -mips_lo_sum_offset_hash (const void *entry)
>>> +inline hashval_t
>>> +mips_lo_sum_offset_hasher::hash (const value_type *entry)
>>>  {
>>> -  return mips_hash_base (((const struct mips_lo_sum_offset *)
>>> entry)->base);
>>> +  return mips_hash_base (entry->base);
>>>  }
>>>
>>> -static int
>>> -mips_lo_sum_offset_eq (const void *entry, const void *value)
>>> +inline bool
>>> +mips_lo_sum_offset_hasher::equal (const value_type *entry,
>>> +                                 const compare_type *value)
>>>  {
>>> -  return rtx_equal_p (((const struct mips_lo_sum_offset *)
>>> entry)->base,
>>> -                     (const_rtx) value);
>>> +  return rtx_equal_p (entry->base, value);
>>>  }
>>>
>>> +typedef hash_table <mips_lo_sum_offset_hasher> mips_offset_table;
>>> +
>>>  /* Look up symbolic constant X in HTAB, which is a hash table of
>>>     mips_lo_sum_offsets.  If OPTION is NO_INSERT, return true if X can
>>> be
>>>     paired with a recorded LO_SUM, otherwise record X in the table.  */
>>>
>>>  static bool
>>> -mips_lo_sum_offset_lookup (htab_t htab, rtx x, enum insert_option
>>> option)
>>> +mips_lo_sum_offset_lookup (mips_offset_table htab, rtx x,
>>> +                          enum insert_option option)
>>>  {
>>>    rtx base, offset;
>>> -  void **slot;
>>> +  mips_lo_sum_offset **slot;
>>>    struct mips_lo_sum_offset *entry;
>>>
>>>    /* Split X into a base and offset.  */
>>> @@ -15624,7 +15637,7 @@ mips_lo_sum_offset_lookup (htab_t htab,
>>>      base = UNSPEC_ADDRESS (base);
>>>
>>>    /* Look up the base in the hash table.  */
>>> -  slot = htab_find_slot_with_hash (htab, base, mips_hash_base (base),
>>> option);
>>> +  slot = htab.find_slot_with_hash (base, mips_hash_base (base),
>>> option);
>>>    if (slot == NULL)
>>>      return false;
>>>
>>> @@ -15654,7 +15667,8 @@ static int
>>>  mips_record_lo_sum (rtx *loc, void *data)
>>>  {
>>>    if (GET_CODE (*loc) == LO_SUM)
>>> -    mips_lo_sum_offset_lookup ((htab_t) data, XEXP (*loc, 1), INSERT);
>>> +    mips_lo_sum_offset_lookup (*(mips_offset_table*)data,
>>> +                              XEXP (*loc, 1), INSERT);
>>>    return 0;
>>>  }
>>>
>>> @@ -15663,7 +15677,7 @@ mips_record_lo_sum (rtx *loc, void *data
>>>     LO_SUMs in the current function.  */
>>>
>>>  static bool
>>> -mips_orphaned_high_part_p (htab_t htab, rtx insn)
>>> +mips_orphaned_high_part_p (mips_offset_table htab, rtx insn)
>>>  {
>>>    enum mips_symbol_type type;
>>>    rtx x, set;
>>> @@ -15771,7 +15785,7 @@ mips_reorg_process_insns (void)
>>>  {
>>>    rtx insn, last_insn, subinsn, next_insn, lo_reg, delayed_reg;
>>>    int hilo_delay;
>>> -  htab_t htab;
>>> +  mips_offset_table htab;
>>>
>>>    /* Force all instructions to be split into their final form.  */
>>>    split_all_insns_noflow ();
>>> @@ -15808,14 +15822,13 @@ mips_reorg_process_insns (void)
>>>    if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
>>>      cfun->machine->all_noreorder_p = false;
>>>
>>> -  htab = htab_create (37, mips_lo_sum_offset_hash,
>>> -                     mips_lo_sum_offset_eq, free);
>>> +  htab.create (37);
>>>
>>>    /* Make a first pass over the instructions, recording all the LO_SUMs.
>>>  */
>>>    for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
>>>      FOR_EACH_SUBINSN (subinsn, insn)
>>>        if (USEFUL_INSN_P (subinsn))
>>> -       for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, htab);
>>> +       for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, &htab);
>>>
>>>    last_insn = 0;
>>>    hilo_delay = 2;
>>> @@ -15872,7 +15885,7 @@ mips_reorg_process_insns (void)
>>>         }
>>>      }
>>>
>>> -  htab_delete (htab);
>>> +  htab.dispose ();
>>>  }
>>>
>>>  /* Return true if the function has a long branch instruction.  */
>>>
>>> --
>>> Lawrence Crowl
>

Patch

Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 194511)
+++ gcc/config/arm/arm.c	(working copy)
@@ -25,6 +25,7 @@ 
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "hash-table.h"
 #include "tm.h"
 #include "rtl.h"
 #include "tree.h"
@@ -3716,36 +3717,48 @@  arm_function_value(const_tree type, cons
   return arm_libcall_value_1 (mode);
 }

-static int
-libcall_eq (const void *p1, const void *p2)
+/* libcall hashtable helpers.  */
+
+struct libcall_hasher : typed_noop_remove <rtx_def>
 {
-  return rtx_equal_p ((const_rtx) p1, (const_rtx) p2);
+  typedef rtx_def value_type;
+  typedef rtx_def 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 *);
+};
+
+inline bool
+libcall_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+  return rtx_equal_p (p1, p2);
 }

-static hashval_t
-libcall_hash (const void *p1)
+inline hashval_t
+libcall_hasher::hash (const value_type *p1)
 {
-  return hash_rtx ((const_rtx) p1, VOIDmode, NULL, NULL, FALSE);
+  return hash_rtx (p1, VOIDmode, NULL, NULL, FALSE);
 }

+typedef hash_table <libcall_hasher> libcall_table_type;
+
 static void
-add_libcall (htab_t htab, rtx libcall)
+add_libcall (libcall_table_type htab, rtx libcall)
 {
-  *htab_find_slot (htab, libcall, INSERT) = libcall;
+  *htab.find_slot (libcall, INSERT) = libcall;
 }

 static bool
 arm_libcall_uses_aapcs_base (const_rtx libcall)
 {
   static bool init_done = false;
-  static htab_t libcall_htab;
+  static libcall_table_type libcall_htab;

   if (!init_done)
     {
       init_done = true;

-      libcall_htab = htab_create (31, libcall_hash, libcall_eq,
-				  NULL);
+      libcall_htab.create (31);
       add_libcall (libcall_htab,
 		   convert_optab_libfunc (sfloat_optab, SFmode, SImode));
       add_libcall (libcall_htab,
@@ -3804,7 +3817,7 @@  arm_libcall_uses_aapcs_base (const_rtx l
 							DFmode));
     }

-  return libcall && htab_find (libcall_htab, libcall) != NULL;
+  return libcall && libcall_htab.find (libcall) != NULL;
 }

 static rtx
Index: gcc/config/arm/t-arm
===================================================================
--- gcc/config/arm/t-arm	(revision 194511)
+++ gcc/config/arm/t-arm	(working copy)
@@ -73,8 +73,8 @@  $(srcdir)/config/arm/arm-tables.opt: $(s
 	$(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
 		$(srcdir)/config/arm/arm-tables.opt

-arm.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
-  $(RTL_H) $(TREE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
+arm.o: $(srcdir)/config/arm/arm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
+  $(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
   insn-config.h conditions.h output.h dumpfile.h \
   $(INSN_ATTR_H) $(FLAGS_H) reload.h $(FUNCTION_H) \
   $(EXPR_H) $(OPTABS_H) $(RECOG_H) $(CGRAPH_H) \
Index: gcc/config/i386/winnt.c
===================================================================
--- gcc/config/i386/winnt.c	(revision 194511)
+++ gcc/config/i386/winnt.c	(working copy)
@@ -31,7 +31,7 @@  along with GCC; see the file COPYING3.
 #include "flags.h"
 #include "tm_p.h"
 #include "diagnostic-core.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "langhooks.h"
 #include "ggc.h"
 #include "target.h"
@@ -449,7 +449,7 @@  i386_pe_reloc_rw_mask (void)
 unsigned int
 i386_pe_section_type_flags (tree decl, const char *name, int reloc)
 {
-  static htab_t htab;
+  static hash_table <pointer_hash <unsigned int> > htab;
   unsigned int flags;
   unsigned int **slot;

@@ -460,8 +460,8 @@  i386_pe_section_type_flags (tree decl, c
   /* The names we put in the hashtable will always be the unique
      versions given to us by the stringtable, so we can just use
      their addresses as the keys.  */
-  if (!htab)
-    htab = htab_create (31, htab_hash_pointer, htab_eq_pointer, NULL);
+  if (!htab.is_created ())
+    htab.create (31);

   if (decl && TREE_CODE (decl) == FUNCTION_DECL)
     flags = SECTION_CODE;
@@ -480,7 +480,7 @@  i386_pe_section_type_flags (tree decl, c
     flags |= SECTION_LINKONCE;

   /* See if we already have an entry for this section.  */
-  slot = (unsigned int **) htab_find_slot (htab, name, INSERT);
+  slot = htab.find_slot ((unsigned int *)name, INSERT);
   if (!*slot)
     {
       *slot = (unsigned int *) xmalloc (sizeof (unsigned int));
@@ -680,12 +680,29 @@  i386_pe_maybe_record_exported_symbol (tr

 #ifdef CXX_WRAP_SPEC_LIST

+/* Hashtable helpers.  */
+
+struct wrapped_symbol_hasher : typed_noop_remove <char>
+{
+  typedef char value_type;
+  typedef char 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 *);
+};
+
+inline hashval_t
+wrapped_symbol_hasher::hash (const value_type *v)
+{
+  return htab_hash_string (v);
+}
+
 /*  Hash table equality helper function.  */

-static int
-wrapper_strcmp (const void *x, const void *y)
+inline bool
+wrapped_symbol_hasher::equal (const value_type *x, const compare_type *y)
 {
-  return !strcmp ((const char *) x, (const char *) y);
+  return !strcmp (x, y);
 }

 /* Search for a function named TARGET in the list of library wrappers
@@ -699,7 +716,7 @@  static const char *
 i386_find_on_wrapper_list (const char *target)
 {
   static char first_time = 1;
-  static htab_t wrappers;
+  static hash_table <wrapped_symbol_hasher> wrappers;

   if (first_time)
     {
@@ -712,8 +729,7 @@  i386_find_on_wrapper_list (const char *t
       char *bufptr;
       /* Breaks up the char array into separated strings
          strings and enter them into the hash table.  */
-      wrappers = htab_create_alloc (8, htab_hash_string, wrapper_strcmp,
-	0, xcalloc, free);
+      wrappers.create (8);
       for (bufptr = wrapper_list_buffer; *bufptr; ++bufptr)
 	{
 	  char *found = NULL;
@@ -726,12 +742,12 @@  i386_find_on_wrapper_list (const char *t
 	  if (*bufptr)
 	    *bufptr = 0;
 	  if (found)
-	    *htab_find_slot (wrappers, found, INSERT) = found;
+	    *wrappers.find_slot (found, INSERT) = found;
 	}
       first_time = 0;
     }

-  return (const char *) htab_find (wrappers, target);
+  return wrappers.find (target);
 }

 #endif /* CXX_WRAP_SPEC_LIST */
Index: gcc/config/i386/t-interix
===================================================================
--- gcc/config/i386/t-interix	(revision 194511)
+++ gcc/config/i386/t-interix	(working copy)
@@ -19,7 +19,7 @@ 

 winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
   $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
-  $(TM_P_H) $(HASHTAB_H) $(GGC_H)
+  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H)
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 		$(srcdir)/config/i386/winnt.c

Index: gcc/config/i386/t-cygming
===================================================================
--- gcc/config/i386/t-cygming	(revision 194511)
+++ gcc/config/i386/t-cygming	(working copy)
@@ -23,7 +23,7 @@  LIMITS_H_TEST = true

 winnt.o: $(srcdir)/config/i386/winnt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
   $(TM_H) $(RTL_H) $(REGS_H) hard-reg-set.h output.h $(TREE_H) flags.h \
-  $(TM_P_H) $(HASHTAB_H) $(GGC_H) $(LTO_STREAMER_H)
+  $(TM_P_H) $(HASH_TABLE_H) $(GGC_H) $(LTO_STREAMER_H)
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
 	$(srcdir)/config/i386/winnt.c

Index: gcc/config/sol2.c
===================================================================
--- gcc/config/sol2.c	(revision 194511)
+++ gcc/config/sol2.c	(working copy)
@@ -30,7 +30,7 @@  along with GCC; see the file COPYING3.
 #include "tm_p.h"
 #include "diagnostic-core.h"
 #include "ggc.h"
-#include "hashtab.h"
+#include "hash-table.h"

 tree solaris_pending_aligns, solaris_pending_inits, solaris_pending_finis;

@@ -158,10 +158,6 @@  solaris_assemble_visibility (tree decl A
 #endif
 }

-/* Hash table of group signature symbols.  */
-
-static htab_t solaris_comdat_htab;
-
 /* Group section information entry stored in solaris_comdat_htab.  */

 typedef struct comdat_entry
@@ -172,25 +168,34 @@  typedef struct comdat_entry
   const char *sig;
 } comdat_entry;

-/* Helper routines for maintaining solaris_comdat_htab.  */
+/* Helpers for maintaining solaris_comdat_htab.  */

-static hashval_t
-comdat_hash (const void *p)
+struct comdat_entry_hasher : typed_noop_remove <comdat_entry>
 {
-  const comdat_entry *entry = (const comdat_entry *) p;
+  typedef comdat_entry value_type;
+  typedef comdat_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 *);
+};

+inline hashval_t
+comdat_entry_hasher::hash (const value_type *entry)
+{
   return htab_hash_string (entry->sig);
 }

-static int
-comdat_eq (const void *p1, const void *p2)
+inline bool
+comdat_entry_hasher::equal (const value_type *entry1,
+			    const compare_type *entry2)
 {
-  const comdat_entry *entry1 = (const comdat_entry *) p1;
-  const comdat_entry *entry2 = (const comdat_entry *) p2;
-
   return strcmp (entry1->sig, entry2->sig) == 0;
 }

+/* Hash table of group signature symbols.  */
+
+static hash_table <comdat_entry_hasher> solaris_comdat_htab;
+
 /* Output assembly to switch to COMDAT group section NAME with attributes
    FLAGS and group signature symbol DECL, using Sun as syntax.  */

@@ -230,12 +235,11 @@  solaris_elf_asm_comdat_section (const ch
      identify the missing ones without changing the affected frontents,
      remember the signature symbols and emit those not marked
      TREE_SYMBOL_REFERENCED in solaris_file_end.  */
-  if (solaris_comdat_htab == NULL)
-    solaris_comdat_htab = htab_create_alloc (37, comdat_hash, comdat_eq, NULL,
-					     xcalloc, free);
+  if (!solaris_comdat_htab.is_created ())
+    solaris_comdat_htab.create (37);

   entry.sig = signature;
-  slot = (comdat_entry **) htab_find_slot (solaris_comdat_htab,
&entry, INSERT);
+  slot = solaris_comdat_htab.find_slot (&entry, INSERT);

   if (*slot == NULL)
     {
@@ -251,10 +255,11 @@  solaris_elf_asm_comdat_section (const ch

 /* Define unreferenced COMDAT group signature symbol corresponding to SLOT.  */

-static int
-solaris_define_comdat_signature (void **slot, void *aux ATTRIBUTE_UNUSED)
+int
+solaris_define_comdat_signature (comdat_entry **slot,
+				 void *aux ATTRIBUTE_UNUSED)
 {
-  comdat_entry *entry = *(comdat_entry **) slot;
+  comdat_entry *entry = *slot;
   tree decl = entry->decl;

   if (TREE_CODE (decl) != IDENTIFIER_NODE)
@@ -278,10 +283,10 @@  solaris_define_comdat_signature (void **
 void
 solaris_file_end (void)
 {
-  if (solaris_comdat_htab == NULL)
+  if (!solaris_comdat_htab.is_created ())
     return;

-  htab_traverse (solaris_comdat_htab, solaris_define_comdat_signature, NULL);
+  solaris_comdat_htab.traverse <void *,
solaris_define_comdat_signature> (NULL);
 }

 void
Index: gcc/config/ia64/t-ia64
===================================================================
--- gcc/config/ia64/t-ia64	(revision 194511)
+++ gcc/config/ia64/t-ia64	(working copy)
@@ -26,4 +26,5 @@  ia64-c.o: $(srcdir)/config/ia64/ia64-c.c
 # genattrtab generates very long string literals.
 insn-attrtab.o-warn = -Wno-error

-ia64.o: debug.h $(PARAMS_H) sel-sched.h reload.h $(OPTS_H) dumpfile.h
+ia64.o: $(srcdir)/config/ia64/ia64.c debug.h $(PARAMS_H) sel-sched.h reload.h \
+	$(OPTS_H) dumpfile.h $(HASH_TABLE_H)
Index: gcc/config/ia64/ia64.c
===================================================================
--- gcc/config/ia64/ia64.c	(revision 194511)
+++ gcc/config/ia64/ia64.c	(working copy)
@@ -49,7 +49,7 @@  along with GCC; see the file COPYING3.
 #include "target-def.h"
 #include "common/common-target.h"
 #include "tm_p.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "langhooks.h"
 #include "gimple.h"
 #include "intl.h"
@@ -259,8 +259,6 @@  static struct bundle_state *get_free_bun
 static void free_bundle_state (struct bundle_state *);
 static void initiate_bundle_states (void);
 static void finish_bundle_states (void);
-static unsigned bundle_state_hash (const void *);
-static int bundle_state_eq_p (const void *, const void *);
 static int insert_bundle_state (struct bundle_state *);
 static void initiate_bundle_state_table (void);
 static void finish_bundle_state_table (void);
@@ -8536,18 +8534,21 @@  finish_bundle_states (void)
     }
 }

-/* Hash table of the bundle states.  The key is dfa_state and insn_num
-   of the bundle states.  */
+/* Hashtable helpers.  */

-static htab_t bundle_state_table;
+struct bundle_state_hasher : typed_noop_remove <bundle_state>
+{
+  typedef bundle_state value_type;
+  typedef bundle_state compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};

 /* The function returns hash of BUNDLE_STATE.  */

-static unsigned
-bundle_state_hash (const void *bundle_state)
+inline hashval_t
+bundle_state_hasher::hash (const value_type *state)
 {
-  const struct bundle_state *const state
-    = (const struct bundle_state *) bundle_state;
   unsigned result, i;

   for (result = i = 0; i < dfa_state_size; i++)
@@ -8558,19 +8559,20 @@  bundle_state_hash (const void *bundle_st

 /* The function returns nonzero if the bundle state keys are equal.  */

-static int
-bundle_state_eq_p (const void *bundle_state_1, const void *bundle_state_2)
+inline bool
+bundle_state_hasher::equal (const value_type *state1,
+			    const compare_type *state2)
 {
-  const struct bundle_state *const state1
-    = (const struct bundle_state *) bundle_state_1;
-  const struct bundle_state *const state2
-    = (const struct bundle_state *) bundle_state_2;
-
   return (state1->insn_num == state2->insn_num
 	  && memcmp (state1->dfa_state, state2->dfa_state,
 		     dfa_state_size) == 0);
 }

+/* Hash table of the bundle states.  The key is dfa_state and insn_num
+   of the bundle states.  */
+
+static hash_table <bundle_state_hasher> bundle_state_table;
+
 /* The function inserts the BUNDLE_STATE into the hash table.  The
    function returns nonzero if the bundle has been inserted into the
    table.  The table contains the best bundle state with given key.  */
@@ -8578,39 +8580,35 @@  bundle_state_eq_p (const void *bundle_st
 static int
 insert_bundle_state (struct bundle_state *bundle_state)
 {
-  void **entry_ptr;
+  struct bundle_state **entry_ptr;

-  entry_ptr = htab_find_slot (bundle_state_table, bundle_state, INSERT);
+  entry_ptr = bundle_state_table.find_slot (bundle_state, INSERT);
   if (*entry_ptr == NULL)
     {
       bundle_state->next = index_to_bundle_states [bundle_state->insn_num];
       index_to_bundle_states [bundle_state->insn_num] = bundle_state;
-      *entry_ptr = (void *) bundle_state;
+      *entry_ptr = bundle_state;
       return TRUE;
     }
-  else if (bundle_state->cost < ((struct bundle_state *) *entry_ptr)->cost
-	   || (bundle_state->cost == ((struct bundle_state *) *entry_ptr)->cost
-	       && (((struct bundle_state *)*entry_ptr)->accumulated_insns_num
+  else if (bundle_state->cost < (*entry_ptr)->cost
+	   || (bundle_state->cost == (*entry_ptr)->cost
+	       && ((*entry_ptr)->accumulated_insns_num
 		   > bundle_state->accumulated_insns_num
-		   || (((struct bundle_state *)
-			*entry_ptr)->accumulated_insns_num
+		   || ((*entry_ptr)->accumulated_insns_num
 		       == bundle_state->accumulated_insns_num
-		       && (((struct bundle_state *)
-			    *entry_ptr)->branch_deviation
+		       && ((*entry_ptr)->branch_deviation
 			   > bundle_state->branch_deviation
-			   || (((struct bundle_state *)
-				*entry_ptr)->branch_deviation
+			   || ((*entry_ptr)->branch_deviation
 			       == bundle_state->branch_deviation
-			       && ((struct bundle_state *)
-				   *entry_ptr)->middle_bundle_stops
+			       && (*entry_ptr)->middle_bundle_stops
 			       > bundle_state->middle_bundle_stops))))))

     {
       struct bundle_state temp;

-      temp = *(struct bundle_state *) *entry_ptr;
-      *(struct bundle_state *) *entry_ptr = *bundle_state;
-      ((struct bundle_state *) *entry_ptr)->next = temp.next;
+      temp = **entry_ptr;
+      **entry_ptr = *bundle_state;
+      (*entry_ptr)->next = temp.next;
       *bundle_state = temp;
     }
   return FALSE;
@@ -8621,8 +8619,7 @@  insert_bundle_state (struct bundle_state
 static void
 initiate_bundle_state_table (void)
 {
-  bundle_state_table = htab_create (50, bundle_state_hash, bundle_state_eq_p,
-				    (htab_del) 0);
+  bundle_state_table.create (50);
 }

 /* Finish work with the hash table.  */
@@ -8630,7 +8627,7 @@  initiate_bundle_state_table (void)
 static void
 finish_bundle_state_table (void)
 {
-  htab_delete (bundle_state_table);
+  bundle_state_table.dispose ();
 }

 
Index: gcc/config/t-sol2
===================================================================
--- gcc/config/t-sol2	(revision 194511)
+++ gcc/config/t-sol2	(working copy)
@@ -34,5 +34,5 @@  sol2-stubs.o: $(srcdir)/config/sol2-stub

 # Solaris-specific attributes
 sol2.o: $(srcdir)/config/sol2.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-  tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H)
+  tree.h output.h $(TM_H) $(TARGET_H) $(TM_P_H) $(GGC_H) $(HASH_TABLE_H)
 	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $<
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c	(revision 194511)
+++ gcc/config/mips/mips.c	(working copy)
@@ -46,7 +46,7 @@  along with GCC; see the file COPYING3.
 #include "tm_p.h"
 #include "ggc.h"
 #include "gstab.h"
-#include "hashtab.h"
+#include "hash-table.h"
 #include "debug.h"
 #include "target.h"
 #include "target-def.h"
@@ -15592,30 +15592,43 @@  mips_hash_base (rtx base)
   return hash_rtx (base, GET_MODE (base), &do_not_record_p, NULL, false);
 }

+/* Hashtable helpers.  */
+
+struct mips_lo_sum_offset_hasher : typed_free_remove <mips_lo_sum_offset>
+{
+  typedef mips_lo_sum_offset value_type;
+  typedef rtx_def compare_type;
+  static inline hashval_t hash (const value_type *);
+  static inline bool equal (const value_type *, const compare_type *);
+};
+
 /* Hash-table callbacks for mips_lo_sum_offsets.  */

-static hashval_t
-mips_lo_sum_offset_hash (const void *entry)
+inline hashval_t
+mips_lo_sum_offset_hasher::hash (const value_type *entry)
 {
-  return mips_hash_base (((const struct mips_lo_sum_offset *) entry)->base);
+  return mips_hash_base (entry->base);
 }

-static int
-mips_lo_sum_offset_eq (const void *entry, const void *value)
+inline bool
+mips_lo_sum_offset_hasher::equal (const value_type *entry,
+				  const compare_type *value)
 {
-  return rtx_equal_p (((const struct mips_lo_sum_offset *) entry)->base,
-		      (const_rtx) value);
+  return rtx_equal_p (entry->base, value);
 }

+typedef hash_table <mips_lo_sum_offset_hasher> mips_offset_table;
+
 /* Look up symbolic constant X in HTAB, which is a hash table of
    mips_lo_sum_offsets.  If OPTION is NO_INSERT, return true if X can be
    paired with a recorded LO_SUM, otherwise record X in the table.  */

 static bool
-mips_lo_sum_offset_lookup (htab_t htab, rtx x, enum insert_option option)
+mips_lo_sum_offset_lookup (mips_offset_table htab, rtx x,
+			   enum insert_option option)
 {
   rtx base, offset;
-  void **slot;
+  mips_lo_sum_offset **slot;
   struct mips_lo_sum_offset *entry;

   /* Split X into a base and offset.  */
@@ -15624,7 +15637,7 @@  mips_lo_sum_offset_lookup (htab_t htab,
     base = UNSPEC_ADDRESS (base);

   /* Look up the base in the hash table.  */
-  slot = htab_find_slot_with_hash (htab, base, mips_hash_base (base), option);
+  slot = htab.find_slot_with_hash (base, mips_hash_base (base), option);
   if (slot == NULL)
     return false;

@@ -15654,7 +15667,8 @@  static int
 mips_record_lo_sum (rtx *loc, void *data)
 {
   if (GET_CODE (*loc) == LO_SUM)
-    mips_lo_sum_offset_lookup ((htab_t) data, XEXP (*loc, 1), INSERT);
+    mips_lo_sum_offset_lookup (*(mips_offset_table*)data,
+			       XEXP (*loc, 1), INSERT);
   return 0;
 }

@@ -15663,7 +15677,7 @@  mips_record_lo_sum (rtx *loc, void *data
    LO_SUMs in the current function.  */

 static bool
-mips_orphaned_high_part_p (htab_t htab, rtx insn)
+mips_orphaned_high_part_p (mips_offset_table htab, rtx insn)
 {
   enum mips_symbol_type type;
   rtx x, set;
@@ -15771,7 +15785,7 @@  mips_reorg_process_insns (void)
 {
   rtx insn, last_insn, subinsn, next_insn, lo_reg, delayed_reg;
   int hilo_delay;
-  htab_t htab;
+  mips_offset_table htab;

   /* Force all instructions to be split into their final form.  */
   split_all_insns_noflow ();
@@ -15808,14 +15822,13 @@  mips_reorg_process_insns (void)
   if (TARGET_FIX_VR4130 && !ISA_HAS_MACCHI)
     cfun->machine->all_noreorder_p = false;

-  htab = htab_create (37, mips_lo_sum_offset_hash,
-		      mips_lo_sum_offset_eq, free);
+  htab.create (37);

   /* Make a first pass over the instructions, recording all the LO_SUMs.  */
   for (insn = get_insns (); insn != 0; insn = NEXT_INSN (insn))
     FOR_EACH_SUBINSN (subinsn, insn)
       if (USEFUL_INSN_P (subinsn))
-	for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, htab);
+	for_each_rtx (&PATTERN (subinsn), mips_record_lo_sum, &htab);

   last_insn = 0;
   hilo_delay = 2;
@@ -15872,7 +15885,7 @@  mips_reorg_process_insns (void)
 	}
     }

-  htab_delete (htab);
+  htab.dispose ();
 }

 /* Return true if the function has a long branch instruction.  */