[RFC] Move hash-table.h and related files to libiberty
diff mbox series

Message ID 20190921091238.187441-1-cbiesinger@google.com
State New
Headers show
Series
  • [RFC] Move hash-table.h and related files to libiberty
Related show

Commit Message

Ian Lance Taylor via gcc-patches Sept. 21, 2019, 9:12 a.m. UTC
Hello,

I would like to move hash-table.h, hash-map.h and related files
to libiberty, so that GDB can make use of it.

I see that gcc already has a C++ file in include/ (unique-ptr.h),
which I understand is libiberty.

However, this patch is not complete yet (for a start, it doesn't
compile). Before I go further down this road, is this acceptable
in principle to the gcc/libiberty maintainers?

(the bulk of the patch is including vec.h in a lot of files,
because hash-table.h previously included it. It doesn't
actually use it, and I didn't think it was necessary to
move that to libiberty as well, so I removed that include
and instead am adding it to all the files that now don't
compile.)

Thanks!
Christian

Comments

Richard Biener Sept. 21, 2019, 10:21 a.m. UTC | #1
On September 21, 2019 11:12:38 AM GMT+02:00, Christian Biesinger via gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>Hello,
>
>I would like to move hash-table.h, hash-map.h and related files
>to libiberty, so that GDB can make use of it.
>
>I see that gcc already has a C++ file in include/ (unique-ptr.h),
>which I understand is libiberty.
>
>However, this patch is not complete yet (for a start, it doesn't
>compile). Before I go further down this road, is this acceptable
>in principle to the gcc/libiberty maintainers?
>
>(the bulk of the patch is including vec.h in a lot of files,
>because hash-table.h previously included it. It doesn't
>actually use it, and I didn't think it was necessary to
>move that to libiberty as well, so I removed that include
>and instead am adding it to all the files that now don't
>compile.)

The bulk seems to be hash_table to hash_table_ggc renaming. Can you explain? Also we can then rename create_ggc back to create? 

Richard. 

>Thanks!
>Christian
>
>Index: Makefile.in
>===================================================================
>--- Makefile.in	(revision 275695)
>+++ Makefile.in	(working copy)
>@@ -1490,7 +1490,6 @@
> 	spellcheck-tree.o \
> 	sreal.o \
> 	stack-ptr-mod.o \
>-	statistics.o \
> 	stmt.o \
> 	stor-layout.o \
> 	store-motion.o \
>Index: bitmap.c
>===================================================================
>--- bitmap.c	(revision 275695)
>+++ bitmap.c	(working copy)
>@@ -22,6 +22,7 @@
> #include "coretypes.h"
> #include "bitmap.h"
> #include "selftest.h"
>+#include "vec.h"
> 
> /* Memory allocation statistics purpose instance.  */
> mem_alloc_description<bitmap_usage> bitmap_mem_desc;
>Index: cfgloop.c
>===================================================================
>--- cfgloop.c	(revision 275695)
>+++ cfgloop.c	(working copy)
>@@ -1135,7 +1135,7 @@
> 
>   gcc_assert (current_loops->exits == NULL);
>   current_loops->exits
>-    = hash_table<loop_exit_hasher>::create_ggc (2 * number_of_loops
>(cfun));
>+    = hash_table_ggc<loop_exit_hasher>::create_ggc (2 *
>number_of_loops (cfun));
> 
>   FOR_EACH_BB_FN (bb, cfun)
>     {
>Index: cgraph.c
>===================================================================
>--- cgraph.c	(revision 275695)
>+++ cgraph.c	(working copy)
>@@ -183,7 +183,7 @@
>   version_info_node->this_node = this;
> 
>   if (cgraph_fnver_htab == NULL)
>-    cgraph_fnver_htab =
>hash_table<function_version_hasher>::create_ggc (2);
>+    cgraph_fnver_htab =
>hash_table_ggc<function_version_hasher>::create_ggc (2);
> 
>   *cgraph_fnver_htab->find_slot (version_info_node, INSERT)
>     = version_info_node;
>@@ -760,7 +760,7 @@
> 
>   if (n > 100)
>     {
>-      call_site_hash = hash_table<cgraph_edge_hasher>::create_ggc
>(120);
>+      call_site_hash = hash_table_ggc<cgraph_edge_hasher>::create_ggc
>(120);
>       for (e2 = callees; e2; e2 = e2->next_callee)
> 	cgraph_add_edge_to_call_site_hash (e2);
>       for (e2 = indirect_calls; e2; e2 = e2->next_callee)
>Index: common/common-target.h
>===================================================================
>--- common/common-target.h	(revision 275695)
>+++ common/common-target.h	(working copy)
>@@ -22,6 +22,7 @@
> #ifndef GCC_COMMON_TARGET_H
> #define GCC_COMMON_TARGET_H
> 
>+#include "vec.h"
> 
> /* Sets of optimization levels at which an option may be enabled by
>    default_options_optimization.  */
>Index: common/common-targhooks.h
>===================================================================
>--- common/common-targhooks.h	(revision 275695)
>+++ common/common-targhooks.h	(working copy)
>@@ -20,6 +20,8 @@
> #ifndef GCC_COMMON_TARGHOOKS_H
> #define GCC_COMMON_TARGHOOKS_H
> 
>+#include "vec.h"
>+
>extern enum unwind_info_type default_except_unwind_info (struct
>gcc_options *);
>extern enum unwind_info_type dwarf2_except_unwind_info (struct
>gcc_options *);
>extern enum unwind_info_type sjlj_except_unwind_info (struct
>gcc_options *);
>Index: config/darwin.c
>===================================================================
>--- config/darwin.c	(revision 275695)
>+++ config/darwin.c	(working copy)
>@@ -572,7 +572,7 @@
>sprintf (buffer, "&%s%c%s%s%s%s", quote, L_or_l, prefix, name, suffix,
>quote);
> 
>   if (!machopic_indirections)
>-    machopic_indirections = hash_table<indirection_hasher>::create_ggc
>(37);
>+    machopic_indirections =
>hash_table_ggc<indirection_hasher>::create_ggc (37);
> 
>   machopic_indirection **slot
>     = machopic_indirections->find_slot_with_hash (buffer,
>@@ -3454,7 +3454,7 @@
>   rest_of_decl_compilation (cfstring_class_reference, 0, 0);
> 
>/* Initialize the hash table used to hold the constant CFString
>objects.  */
>-  cfstring_htab = hash_table<cfstring_hasher>::create_ggc (31);
>+  cfstring_htab = hash_table_ggc<cfstring_hasher>::create_ggc (31);
> 
>   return cfstring_type_node;
> }
>Index: config/i386/i386.c
>===================================================================
>--- config/i386/i386.c	(revision 275695)
>+++ config/i386/i386.c	(working copy)
>@@ -95,6 +95,7 @@
> #include "i386-builtins.h"
> #include "i386-expand.h"
> #include "i386-features.h"
>+#include "hash-table-ggc.h"
> 
> /* This file should be included last.  */
> #include "target-def.h"
>@@ -11048,7 +11049,7 @@
>   rtx rtl;
> 
>   if (!dllimport_map)
>-    dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
>+    dllimport_map = hash_table_ggc<dllimport_hasher>::create_ggc
>(512);
> 
>   in.hash = htab_hash_pointer (decl);
>   in.base.from = decl;
>Index: cp/constexpr.c
>===================================================================
>--- cp/constexpr.c	(revision 275695)
>+++ cp/constexpr.c	(working copy)
>@@ -895,7 +895,7 @@
>   /* Create the constexpr function table if necessary.  */
>   if (constexpr_fundef_table == NULL)
>     constexpr_fundef_table
>-      = hash_table<constexpr_fundef_hasher>::create_ggc (101);
>+      = hash_table_ggc<constexpr_fundef_hasher>::create_ggc (101);
> 
>   entry.decl = fun;
>   tree saved_fn = current_function_decl;
>@@ -1081,7 +1081,7 @@
> maybe_initialize_constexpr_call_table (void)
> {
>   if (constexpr_call_table == NULL)
>-    constexpr_call_table =
>hash_table<constexpr_call_hasher>::create_ggc (101);
>+    constexpr_call_table =
>hash_table_ggc<constexpr_call_hasher>::create_ggc (101);
> }
> 
>/* During constexpr CALL_EXPR evaluation, to avoid issues with sharing
>when
>Index: cp/decl.c
>===================================================================
>--- cp/decl.c	(revision 275695)
>+++ cp/decl.c	(working copy)
>@@ -3070,7 +3070,7 @@
>     }
> 
>   if (!named_labels)
>-    named_labels = hash_table<named_label_hash>::create_ggc (13);
>+    named_labels = hash_table_ggc<named_label_hash>::create_ggc (13);
> 
>   hashval_t hash = IDENTIFIER_HASH_VALUE (id);
>   named_label_entry **slot
>@@ -3754,7 +3754,7 @@
>   hashval_t hash;
> 
>   if (typename_htab == NULL)
>-    typename_htab = hash_table<typename_hasher>::create_ggc (61);
>+    typename_htab = hash_table_ggc<typename_hasher>::create_ggc (61);
> 
>   ti.scope = FROB_CONTEXT (context);
>   ti.name = name;
>Index: cp/decl2.c
>===================================================================
>--- cp/decl2.c	(revision 275695)
>+++ cp/decl2.c	(working copy)
>@@ -4612,7 +4612,7 @@
> record_mangling (tree decl, bool need_warning)
> {
>   if (!mangled_decls)
>-    mangled_decls = hash_table<mangled_decl_hash>::create_ggc (499);
>+    mangled_decls = hash_table_ggc<mangled_decl_hash>::create_ggc
>(499);
> 
>   gcc_checking_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
>   tree id = DECL_ASSEMBLER_NAME_RAW (decl);
>Index: cp/lex.c
>===================================================================
>--- cp/lex.c	(revision 275695)
>+++ cp/lex.c	(working copy)
>@@ -625,7 +625,7 @@
>     return error_mark_node;
> 
>   if (conv_type_names == NULL)
>-    conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
>+    conv_type_names = hash_table_ggc<conv_type_hasher>::create_ggc
>(31);
> 
>   tree *slot = conv_type_names->find_slot_with_hash
>     (type, (hashval_t) TYPE_UID (type), INSERT);
>@@ -703,7 +703,7 @@
> 
>   if (sel == lds_ns)
>     /* Who'd create a namespace, only to put nothing in it?  */
>-    ld->u.ns.bindings = hash_table<named_decl_hash>::create_ggc (499);
>+    ld->u.ns.bindings = hash_table_ggc<named_decl_hash>::create_ggc
>(499);
> 
>   if (GATHER_STATISTICS)
>     {
>Index: cp/name-lookup.c
>===================================================================
>--- cp/name-lookup.c	(revision 275695)
>+++ cp/name-lookup.c	(working copy)
>@@ -2522,7 +2522,7 @@
>     return;
> 
>   if (!extern_c_decls)
>-    extern_c_decls = hash_table<named_decl_hash>::create_ggc (127);
>+    extern_c_decls = hash_table_ggc<named_decl_hash>::create_ggc
>(127);
> 
>   tree *slot = extern_c_decls
>     ->find_slot_with_hash (DECL_NAME (decl),
>@@ -2907,7 +2907,7 @@
> 
> 	    if (cp_function_chain->extern_decl_map == NULL)
> 	      cp_function_chain->extern_decl_map
>-		= hash_table<cxx_int_tree_map_hasher>::create_ggc (20);
>+		= hash_table_ggc<cxx_int_tree_map_hasher>::create_ggc (20);
> 
> 	    h = ggc_alloc<cxx_int_tree_map> ();
> 	    h->uid = DECL_UID (decl);
>Index: cp/pt.c
>===================================================================
>--- cp/pt.c	(revision 275695)
>+++ cp/pt.c	(working copy)
>@@ -28306,11 +28306,11 @@
>   if (!flag_concepts)
>     return;
> 
>-  decl_constraints = hash_table<constr_hasher>::create_ggc(37);
>-  constraint_memos =
>hash_table<constraint_sat_hasher>::create_ggc(37);
>-  concept_memos = hash_table<concept_spec_hasher>::create_ggc(37);
>-  concept_expansions =
>hash_table<concept_spec_hasher>::create_ggc(37);
>-  subsumption_table = hash_table<subsumption_hasher>::create_ggc(37);
>+  decl_constraints = hash_table_ggc<constr_hasher>::create_ggc(37);
>+  constraint_memos =
>hash_table_ggc<constraint_sat_hasher>::create_ggc(37);
>+  concept_memos = hash_table_ggc<concept_spec_hasher>::create_ggc(37);
>+  concept_expansions =
>hash_table_ggc<concept_spec_hasher>::create_ggc(37);
>+  subsumption_table =
>hash_table_ggc<subsumption_hasher>::create_ggc(37);
> }
> 
>/* __integer_pack(N) in a pack expansion expands to a sequence of
>numbers from
>@@ -28335,8 +28335,8 @@
> init_template_processing (void)
> {
>   /* FIXME: enable sanitization (PR87847) */
>-  decl_specializations = hash_table<spec_hasher>::create_ggc (37,
>false);
>-  type_specializations = hash_table<spec_hasher>::create_ggc (37,
>false);
>+  decl_specializations = hash_table_ggc<spec_hasher>::create_ggc (37,
>false);
>+  type_specializations = hash_table_ggc<spec_hasher>::create_ggc (37,
>false);
> 
>   if (cxx_dialect >= cxx11)
>     declare_integer_pack ();
>Index: cp/tree.c
>===================================================================
>--- cp/tree.c	(revision 275695)
>+++ cp/tree.c	(working copy)
>@@ -1011,7 +1011,7 @@
>       hashval_t hash;
> 
>       if (cplus_array_htab == NULL)
>-	cplus_array_htab = hash_table<cplus_array_hasher>::create_ggc (61);
>+	cplus_array_htab = hash_table_ggc<cplus_array_hasher>::create_ggc
>(61);
>       
>       hash = TYPE_UID (elt_type);
>       if (index_type)
>@@ -4982,7 +4982,7 @@
> void
> init_tree (void)
> {
>-  list_hash_table = hash_table<list_hasher>::create_ggc (61);
>+  list_hash_table = hash_table_ggc<list_hasher>::create_ggc (61);
>   register_scoped_attributes (std_attribute_table, NULL);
> }
> 
>Index: cp/typeck2.c
>===================================================================
>--- cp/typeck2.c	(revision 275695)
>+++ cp/typeck2.c	(working copy)
>@@ -277,7 +277,7 @@
> 
>       if (!abstract_pending_vars)
> 	abstract_pending_vars
>-	  = hash_table<abstract_type_hasher>::create_ggc (31);
>+	  = hash_table_ggc<abstract_type_hasher>::create_ggc (31);
> 
>       pending_abstract_type **slot
>  	= abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
>Index: dbgcnt.c
>===================================================================
>--- dbgcnt.c	(revision 275695)
>+++ dbgcnt.c	(working copy)
>@@ -24,6 +24,7 @@
> #include "coretypes.h"
> #include "diagnostic-core.h"
> #include "dumpfile.h"
>+#include "vec.h"
> 
> #include "dbgcnt.h"
> 
>Index: diagnostic-show-locus.c
>===================================================================
>--- diagnostic-show-locus.c	(revision 275695)
>+++ diagnostic-show-locus.c	(working copy)
>@@ -30,6 +30,7 @@
> #include "gcc-rich-location.h"
> #include "selftest.h"
> #include "selftest-diagnostic.h"
>+#include "vec.h"
> 
> #ifdef HAVE_TERMIOS_H
> # include <termios.h>
>Index: dwarf2out.c
>===================================================================
>--- dwarf2out.c	(revision 275695)
>+++ dwarf2out.c	(working copy)
>@@ -4651,7 +4651,7 @@
> find_AT_string (const char *str, enum insert_option insert = INSERT)
> {
>   if (! debug_str_hash)
>-    debug_str_hash = hash_table<indirect_string_hasher>::create_ggc
>(10);
>+    debug_str_hash =
>hash_table_ggc<indirect_string_hasher>::create_ggc (10);
> 
>   return find_AT_string_in_table (str, debug_str_hash, insert);
> }
>@@ -5023,7 +5023,7 @@
> 
>   gcc_assert (dwarf_split_debug_info);
>   if (! addr_index_table)
>-    addr_index_table = hash_table<addr_hasher>::create_ggc (10);
>+    addr_index_table = hash_table_ggc<addr_hasher>::create_ggc (10);
>   init_addr_table_entry (&finder, kind, addr);
>addr_table_entry **slot = addr_index_table->find_slot (&finder,
>INSERT);
> 
>@@ -11170,7 +11170,7 @@
> 
>   if (! skeleton_debug_str_hash)
>     skeleton_debug_str_hash
>-      = hash_table<indirect_string_hasher>::create_ggc (10);
>+      = hash_table_ggc<indirect_string_hasher>::create_ggc (10);
> 
>   node = find_AT_string_in_table (str, skeleton_debug_str_hash);
>   find_string_form (node);
>@@ -12145,7 +12145,7 @@
>     case DW_FORM_line_strp:
>       if (!debug_line_str_hash)
> 	debug_line_str_hash
>-	  = hash_table<indirect_string_hasher>::create_ggc (10);
>+	  = hash_table_ggc<indirect_string_hasher>::create_ggc (10);
> 
>       struct indirect_string_node *node;
>       node = find_AT_string_in_table (str, debug_line_str_hash);
>@@ -23765,7 +23765,7 @@
> 	}
> 
>       if (common_block_die_table == NULL)
>-	common_block_die_table = hash_table<block_die_hasher>::create_ggc
>(10);
>+	common_block_die_table = hash_table_ggc<block_die_hasher>::create_ggc
>(10);
> 
>       com_die_arg.decl_id = DECL_UID (com_decl);
>       com_die_arg.die_parent = context_die;
>@@ -27666,7 +27666,7 @@
> 
>   if (!inline_entry_data_table)
>     inline_entry_data_table
>-      = hash_table<inline_entry_data_hasher>::create_ggc (10);
>+      = hash_table_ggc<inline_entry_data_hasher>::create_ggc (10);
> 
> 
>   inline_entry_data **iedp
>@@ -28836,17 +28836,17 @@
> dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
> {
>   /* Allocate the file_table.  */
>-  file_table = hash_table<dwarf_file_hasher>::create_ggc (50);
>+  file_table = hash_table_ggc<dwarf_file_hasher>::create_ggc (50);
> 
> #ifndef DWARF2_LINENO_DEBUGGING_INFO
>   /* Allocate the decl_die_table.  */
>-  decl_die_table = hash_table<decl_die_hasher>::create_ggc (10);
>+  decl_die_table = hash_table_ggc<decl_die_hasher>::create_ggc (10);
> 
>   /* Allocate the decl_loc_table.  */
>-  decl_loc_table = hash_table<decl_loc_hasher>::create_ggc (10);
>+  decl_loc_table = hash_table_ggc<decl_loc_hasher>::create_ggc (10);
> 
>   /* Allocate the cached_dw_loc_list_table.  */
>-  cached_dw_loc_list_table =
>hash_table<dw_loc_list_hasher>::create_ggc (10);
>+  cached_dw_loc_list_table =
>hash_table_ggc<dw_loc_list_hasher>::create_ggc (10);
> 
>   /* Allocate the initial hunk of the abbrev_die_table.  */
>   vec_alloc (abbrev_die_table, 256);
>@@ -32002,7 +32002,7 @@
> 	  {
> 	    if (!variable_value_hash)
> 	      variable_value_hash
>-		= hash_table<variable_value_hasher>::create_ggc (10);
>+		= hash_table_ggc<variable_value_hasher>::create_ggc (10);
> 
> 	    tree fndecl = DECL_CONTEXT (decl);
> 	    struct variable_value_struct *node;
>@@ -32098,7 +32098,7 @@
> 
> 	  if (! debug_line_str_hash)
> 	    debug_line_str_hash
>-	      = hash_table<indirect_string_hasher>::create_ggc (10);
>+	      = hash_table_ggc<indirect_string_hasher>::create_ggc (10);
> 
> 	  struct indirect_string_node *node
> 	    = find_AT_string_in_table (AT_string (a), debug_line_str_hash);
>Index: edit-context.c
>===================================================================
>--- edit-context.c	(revision 275695)
>+++ edit-context.c	(working copy)
>@@ -25,6 +25,7 @@
> #include "pretty-print.h"
> #include "diagnostic-color.h"
> #include "selftest.h"
>+#include "vec.h"
> 
> /* This file implements a way to track the effect of fix-its,
>    via a class edit_context; the other classes are support classes for
>Index: emit-rtl.c
>===================================================================
>--- emit-rtl.c	(revision 275695)
>+++ emit-rtl.c	(working copy)
>@@ -6218,19 +6218,19 @@
> 
>   /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE,
>      CONST_FIXED, and memory attribute hash tables.  */
>-  const_int_htab = hash_table<const_int_hasher>::create_ggc (37);
>+  const_int_htab = hash_table_ggc<const_int_hasher>::create_ggc (37);
> 
> #if TARGET_SUPPORTS_WIDE_INT
>-  const_wide_int_htab = hash_table<const_wide_int_hasher>::create_ggc
>(37);
>+  const_wide_int_htab =
>hash_table_ggc<const_wide_int_hasher>::create_ggc (37);
> #endif
>-  const_double_htab = hash_table<const_double_hasher>::create_ggc
>(37);
>+  const_double_htab = hash_table_ggc<const_double_hasher>::create_ggc
>(37);
> 
>   if (NUM_POLY_INT_COEFFS > 1)
>-    const_poly_int_htab =
>hash_table<const_poly_int_hasher>::create_ggc (37);
>+    const_poly_int_htab =
>hash_table_ggc<const_poly_int_hasher>::create_ggc (37);
> 
>-  const_fixed_htab = hash_table<const_fixed_hasher>::create_ggc (37);
>+  const_fixed_htab = hash_table_ggc<const_fixed_hasher>::create_ggc
>(37);
> 
>-  reg_attrs_htab = hash_table<reg_attr_hasher>::create_ggc (37);
>+  reg_attrs_htab = hash_table_ggc<reg_attr_hasher>::create_ggc (37);
> 
> #ifdef INIT_EXPANDERS
>/* This is to initialize {init|mark|free}_machine_status before the
>first
>Index: fibonacci_heap.h
>===================================================================
>--- fibonacci_heap.h	(revision 275695)
>+++ fibonacci_heap.h	(working copy)
>@@ -40,6 +40,8 @@
> #ifndef GCC_FIBONACCI_HEAP_H
> #define GCC_FIBONACCI_HEAP_H
> 
>+#include "vec.h"
>+
> /* Forward definition.  */
> 
> template<class K, class V>
>Index: fortran/trans-decl.c
>===================================================================
>--- fortran/trans-decl.c	(revision 275695)
>+++ fortran/trans-decl.c	(working copy)
>@@ -5095,7 +5095,7 @@
> gfc_find_module (const char *name)
> {
>   if (! module_htab)
>-    module_htab = hash_table<module_hasher>::create_ggc (10);
>+    module_htab = hash_table_ggc<module_hasher>::create_ggc (10);
> 
>   module_htab_entry **slot
>= module_htab->find_slot_with_hash (name, htab_hash_string (name),
>INSERT);
>@@ -5104,7 +5104,7 @@
>    module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
> 
>       entry->name = gfc_get_string ("%s", name);
>-      entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
>+      entry->decls = hash_table_ggc<module_decl_hasher>::create_ggc
>(10);
>       *slot = entry;
>     }
>   return *slot;
>Index: function.c
>===================================================================
>--- function.c	(revision 275695)
>+++ function.c	(working copy)
>@@ -1237,7 +1237,7 @@
> 
>   /* Set up the table to map addresses to temp slots.  */
>   if (! temp_slot_address_table)
>-    temp_slot_address_table =
>hash_table<temp_address_hasher>::create_ggc (32);
>+    temp_slot_address_table =
>hash_table_ggc<temp_address_hasher>::create_ggc (32);
>   else
>     temp_slot_address_table->empty ();
> }
>@@ -5607,7 +5607,7 @@
>   hash_table<insn_cache_hasher> *hash = *hashp;
> 
>   if (hash == NULL)
>-    *hashp = hash = hash_table<insn_cache_hasher>::create_ggc (17);
>+    *hashp = hash = hash_table_ggc<insn_cache_hasher>::create_ggc
>(17);
> 
>   for (tmp = insns; tmp != end; tmp = NEXT_INSN (tmp))
>     {
>@@ -6285,7 +6285,7 @@
>       e.type = type;
>       if (types_used_by_vars_hash == NULL)
> 	types_used_by_vars_hash
>-	  = hash_table<used_type_hasher>::create_ggc (37);
>+	  = hash_table_ggc<used_type_hasher>::create_ggc (37);
> 
>       slot = types_used_by_vars_hash->find_slot (&e, INSERT);
>       if (*slot == NULL)
>Index: function.h
>===================================================================
>--- function.h	(revision 275695)
>+++ function.h	(working copy)
>@@ -20,6 +20,7 @@
> #ifndef GCC_FUNCTION_H
> #define GCC_FUNCTION_H
> 
>+#include "vec.h"
> 
> /* Stack of pending (incomplete) sequences saved by `start_sequence'.
>    Each element describes one pending sequence.
>Index: genmatch.c
>===================================================================
>--- genmatch.c	(revision 275695)
>+++ genmatch.c	(working copy)
>@@ -29,6 +29,7 @@
> #include "hash-table.h"
> #include "hash-set.h"
> #include "is-a.h"
>+#include "vec.h"
> 
> 
>/* Stubs for GGC referenced through instantiations triggered by
>hash-map.  */
>Index: ggc-common.c
>===================================================================
>--- ggc-common.c	(revision 275695)
>+++ ggc-common.c	(working copy)
>@@ -29,6 +29,7 @@
> #include "params.h"
> #include "hosthooks.h"
> #include "plugin.h"
>+#include "vec.h"
> 
> /* When set, ggc_collect will do collection.  */
> bool ggc_force_collect;
>Index: graphds.h
>===================================================================
>--- graphds.h	(revision 275695)
>+++ graphds.h	(working copy)
>@@ -20,6 +20,8 @@
> #ifndef GCC_GRAPHDS_H
> #define GCC_GRAPHDS_H
> 
>+#include "vec.h"
>+
> /* Structure representing edge of a graph.  */
> 
> struct graph_edge
>Index: hash-map-traits.h
>===================================================================
>--- hash-map-traits.h	(revision 275695)
>+++ hash-map-traits.h	(nonexistent)
>@@ -1,188 +0,0 @@
>-/* A hash map traits.
>-   Copyright (C) 2015-2019 Free Software Foundation, Inc.
>-
>-This file is part of GCC.
>-
>-GCC is free software; you can redistribute it and/or modify it under
>-the terms of the GNU General Public License as published by the Free
>-Software Foundation; either version 3, or (at your option) any later
>-version.
>-
>-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>-WARRANTY; without even the implied warranty of MERCHANTABILITY or
>-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>-for more details.
>-
>-You should have received a copy of the GNU General Public License
>-along with GCC; see the file COPYING3.  If not see
>-<http://www.gnu.org/licenses/>.  */
>-
>-#ifndef HASH_MAP_TRAITS_H
>-#define HASH_MAP_TRAITS_H
>-
>-/* Bacause mem-stats.h uses default hashmap traits, we have to
>-   put the class to this separate header file.  */
>-
>-#include "hash-traits.h"
>-
>-/* Implement hash_map traits for a key with hash traits H.  Empty and
>-   deleted map entries are represented as empty and deleted keys.  */
>-
>-template <typename H, typename Value>
>-struct simple_hashmap_traits
>-{
>-  typedef typename H::value_type key_type;
>-  static const bool maybe_mx = true;
>-  static inline hashval_t hash (const key_type &);
>-  static inline bool equal_keys (const key_type &, const key_type &);
>-  template <typename T> static inline void remove (T &);
>-  template <typename T> static inline bool is_empty (const T &);
>-  template <typename T> static inline bool is_deleted (const T &);
>-  template <typename T> static inline void mark_empty (T &);
>-  template <typename T> static inline void mark_deleted (T &);
>-};
>-
>-template <typename H, typename Value>
>-inline hashval_t
>-simple_hashmap_traits <H, Value>::hash (const key_type &h)
>-{
>-  return H::hash (h);
>-}
>-
>-template <typename H, typename Value>
>-inline bool
>-simple_hashmap_traits <H, Value>::equal_keys (const key_type &k1,
>-					      const key_type &k2)
>-{
>-  return H::equal (k1, k2);
>-}
>-
>-template <typename H, typename Value>
>-template <typename T>
>-inline void
>-simple_hashmap_traits <H, Value>::remove (T &entry)
>-{
>-  H::remove (entry.m_key);
>-  entry.m_value.~Value ();
>-}
>-
>-template <typename H, typename Value>
>-template <typename T>
>-inline bool
>-simple_hashmap_traits <H, Value>::is_empty (const T &entry)
>-{
>-  return H::is_empty (entry.m_key);
>-}
>-
>-template <typename H, typename Value>
>-template <typename T>
>-inline bool
>-simple_hashmap_traits <H, Value>::is_deleted (const T &entry)
>-{
>-  return H::is_deleted (entry.m_key);
>-}
>-
>-template <typename H, typename Value>
>-template <typename T>
>-inline void
>-simple_hashmap_traits <H, Value>::mark_empty (T &entry)
>-{
>-  H::mark_empty (entry.m_key);
>-}
>-
>-template <typename H, typename Value>
>-template <typename T>
>-inline void
>-simple_hashmap_traits <H, Value>::mark_deleted (T &entry)
>-{
>-  H::mark_deleted (entry.m_key);
>-}
>-
>-template <typename H, typename Value>
>-struct simple_cache_map_traits: public simple_hashmap_traits<H,Value>
>-{
>-  static const bool maybe_mx = false;
>-};
>-
>-/* Implement traits for a hash_map with values of type Value for cases
>-   in which the key cannot represent empty and deleted slots.  Instead
>-   record empty and deleted entries in Value.  Derived classes must
>-   implement the hash and equal_keys functions.  */
>-
>-template <typename Value>
>-struct unbounded_hashmap_traits
>-{
>-  template <typename T> static inline void remove (T &);
>-  template <typename T> static inline bool is_empty (const T &);
>-  template <typename T> static inline bool is_deleted (const T &);
>-  template <typename T> static inline void mark_empty (T &);
>-  template <typename T> static inline void mark_deleted (T &);
>-};
>-
>-template <typename Value>
>-template <typename T>
>-inline void
>-unbounded_hashmap_traits <Value>::remove (T &entry)
>-{
>-  default_hash_traits <Value>::remove (entry.m_value);
>-}
>-
>-template <typename Value>
>-template <typename T>
>-inline bool
>-unbounded_hashmap_traits <Value>::is_empty (const T &entry)
>-{
>-  return default_hash_traits <Value>::is_empty (entry.m_value);
>-}
>-
>-template <typename Value>
>-template <typename T>
>-inline bool
>-unbounded_hashmap_traits <Value>::is_deleted (const T &entry)
>-{
>-  return default_hash_traits <Value>::is_deleted (entry.m_value);
>-}
>-
>-template <typename Value>
>-template <typename T>
>-inline void
>-unbounded_hashmap_traits <Value>::mark_empty (T &entry)
>-{
>-  default_hash_traits <Value>::mark_empty (entry.m_value);
>-}
>-
>-template <typename Value>
>-template <typename T>
>-inline void
>-unbounded_hashmap_traits <Value>::mark_deleted (T &entry)
>-{
>-  default_hash_traits <Value>::mark_deleted (entry.m_value);
>-}
>-
>-/* Implement traits for a hash_map from integer type Key to Value in
>-   cases where Key has no spare values for recording empty and deleted
>-   slots.  */
>-
>-template <typename Key, typename Value>
>-struct unbounded_int_hashmap_traits : unbounded_hashmap_traits <Value>
>-{
>-  typedef Key key_type;
>-  static inline hashval_t hash (Key);
>-  static inline bool equal_keys (Key, Key);
>-};
>-
>-template <typename Key, typename Value>
>-inline hashval_t
>-unbounded_int_hashmap_traits <Key, Value>::hash (Key k)
>-{
>-  return k;
>-}
>-
>-template <typename Key, typename Value>
>-inline bool
>-unbounded_int_hashmap_traits <Key, Value>::equal_keys (Key k1, Key k2)
>-{
>-  return k1 == k2;
>-}
>-
>-#endif // HASH_MAP_TRAITS_H
>Index: hash-map.h
>===================================================================
>--- hash-map.h	(revision 275695)
>+++ hash-map.h	(working copy)
>@@ -21,6 +21,8 @@
> #ifndef hash_map_h
> #define hash_map_h
> 
>+#include "hash-table-ggc.h"
>+
> /* Class hash_map is a hash-value based container mapping objects of
>    KeyId type to those of the Value type.
>    Both KeyId and Value may be non-trivial (non-POD) types provided
>Index: hash-table.h
>===================================================================
>--- hash-table.h	(revision 275695)
>+++ hash-table.h	(nonexistent)
>@@ -1,1231 +0,0 @@
>-/* A type-safe hash table template.
>-   Copyright (C) 2012-2019 Free Software Foundation, Inc.
>-   Contributed by Lawrence Crowl <crowl@google.com>
>-
>-This file is part of GCC.
>-
>-GCC is free software; you can redistribute it and/or modify it under
>-the terms of the GNU General Public License as published by the Free
>-Software Foundation; either version 3, or (at your option) any later
>-version.
>-
>-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
>-WARRANTY; without even the implied warranty of MERCHANTABILITY or
>-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
>-for more details.
>-
>-You should have received a copy of the GNU General Public License
>-along with GCC; see the file COPYING3.  If not see
>-<http://www.gnu.org/licenses/>.  */
>-
>-
>-/* This file implements a typed hash table.
>-   The implementation borrows from libiberty's htab_t in hashtab.h.
>-
>-
>-   INTRODUCTION TO TYPES
>-
>-   Users of the hash table generally need to be aware of three types.
>-
>-      1. The type being placed into the hash table.  This type is
>called
>-      the value type.
>-
>-      2. The type used to describe how to handle the value type within
>-      the hash table.  This descriptor type provides the hash table
>with
>-      several things.
>-
>-         - A typedef named 'value_type' to the value type (from
>above).
>-	 Provided a suitable Descriptor class it may be a user-defined,
>-	 non-POD type.
>-
>-         - A static member function named 'hash' that takes a
>value_type
>-         (or 'const value_type &') and returns a hashval_t value.
>-
>-         - A typedef named 'compare_type' that is used to test when a
>value
>-	 is found.  This type is the comparison type.  Usually, it will be
>-	 the same as value_type and may be a user-defined, non-POD type.
>-	 If it is not the same type, you must generally explicitly compute
>-	 hash values and pass them to the hash table.
>-
>-         - A static member function named 'equal' that takes a
>value_type
>-         and a compare_type, and returns a bool.  Both arguments can
>be
>-         const references.
>-
>-         - A static function named 'remove' that takes an value_type
>pointer
>-         and frees the memory allocated by it.  This function is used
>when
>-         individual elements of the table need to be disposed of
>(e.g.,
>-         when deleting a hash table, removing elements from the table,
>etc).
>-
>-	 - An optional static function named 'keep_cache_entry'.  This
>-	 function is provided only for garbage-collected elements that
>-	 are not marked by the normal gc mark pass.  It describes what
>-	 what should happen to the element at the end of the gc mark phase.
>-	 The return value should be:
>-	   - 0 if the element should be deleted
>-	   - 1 if the element should be kept and needs to be marked
>-	   - -1 if the element should be kept and is already marked.
>-	 Returning -1 rather than 1 is purely an optimization.
>-
>-      3. The type of the hash table itself.  (More later.)
>-
>-   In very special circumstances, users may need to know about a
>fourth type.
>-
>-      4. The template type used to describe how hash table memory
>-      is allocated.  This type is called the allocator type.  It is
>-      parameterized on the value type.  It provides two functions:
>-
>-         - A static member function named 'data_alloc'.  This function
>-         allocates the data elements in the table.
>-
>-         - A static member function named 'data_free'.  This function
>-         deallocates the data elements in the table.
>-
>-   Hash table are instantiated with two type arguments.
>-
>-      * The descriptor type, (2) above.
>-
>-      * The allocator type, (4) above.  In general, you will not need
>to
>-      provide your own allocator type.  By default, hash tables will
>use
>-      the class template xcallocator, which uses malloc/free for
>allocation.
>-
>-
>-   DEFINING A DESCRIPTOR TYPE
>-
>-   The first task in using the hash table is to describe the element
>type.
>-   We compose this into a few steps.
>-
>-      1. Decide on a removal policy for values stored in the table.
>-         hash-traits.h provides class templates for the four most
>common
>-         policies:
>-
>-         * typed_free_remove implements the static 'remove' member
>function
>-         by calling free().
>-
>-         * typed_noop_remove implements the static 'remove' member
>function
>-         by doing nothing.
>-
>-         * ggc_remove implements the static 'remove' member by doing
>nothing,
>-         but instead provides routines for gc marking and for PCH
>streaming.
>-         Use this for garbage-collected data that needs to be
>preserved across
>-         collections.
>-
>-         * ggc_cache_remove is like ggc_remove, exce
Ian Lance Taylor via gcc-patches Sept. 21, 2019, 10:28 a.m. UTC | #2
On Sat, Sep 21, 2019 at 7:22 PM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On September 21, 2019 11:12:38 AM GMT+02:00, Christian Biesinger via gcc-patches <gcc-patches@gcc.gnu.org> wrote:
> >Hello,
> >
> >I would like to move hash-table.h, hash-map.h and related files
> >to libiberty, so that GDB can make use of it.
> >
> >I see that gcc already has a C++ file in include/ (unique-ptr.h),
> >which I understand is libiberty.
> >
> >However, this patch is not complete yet (for a start, it doesn't
> >compile). Before I go further down this road, is this acceptable
> >in principle to the gcc/libiberty maintainers?
> >
> >(the bulk of the patch is including vec.h in a lot of files,
> >because hash-table.h previously included it. It doesn't
> >actually use it, and I didn't think it was necessary to
> >move that to libiberty as well, so I removed that include
> >and instead am adding it to all the files that now don't
> >compile.)
>
> The bulk seems to be hash_table to hash_table_ggc renaming. Can you explain?

Yeah, sure. If hash-table.h lives in libiberty, I wanted to reduce the
dependencies on other headers. GCC's garbage collector seems like
something that does not belong there, so I moved this create function
to a separate header, which required renaming it since it now can't be
part of the same class. (the other option would be some kind of #ifdef
GCC thing, but that seemed ugly to me)

> Also we can then rename create_ggc back to create?

Sure, that'd work.

Christian
Richard Biener Sept. 21, 2019, 12:41 p.m. UTC | #3
On September 21, 2019 12:28:57 PM GMT+02:00, Christian Biesinger <cbiesinger@google.com> wrote:
>On Sat, Sep 21, 2019 at 7:22 PM Richard Biener
><richard.guenther@gmail.com> wrote:
>>
>> On September 21, 2019 11:12:38 AM GMT+02:00, Christian Biesinger via
>gcc-patches <gcc-patches@gcc.gnu.org> wrote:
>> >Hello,
>> >
>> >I would like to move hash-table.h, hash-map.h and related files
>> >to libiberty, so that GDB can make use of it.
>> >
>> >I see that gcc already has a C++ file in include/ (unique-ptr.h),
>> >which I understand is libiberty.
>> >
>> >However, this patch is not complete yet (for a start, it doesn't
>> >compile). Before I go further down this road, is this acceptable
>> >in principle to the gcc/libiberty maintainers?
>> >
>> >(the bulk of the patch is including vec.h in a lot of files,
>> >because hash-table.h previously included it. It doesn't
>> >actually use it, and I didn't think it was necessary to
>> >move that to libiberty as well, so I removed that include
>> >and instead am adding it to all the files that now don't
>> >compile.)
>>
>> The bulk seems to be hash_table to hash_table_ggc renaming. Can you
>explain?
>
>Yeah, sure. If hash-table.h lives in libiberty, I wanted to reduce the
>dependencies on other headers. GCC's garbage collector seems like
>something that does not belong there, so I moved this create function
>to a separate header, which required renaming it since it now can't be
>part of the same class. (the other option would be some kind of #ifdef
>GCC thing, but that seemed ugly to me)

As long as gengtype can still pick up everything correctly via the GTY annotations that's probably OK. 

>> Also we can then rename create_ggc back to create?
>
>Sure, that'd work.
>
>Christian
Ian Lance Taylor via gcc-patches Sept. 25, 2019, 11:52 p.m. UTC | #4
On Sat, Sep 21, 2019 at 7:41 AM Richard Biener
<richard.guenther@gmail.com> wrote:
>
> On September 21, 2019 12:28:57 PM GMT+02:00, Christian Biesinger <cbiesinger@google.com> wrote:
> >On Sat, Sep 21, 2019 at 7:22 PM Richard Biener
> ><richard.guenther@gmail.com> wrote:
> >>
> >> On September 21, 2019 11:12:38 AM GMT+02:00, Christian Biesinger via
> >gcc-patches <gcc-patches@gcc.gnu.org> wrote:
> >> >Hello,
> >> >
> >> >I would like to move hash-table.h, hash-map.h and related files
> >> >to libiberty, so that GDB can make use of it.
> >> >
> >> >I see that gcc already has a C++ file in include/ (unique-ptr.h),
> >> >which I understand is libiberty.
> >> >
> >> >However, this patch is not complete yet (for a start, it doesn't
> >> >compile). Before I go further down this road, is this acceptable
> >> >in principle to the gcc/libiberty maintainers?
> >> >
> >> >(the bulk of the patch is including vec.h in a lot of files,
> >> >because hash-table.h previously included it. It doesn't
> >> >actually use it, and I didn't think it was necessary to
> >> >move that to libiberty as well, so I removed that include
> >> >and instead am adding it to all the files that now don't
> >> >compile.)
> >>
> >> The bulk seems to be hash_table to hash_table_ggc renaming. Can you
> >explain?
> >
> >Yeah, sure. If hash-table.h lives in libiberty, I wanted to reduce the
> >dependencies on other headers. GCC's garbage collector seems like
> >something that does not belong there, so I moved this create function
> >to a separate header, which required renaming it since it now can't be
> >part of the same class. (the other option would be some kind of #ifdef
> >GCC thing, but that seemed ugly to me)
>
> As long as gengtype can still pick up everything correctly via the GTY annotations that's probably OK.

OK, I've decided to give up on this project for now -- there are too
many GCC dependencies in this file. But I may try forking the file for
GDB.

Christian

Patch
diff mbox series

Index: Makefile.in
===================================================================
--- Makefile.in	(revision 275695)
+++ Makefile.in	(working copy)
@@ -1490,7 +1490,6 @@ 
 	spellcheck-tree.o \
 	sreal.o \
 	stack-ptr-mod.o \
-	statistics.o \
 	stmt.o \
 	stor-layout.o \
 	store-motion.o \
Index: bitmap.c
===================================================================
--- bitmap.c	(revision 275695)
+++ bitmap.c	(working copy)
@@ -22,6 +22,7 @@ 
 #include "coretypes.h"
 #include "bitmap.h"
 #include "selftest.h"
+#include "vec.h"
 
 /* Memory allocation statistics purpose instance.  */
 mem_alloc_description<bitmap_usage> bitmap_mem_desc;
Index: cfgloop.c
===================================================================
--- cfgloop.c	(revision 275695)
+++ cfgloop.c	(working copy)
@@ -1135,7 +1135,7 @@ 
 
   gcc_assert (current_loops->exits == NULL);
   current_loops->exits
-    = hash_table<loop_exit_hasher>::create_ggc (2 * number_of_loops (cfun));
+    = hash_table_ggc<loop_exit_hasher>::create_ggc (2 * number_of_loops (cfun));
 
   FOR_EACH_BB_FN (bb, cfun)
     {
Index: cgraph.c
===================================================================
--- cgraph.c	(revision 275695)
+++ cgraph.c	(working copy)
@@ -183,7 +183,7 @@ 
   version_info_node->this_node = this;
 
   if (cgraph_fnver_htab == NULL)
-    cgraph_fnver_htab = hash_table<function_version_hasher>::create_ggc (2);
+    cgraph_fnver_htab = hash_table_ggc<function_version_hasher>::create_ggc (2);
 
   *cgraph_fnver_htab->find_slot (version_info_node, INSERT)
     = version_info_node;
@@ -760,7 +760,7 @@ 
 
   if (n > 100)
     {
-      call_site_hash = hash_table<cgraph_edge_hasher>::create_ggc (120);
+      call_site_hash = hash_table_ggc<cgraph_edge_hasher>::create_ggc (120);
       for (e2 = callees; e2; e2 = e2->next_callee)
 	cgraph_add_edge_to_call_site_hash (e2);
       for (e2 = indirect_calls; e2; e2 = e2->next_callee)
Index: common/common-target.h
===================================================================
--- common/common-target.h	(revision 275695)
+++ common/common-target.h	(working copy)
@@ -22,6 +22,7 @@ 
 #ifndef GCC_COMMON_TARGET_H
 #define GCC_COMMON_TARGET_H
 
+#include "vec.h"
 
 /* Sets of optimization levels at which an option may be enabled by
    default_options_optimization.  */
Index: common/common-targhooks.h
===================================================================
--- common/common-targhooks.h	(revision 275695)
+++ common/common-targhooks.h	(working copy)
@@ -20,6 +20,8 @@ 
 #ifndef GCC_COMMON_TARGHOOKS_H
 #define GCC_COMMON_TARGHOOKS_H
 
+#include "vec.h"
+
 extern enum unwind_info_type default_except_unwind_info (struct gcc_options *);
 extern enum unwind_info_type dwarf2_except_unwind_info (struct gcc_options *);
 extern enum unwind_info_type sjlj_except_unwind_info (struct gcc_options *);
Index: config/darwin.c
===================================================================
--- config/darwin.c	(revision 275695)
+++ config/darwin.c	(working copy)
@@ -572,7 +572,7 @@ 
   sprintf (buffer, "&%s%c%s%s%s%s", quote, L_or_l, prefix, name, suffix, quote);
 
   if (!machopic_indirections)
-    machopic_indirections = hash_table<indirection_hasher>::create_ggc (37);
+    machopic_indirections = hash_table_ggc<indirection_hasher>::create_ggc (37);
 
   machopic_indirection **slot
     = machopic_indirections->find_slot_with_hash (buffer,
@@ -3454,7 +3454,7 @@ 
   rest_of_decl_compilation (cfstring_class_reference, 0, 0);
 
   /* Initialize the hash table used to hold the constant CFString objects.  */
-  cfstring_htab = hash_table<cfstring_hasher>::create_ggc (31);
+  cfstring_htab = hash_table_ggc<cfstring_hasher>::create_ggc (31);
 
   return cfstring_type_node;
 }
Index: config/i386/i386.c
===================================================================
--- config/i386/i386.c	(revision 275695)
+++ config/i386/i386.c	(working copy)
@@ -95,6 +95,7 @@ 
 #include "i386-builtins.h"
 #include "i386-expand.h"
 #include "i386-features.h"
+#include "hash-table-ggc.h"
 
 /* This file should be included last.  */
 #include "target-def.h"
@@ -11048,7 +11049,7 @@ 
   rtx rtl;
 
   if (!dllimport_map)
-    dllimport_map = hash_table<dllimport_hasher>::create_ggc (512);
+    dllimport_map = hash_table_ggc<dllimport_hasher>::create_ggc (512);
 
   in.hash = htab_hash_pointer (decl);
   in.base.from = decl;
Index: cp/constexpr.c
===================================================================
--- cp/constexpr.c	(revision 275695)
+++ cp/constexpr.c	(working copy)
@@ -895,7 +895,7 @@ 
   /* Create the constexpr function table if necessary.  */
   if (constexpr_fundef_table == NULL)
     constexpr_fundef_table
-      = hash_table<constexpr_fundef_hasher>::create_ggc (101);
+      = hash_table_ggc<constexpr_fundef_hasher>::create_ggc (101);
 
   entry.decl = fun;
   tree saved_fn = current_function_decl;
@@ -1081,7 +1081,7 @@ 
 maybe_initialize_constexpr_call_table (void)
 {
   if (constexpr_call_table == NULL)
-    constexpr_call_table = hash_table<constexpr_call_hasher>::create_ggc (101);
+    constexpr_call_table = hash_table_ggc<constexpr_call_hasher>::create_ggc (101);
 }
 
 /* During constexpr CALL_EXPR evaluation, to avoid issues with sharing when
Index: cp/decl.c
===================================================================
--- cp/decl.c	(revision 275695)
+++ cp/decl.c	(working copy)
@@ -3070,7 +3070,7 @@ 
     }
 
   if (!named_labels)
-    named_labels = hash_table<named_label_hash>::create_ggc (13);
+    named_labels = hash_table_ggc<named_label_hash>::create_ggc (13);
 
   hashval_t hash = IDENTIFIER_HASH_VALUE (id);
   named_label_entry **slot
@@ -3754,7 +3754,7 @@ 
   hashval_t hash;
 
   if (typename_htab == NULL)
-    typename_htab = hash_table<typename_hasher>::create_ggc (61);
+    typename_htab = hash_table_ggc<typename_hasher>::create_ggc (61);
 
   ti.scope = FROB_CONTEXT (context);
   ti.name = name;
Index: cp/decl2.c
===================================================================
--- cp/decl2.c	(revision 275695)
+++ cp/decl2.c	(working copy)
@@ -4612,7 +4612,7 @@ 
 record_mangling (tree decl, bool need_warning)
 {
   if (!mangled_decls)
-    mangled_decls = hash_table<mangled_decl_hash>::create_ggc (499);
+    mangled_decls = hash_table_ggc<mangled_decl_hash>::create_ggc (499);
 
   gcc_checking_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
   tree id = DECL_ASSEMBLER_NAME_RAW (decl);
Index: cp/lex.c
===================================================================
--- cp/lex.c	(revision 275695)
+++ cp/lex.c	(working copy)
@@ -625,7 +625,7 @@ 
     return error_mark_node;
 
   if (conv_type_names == NULL)
-    conv_type_names = hash_table<conv_type_hasher>::create_ggc (31);
+    conv_type_names = hash_table_ggc<conv_type_hasher>::create_ggc (31);
 
   tree *slot = conv_type_names->find_slot_with_hash
     (type, (hashval_t) TYPE_UID (type), INSERT);
@@ -703,7 +703,7 @@ 
 
   if (sel == lds_ns)
     /* Who'd create a namespace, only to put nothing in it?  */
-    ld->u.ns.bindings = hash_table<named_decl_hash>::create_ggc (499);
+    ld->u.ns.bindings = hash_table_ggc<named_decl_hash>::create_ggc (499);
 
   if (GATHER_STATISTICS)
     {
Index: cp/name-lookup.c
===================================================================
--- cp/name-lookup.c	(revision 275695)
+++ cp/name-lookup.c	(working copy)
@@ -2522,7 +2522,7 @@ 
     return;
 
   if (!extern_c_decls)
-    extern_c_decls = hash_table<named_decl_hash>::create_ggc (127);
+    extern_c_decls = hash_table_ggc<named_decl_hash>::create_ggc (127);
 
   tree *slot = extern_c_decls
     ->find_slot_with_hash (DECL_NAME (decl),
@@ -2907,7 +2907,7 @@ 
 
 	    if (cp_function_chain->extern_decl_map == NULL)
 	      cp_function_chain->extern_decl_map
-		= hash_table<cxx_int_tree_map_hasher>::create_ggc (20);
+		= hash_table_ggc<cxx_int_tree_map_hasher>::create_ggc (20);
 
 	    h = ggc_alloc<cxx_int_tree_map> ();
 	    h->uid = DECL_UID (decl);
Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 275695)
+++ cp/pt.c	(working copy)
@@ -28306,11 +28306,11 @@ 
   if (!flag_concepts)
     return;
 
-  decl_constraints = hash_table<constr_hasher>::create_ggc(37);
-  constraint_memos = hash_table<constraint_sat_hasher>::create_ggc(37);
-  concept_memos = hash_table<concept_spec_hasher>::create_ggc(37);
-  concept_expansions = hash_table<concept_spec_hasher>::create_ggc(37);
-  subsumption_table = hash_table<subsumption_hasher>::create_ggc(37);
+  decl_constraints = hash_table_ggc<constr_hasher>::create_ggc(37);
+  constraint_memos = hash_table_ggc<constraint_sat_hasher>::create_ggc(37);
+  concept_memos = hash_table_ggc<concept_spec_hasher>::create_ggc(37);
+  concept_expansions = hash_table_ggc<concept_spec_hasher>::create_ggc(37);
+  subsumption_table = hash_table_ggc<subsumption_hasher>::create_ggc(37);
 }
 
 /* __integer_pack(N) in a pack expansion expands to a sequence of numbers from
@@ -28335,8 +28335,8 @@ 
 init_template_processing (void)
 {
   /* FIXME: enable sanitization (PR87847) */
-  decl_specializations = hash_table<spec_hasher>::create_ggc (37, false);
-  type_specializations = hash_table<spec_hasher>::create_ggc (37, false);
+  decl_specializations = hash_table_ggc<spec_hasher>::create_ggc (37, false);
+  type_specializations = hash_table_ggc<spec_hasher>::create_ggc (37, false);
 
   if (cxx_dialect >= cxx11)
     declare_integer_pack ();
Index: cp/tree.c
===================================================================
--- cp/tree.c	(revision 275695)
+++ cp/tree.c	(working copy)
@@ -1011,7 +1011,7 @@ 
       hashval_t hash;
 
       if (cplus_array_htab == NULL)
-	cplus_array_htab = hash_table<cplus_array_hasher>::create_ggc (61);
+	cplus_array_htab = hash_table_ggc<cplus_array_hasher>::create_ggc (61);
       
       hash = TYPE_UID (elt_type);
       if (index_type)
@@ -4982,7 +4982,7 @@ 
 void
 init_tree (void)
 {
-  list_hash_table = hash_table<list_hasher>::create_ggc (61);
+  list_hash_table = hash_table_ggc<list_hasher>::create_ggc (61);
   register_scoped_attributes (std_attribute_table, NULL);
 }
 
Index: cp/typeck2.c
===================================================================
--- cp/typeck2.c	(revision 275695)
+++ cp/typeck2.c	(working copy)
@@ -277,7 +277,7 @@ 
 
       if (!abstract_pending_vars)
 	abstract_pending_vars
-	  = hash_table<abstract_type_hasher>::create_ggc (31);
+	  = hash_table_ggc<abstract_type_hasher>::create_ggc (31);
 
       pending_abstract_type **slot
        	= abstract_pending_vars->find_slot_with_hash (type, TYPE_UID (type),
Index: dbgcnt.c
===================================================================
--- dbgcnt.c	(revision 275695)
+++ dbgcnt.c	(working copy)
@@ -24,6 +24,7 @@ 
 #include "coretypes.h"
 #include "diagnostic-core.h"
 #include "dumpfile.h"
+#include "vec.h"
 
 #include "dbgcnt.h"
 
Index: diagnostic-show-locus.c
===================================================================
--- diagnostic-show-locus.c	(revision 275695)
+++ diagnostic-show-locus.c	(working copy)
@@ -30,6 +30,7 @@ 
 #include "gcc-rich-location.h"
 #include "selftest.h"
 #include "selftest-diagnostic.h"
+#include "vec.h"
 
 #ifdef HAVE_TERMIOS_H
 # include <termios.h>
Index: dwarf2out.c
===================================================================
--- dwarf2out.c	(revision 275695)
+++ dwarf2out.c	(working copy)
@@ -4651,7 +4651,7 @@ 
 find_AT_string (const char *str, enum insert_option insert = INSERT)
 {
   if (! debug_str_hash)
-    debug_str_hash = hash_table<indirect_string_hasher>::create_ggc (10);
+    debug_str_hash = hash_table_ggc<indirect_string_hasher>::create_ggc (10);
 
   return find_AT_string_in_table (str, debug_str_hash, insert);
 }
@@ -5023,7 +5023,7 @@ 
 
   gcc_assert (dwarf_split_debug_info);
   if (! addr_index_table)
-    addr_index_table = hash_table<addr_hasher>::create_ggc (10);
+    addr_index_table = hash_table_ggc<addr_hasher>::create_ggc (10);
   init_addr_table_entry (&finder, kind, addr);
   addr_table_entry **slot = addr_index_table->find_slot (&finder, INSERT);
 
@@ -11170,7 +11170,7 @@ 
 
   if (! skeleton_debug_str_hash)
     skeleton_debug_str_hash
-      = hash_table<indirect_string_hasher>::create_ggc (10);
+      = hash_table_ggc<indirect_string_hasher>::create_ggc (10);
 
   node = find_AT_string_in_table (str, skeleton_debug_str_hash);
   find_string_form (node);
@@ -12145,7 +12145,7 @@ 
     case DW_FORM_line_strp:
       if (!debug_line_str_hash)
 	debug_line_str_hash
-	  = hash_table<indirect_string_hasher>::create_ggc (10);
+	  = hash_table_ggc<indirect_string_hasher>::create_ggc (10);
 
       struct indirect_string_node *node;
       node = find_AT_string_in_table (str, debug_line_str_hash);
@@ -23765,7 +23765,7 @@ 
 	}
 
       if (common_block_die_table == NULL)
-	common_block_die_table = hash_table<block_die_hasher>::create_ggc (10);
+	common_block_die_table = hash_table_ggc<block_die_hasher>::create_ggc (10);
 
       com_die_arg.decl_id = DECL_UID (com_decl);
       com_die_arg.die_parent = context_die;
@@ -27666,7 +27666,7 @@ 
 
   if (!inline_entry_data_table)
     inline_entry_data_table
-      = hash_table<inline_entry_data_hasher>::create_ggc (10);
+      = hash_table_ggc<inline_entry_data_hasher>::create_ggc (10);
 
 
   inline_entry_data **iedp
@@ -28836,17 +28836,17 @@ 
 dwarf2out_init (const char *filename ATTRIBUTE_UNUSED)
 {
   /* Allocate the file_table.  */
-  file_table = hash_table<dwarf_file_hasher>::create_ggc (50);
+  file_table = hash_table_ggc<dwarf_file_hasher>::create_ggc (50);
 
 #ifndef DWARF2_LINENO_DEBUGGING_INFO
   /* Allocate the decl_die_table.  */
-  decl_die_table = hash_table<decl_die_hasher>::create_ggc (10);
+  decl_die_table = hash_table_ggc<decl_die_hasher>::create_ggc (10);
 
   /* Allocate the decl_loc_table.  */
-  decl_loc_table = hash_table<decl_loc_hasher>::create_ggc (10);
+  decl_loc_table = hash_table_ggc<decl_loc_hasher>::create_ggc (10);
 
   /* Allocate the cached_dw_loc_list_table.  */
-  cached_dw_loc_list_table = hash_table<dw_loc_list_hasher>::create_ggc (10);
+  cached_dw_loc_list_table = hash_table_ggc<dw_loc_list_hasher>::create_ggc (10);
 
   /* Allocate the initial hunk of the abbrev_die_table.  */
   vec_alloc (abbrev_die_table, 256);
@@ -32002,7 +32002,7 @@ 
 	  {
 	    if (!variable_value_hash)
 	      variable_value_hash
-		= hash_table<variable_value_hasher>::create_ggc (10);
+		= hash_table_ggc<variable_value_hasher>::create_ggc (10);
 
 	    tree fndecl = DECL_CONTEXT (decl);
 	    struct variable_value_struct *node;
@@ -32098,7 +32098,7 @@ 
 
 	  if (! debug_line_str_hash)
 	    debug_line_str_hash
-	      = hash_table<indirect_string_hasher>::create_ggc (10);
+	      = hash_table_ggc<indirect_string_hasher>::create_ggc (10);
 
 	  struct indirect_string_node *node
 	    = find_AT_string_in_table (AT_string (a), debug_line_str_hash);
Index: edit-context.c
===================================================================
--- edit-context.c	(revision 275695)
+++ edit-context.c	(working copy)
@@ -25,6 +25,7 @@ 
 #include "pretty-print.h"
 #include "diagnostic-color.h"
 #include "selftest.h"
+#include "vec.h"
 
 /* This file implements a way to track the effect of fix-its,
    via a class edit_context; the other classes are support classes for
Index: emit-rtl.c
===================================================================
--- emit-rtl.c	(revision 275695)
+++ emit-rtl.c	(working copy)
@@ -6218,19 +6218,19 @@ 
 
   /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE,
      CONST_FIXED, and memory attribute hash tables.  */
-  const_int_htab = hash_table<const_int_hasher>::create_ggc (37);
+  const_int_htab = hash_table_ggc<const_int_hasher>::create_ggc (37);
 
 #if TARGET_SUPPORTS_WIDE_INT
-  const_wide_int_htab = hash_table<const_wide_int_hasher>::create_ggc (37);
+  const_wide_int_htab = hash_table_ggc<const_wide_int_hasher>::create_ggc (37);
 #endif
-  const_double_htab = hash_table<const_double_hasher>::create_ggc (37);
+  const_double_htab = hash_table_ggc<const_double_hasher>::create_ggc (37);
 
   if (NUM_POLY_INT_COEFFS > 1)
-    const_poly_int_htab = hash_table<const_poly_int_hasher>::create_ggc (37);
+    const_poly_int_htab = hash_table_ggc<const_poly_int_hasher>::create_ggc (37);
 
-  const_fixed_htab = hash_table<const_fixed_hasher>::create_ggc (37);
+  const_fixed_htab = hash_table_ggc<const_fixed_hasher>::create_ggc (37);
 
-  reg_attrs_htab = hash_table<reg_attr_hasher>::create_ggc (37);
+  reg_attrs_htab = hash_table_ggc<reg_attr_hasher>::create_ggc (37);
 
 #ifdef INIT_EXPANDERS
   /* This is to initialize {init|mark|free}_machine_status before the first
Index: fibonacci_heap.h
===================================================================
--- fibonacci_heap.h	(revision 275695)
+++ fibonacci_heap.h	(working copy)
@@ -40,6 +40,8 @@ 
 #ifndef GCC_FIBONACCI_HEAP_H
 #define GCC_FIBONACCI_HEAP_H
 
+#include "vec.h"
+
 /* Forward definition.  */
 
 template<class K, class V>
Index: fortran/trans-decl.c
===================================================================
--- fortran/trans-decl.c	(revision 275695)
+++ fortran/trans-decl.c	(working copy)
@@ -5095,7 +5095,7 @@ 
 gfc_find_module (const char *name)
 {
   if (! module_htab)
-    module_htab = hash_table<module_hasher>::create_ggc (10);
+    module_htab = hash_table_ggc<module_hasher>::create_ggc (10);
 
   module_htab_entry **slot
     = module_htab->find_slot_with_hash (name, htab_hash_string (name), INSERT);
@@ -5104,7 +5104,7 @@ 
       module_htab_entry *entry = ggc_cleared_alloc<module_htab_entry> ();
 
       entry->name = gfc_get_string ("%s", name);
-      entry->decls = hash_table<module_decl_hasher>::create_ggc (10);
+      entry->decls = hash_table_ggc<module_decl_hasher>::create_ggc (10);
       *slot = entry;
     }
   return *slot;
Index: function.c
===================================================================
--- function.c	(revision 275695)
+++ function.c	(working copy)
@@ -1237,7 +1237,7 @@ 
 
   /* Set up the table to map addresses to temp slots.  */
   if (! temp_slot_address_table)
-    temp_slot_address_table = hash_table<temp_address_hasher>::create_ggc (32);
+    temp_slot_address_table = hash_table_ggc<temp_address_hasher>::create_ggc (32);
   else
     temp_slot_address_table->empty ();
 }
@@ -5607,7 +5607,7 @@ 
   hash_table<insn_cache_hasher> *hash = *hashp;
 
   if (hash == NULL)
-    *hashp = hash = hash_table<insn_cache_hasher>::create_ggc (17);
+    *hashp = hash = hash_table_ggc<insn_cache_hasher>::create_ggc (17);
 
   for (tmp = insns; tmp != end; tmp = NEXT_INSN (tmp))
     {
@@ -6285,7 +6285,7 @@ 
       e.type = type;
       if (types_used_by_vars_hash == NULL)
 	types_used_by_vars_hash
-	  = hash_table<used_type_hasher>::create_ggc (37);
+	  = hash_table_ggc<used_type_hasher>::create_ggc (37);
 
       slot = types_used_by_vars_hash->find_slot (&e, INSERT);
       if (*slot == NULL)
Index: function.h
===================================================================
--- function.h	(revision 275695)
+++ function.h	(working copy)
@@ -20,6 +20,7 @@ 
 #ifndef GCC_FUNCTION_H
 #define GCC_FUNCTION_H
 
+#include "vec.h"
 
 /* Stack of pending (incomplete) sequences saved by `start_sequence'.
    Each element describes one pending sequence.
Index: genmatch.c
===================================================================
--- genmatch.c	(revision 275695)
+++ genmatch.c	(working copy)
@@ -29,6 +29,7 @@ 
 #include "hash-table.h"
 #include "hash-set.h"
 #include "is-a.h"
+#include "vec.h"
 
 
 /* Stubs for GGC referenced through instantiations triggered by hash-map.  */
Index: ggc-common.c
===================================================================
--- ggc-common.c	(revision 275695)
+++ ggc-common.c	(working copy)
@@ -29,6 +29,7 @@ 
 #include "params.h"
 #include "hosthooks.h"
 #include "plugin.h"
+#include "vec.h"
 
 /* When set, ggc_collect will do collection.  */
 bool ggc_force_collect;
Index: graphds.h
===================================================================
--- graphds.h	(revision 275695)
+++ graphds.h	(working copy)
@@ -20,6 +20,8 @@ 
 #ifndef GCC_GRAPHDS_H
 #define GCC_GRAPHDS_H
 
+#include "vec.h"
+
 /* Structure representing edge of a graph.  */
 
 struct graph_edge
Index: hash-map-traits.h
===================================================================
--- hash-map-traits.h	(revision 275695)
+++ hash-map-traits.h	(nonexistent)
@@ -1,188 +0,0 @@ 
-/* A hash map traits.
-   Copyright (C) 2015-2019 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#ifndef HASH_MAP_TRAITS_H
-#define HASH_MAP_TRAITS_H
-
-/* Bacause mem-stats.h uses default hashmap traits, we have to
-   put the class to this separate header file.  */
-
-#include "hash-traits.h"
-
-/* Implement hash_map traits for a key with hash traits H.  Empty and
-   deleted map entries are represented as empty and deleted keys.  */
-
-template <typename H, typename Value>
-struct simple_hashmap_traits
-{
-  typedef typename H::value_type key_type;
-  static const bool maybe_mx = true;
-  static inline hashval_t hash (const key_type &);
-  static inline bool equal_keys (const key_type &, const key_type &);
-  template <typename T> static inline void remove (T &);
-  template <typename T> static inline bool is_empty (const T &);
-  template <typename T> static inline bool is_deleted (const T &);
-  template <typename T> static inline void mark_empty (T &);
-  template <typename T> static inline void mark_deleted (T &);
-};
-
-template <typename H, typename Value>
-inline hashval_t
-simple_hashmap_traits <H, Value>::hash (const key_type &h)
-{
-  return H::hash (h);
-}
-
-template <typename H, typename Value>
-inline bool
-simple_hashmap_traits <H, Value>::equal_keys (const key_type &k1,
-					      const key_type &k2)
-{
-  return H::equal (k1, k2);
-}
-
-template <typename H, typename Value>
-template <typename T>
-inline void
-simple_hashmap_traits <H, Value>::remove (T &entry)
-{
-  H::remove (entry.m_key);
-  entry.m_value.~Value ();
-}
-
-template <typename H, typename Value>
-template <typename T>
-inline bool
-simple_hashmap_traits <H, Value>::is_empty (const T &entry)
-{
-  return H::is_empty (entry.m_key);
-}
-
-template <typename H, typename Value>
-template <typename T>
-inline bool
-simple_hashmap_traits <H, Value>::is_deleted (const T &entry)
-{
-  return H::is_deleted (entry.m_key);
-}
-
-template <typename H, typename Value>
-template <typename T>
-inline void
-simple_hashmap_traits <H, Value>::mark_empty (T &entry)
-{
-  H::mark_empty (entry.m_key);
-}
-
-template <typename H, typename Value>
-template <typename T>
-inline void
-simple_hashmap_traits <H, Value>::mark_deleted (T &entry)
-{
-  H::mark_deleted (entry.m_key);
-}
-
-template <typename H, typename Value>
-struct simple_cache_map_traits: public simple_hashmap_traits<H,Value>
-{
-  static const bool maybe_mx = false;
-};
-
-/* Implement traits for a hash_map with values of type Value for cases
-   in which the key cannot represent empty and deleted slots.  Instead
-   record empty and deleted entries in Value.  Derived classes must
-   implement the hash and equal_keys functions.  */
-
-template <typename Value>
-struct unbounded_hashmap_traits
-{
-  template <typename T> static inline void remove (T &);
-  template <typename T> static inline bool is_empty (const T &);
-  template <typename T> static inline bool is_deleted (const T &);
-  template <typename T> static inline void mark_empty (T &);
-  template <typename T> static inline void mark_deleted (T &);
-};
-
-template <typename Value>
-template <typename T>
-inline void
-unbounded_hashmap_traits <Value>::remove (T &entry)
-{
-  default_hash_traits <Value>::remove (entry.m_value);
-}
-
-template <typename Value>
-template <typename T>
-inline bool
-unbounded_hashmap_traits <Value>::is_empty (const T &entry)
-{
-  return default_hash_traits <Value>::is_empty (entry.m_value);
-}
-
-template <typename Value>
-template <typename T>
-inline bool
-unbounded_hashmap_traits <Value>::is_deleted (const T &entry)
-{
-  return default_hash_traits <Value>::is_deleted (entry.m_value);
-}
-
-template <typename Value>
-template <typename T>
-inline void
-unbounded_hashmap_traits <Value>::mark_empty (T &entry)
-{
-  default_hash_traits <Value>::mark_empty (entry.m_value);
-}
-
-template <typename Value>
-template <typename T>
-inline void
-unbounded_hashmap_traits <Value>::mark_deleted (T &entry)
-{
-  default_hash_traits <Value>::mark_deleted (entry.m_value);
-}
-
-/* Implement traits for a hash_map from integer type Key to Value in
-   cases where Key has no spare values for recording empty and deleted
-   slots.  */
-
-template <typename Key, typename Value>
-struct unbounded_int_hashmap_traits : unbounded_hashmap_traits <Value>
-{
-  typedef Key key_type;
-  static inline hashval_t hash (Key);
-  static inline bool equal_keys (Key, Key);
-};
-
-template <typename Key, typename Value>
-inline hashval_t
-unbounded_int_hashmap_traits <Key, Value>::hash (Key k)
-{
-  return k;
-}
-
-template <typename Key, typename Value>
-inline bool
-unbounded_int_hashmap_traits <Key, Value>::equal_keys (Key k1, Key k2)
-{
-  return k1 == k2;
-}
-
-#endif // HASH_MAP_TRAITS_H
Index: hash-map.h
===================================================================
--- hash-map.h	(revision 275695)
+++ hash-map.h	(working copy)
@@ -21,6 +21,8 @@ 
 #ifndef hash_map_h
 #define hash_map_h
 
+#include "hash-table-ggc.h"
+
 /* Class hash_map is a hash-value based container mapping objects of
    KeyId type to those of the Value type.
    Both KeyId and Value may be non-trivial (non-POD) types provided
Index: hash-table.h
===================================================================
--- hash-table.h	(revision 275695)
+++ hash-table.h	(nonexistent)
@@ -1,1231 +0,0 @@ 
-/* A type-safe hash table template.
-   Copyright (C) 2012-2019 Free Software Foundation, Inc.
-   Contributed by Lawrence Crowl <crowl@google.com>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-
-/* This file implements a typed hash table.
-   The implementation borrows from libiberty's htab_t in hashtab.h.
-
-
-   INTRODUCTION TO TYPES
-
-   Users of the hash table generally need to be aware of three types.
-
-      1. The type being placed into the hash table.  This type is called
-      the value type.
-
-      2. The type used to describe how to handle the value type within
-      the hash table.  This descriptor type provides the hash table with
-      several things.
-
-         - A typedef named 'value_type' to the value type (from above).
-	 Provided a suitable Descriptor class it may be a user-defined,
-	 non-POD type.
-
-         - A static member function named 'hash' that takes a value_type
-         (or 'const value_type &') and returns a hashval_t value.
-
-         - A typedef named 'compare_type' that is used to test when a value
-	 is found.  This type is the comparison type.  Usually, it will be
-	 the same as value_type and may be a user-defined, non-POD type.
-	 If it is not the same type, you must generally explicitly compute
-	 hash values and pass them to the hash table.
-
-         - A static member function named 'equal' that takes a value_type
-         and a compare_type, and returns a bool.  Both arguments can be
-         const references.
-
-         - A static function named 'remove' that takes an value_type pointer
-         and frees the memory allocated by it.  This function is used when
-         individual elements of the table need to be disposed of (e.g.,
-         when deleting a hash table, removing elements from the table, etc).
-
-	 - An optional static function named 'keep_cache_entry'.  This
-	 function is provided only for garbage-collected elements that
-	 are not marked by the normal gc mark pass.  It describes what
-	 what should happen to the element at the end of the gc mark phase.
-	 The return value should be:
-	   - 0 if the element should be deleted
-	   - 1 if the element should be kept and needs to be marked
-	   - -1 if the element should be kept and is already marked.
-	 Returning -1 rather than 1 is purely an optimization.
-
-      3. The type of the hash table itself.  (More later.)
-
-   In very special circumstances, users may need to know about a fourth type.
-
-      4. The template type used to describe how hash table memory
-      is allocated.  This type is called the allocator type.  It is
-      parameterized on the value type.  It provides two functions:
-
-         - A static member function named 'data_alloc'.  This function
-         allocates the data elements in the table.
-
-         - A static member function named 'data_free'.  This function
-         deallocates the data elements in the table.
-
-   Hash table are instantiated with two type arguments.
-
-      * The descriptor type, (2) above.
-
-      * The allocator type, (4) above.  In general, you will not need to
-      provide your own allocator type.  By default, hash tables will use
-      the class template xcallocator, which uses malloc/free for allocation.
-
-
-   DEFINING A DESCRIPTOR TYPE
-
-   The first task in using the hash table is to describe the element type.
-   We compose this into a few steps.
-
-      1. Decide on a removal policy for values stored in the table.
-         hash-traits.h provides class templates for the four most common
-         policies:
-
-         * typed_free_remove implements the static 'remove' member function
-         by calling free().
-
-         * typed_noop_remove implements the static 'remove' member function
-         by doing nothing.
-
-         * ggc_remove implements the static 'remove' member by doing nothing,
-         but instead provides routines for gc marking and for PCH streaming.
-         Use this for garbage-collected data that needs to be preserved across
-         collections.
-
-         * ggc_cache_remove is like ggc_remove, except that it does not
-         mark the entries during the normal gc mark phase.  Instead it
-         uses 'keep_cache_entry' (described above) to keep elements that
-         were not collected and delete those that were.  Use this for
-         garbage-collected caches that should not in themselves stop
-         the data from being collected.
-
-         You can use these policies by simply deriving the descriptor type
-         from one of those class template, with the appropriate argument.
-
-         Otherwise, you need to write the static 'remove' member function
-         in the descriptor class.
-
-      2. Choose a hash function.  Write the static 'hash' member function.
-
-      3. Decide whether the lookup function should take as input an object
-	 of type value_type or something more restricted.  Define compare_type
-	 accordingly.
-
-      4. Choose an equality testing function 'equal' that compares a value_type
-	 and a compare_type.
-
-   If your elements are pointers, it is usually easiest to start with one
-   of the generic pointer descriptors described below and override the bits
-   you need to change.
-
-   AN EXAMPLE DESCRIPTOR TYPE
-
-   Suppose you want to put some_type into the hash table.  You could define
-   the descriptor type as follows.
-
-      struct some_type_hasher : nofree_ptr_hash <some_type>
-      // Deriving from nofree_ptr_hash means that we get a 'remove' that does
-      // nothing.  This choice is good for raw values.
-      {
-        static inline hashval_t hash (const value_type *);
-        static inline bool equal (const value_type *, const compare_type *);
-      };
-
-      inline hashval_t
-      some_type_hasher::hash (const value_type *e)
-      { ... compute and return a hash value for E ... }
-
-      inline bool
-      some_type_hasher::equal (const value_type *p1, const compare_type *p2)
-      { ... compare P1 vs P2.  Return true if they are the 'same' ... }
-
-
-   AN EXAMPLE HASH_TABLE DECLARATION
-
-   To instantiate a hash table for some_type:
-
-      hash_table <some_type_hasher> some_type_hash_table;
-
-   There is no need to mention some_type directly, as the hash table will
-   obtain it using some_type_hasher::value_type.
-
-   You can then use any of the functions in hash_table's public interface.
-   See hash_table for details.  The interface is very similar to libiberty's
-   htab_t.
-
-   If a hash table is used only in some rare cases, it is possible
-   to construct the hash_table lazily before first use.  This is done
-   through:
-
-      hash_table <some_type_hasher, true> some_type_hash_table;
-
-   which will cause whatever methods actually need the allocated entries
-   array to allocate it later.
-
-
-   EASY DESCRIPTORS FOR POINTERS
-
-   There are four descriptors for pointer elements, one for each of
-   the removal policies above:
-
-   * nofree_ptr_hash (based on typed_noop_remove)
-   * free_ptr_hash (based on typed_free_remove)
-   * ggc_ptr_hash (based on ggc_remove)
-   * ggc_cache_ptr_hash (based on ggc_cache_remove)
-
-   These descriptors hash and compare elements by their pointer value,
-   rather than what they point to.  So, to instantiate a hash table over
-   pointers to whatever_type, without freeing the whatever_types, use:
-
-      hash_table <nofree_ptr_hash <whatever_type> > whatever_type_hash_table;
-
-
-   HASH TABLE ITERATORS
-
-   The hash table provides standard C++ iterators.  For example, consider a
-   hash table of some_info.  We wish to consume each element of the table:
-
-      extern void consume (some_info *);
-
-   We define a convenience typedef and the hash table:
-
-      typedef hash_table <some_info_hasher> info_table_type;
-      info_table_type info_table;
-
-   Then we write the loop in typical C++ style:
-
-      for (info_table_type::iterator iter = info_table.begin ();
-           iter != info_table.end ();
-           ++iter)
-        if ((*iter).status == INFO_READY)
-          consume (&*iter);
-
-   Or with common sub-expression elimination:
-
-      for (info_table_type::iterator iter = info_table.begin ();
-           iter != info_table.end ();
-           ++iter)
-        {
-          some_info &elem = *iter;
-          if (elem.status == INFO_READY)
-            consume (&elem);
-        }
-
-   One can also use a more typical GCC style:
-
-      typedef some_info *some_info_p;
-      some_info *elem_ptr;
-      info_table_type::iterator iter;
-      FOR_EACH_HASH_TABLE_ELEMENT (info_table, elem_ptr, some_info_p, iter)
-        if (elem_ptr->status == INFO_READY)
-          consume (elem_ptr);
-
-*/
-
-
-#ifndef TYPED_HASHTAB_H
-#define TYPED_HASHTAB_H
-
-#include "statistics.h"
-#include "ggc.h"
-#include "vec.h"
-#include "hashtab.h"
-#include "inchash.h"
-#include "mem-stats-traits.h"
-#include "hash-traits.h"
-#include "hash-map-traits.h"
-
-template<typename, typename, typename> class hash_map;
-template<typename, bool, typename> class hash_set;
-
-/* The ordinary memory allocator.  */
-/* FIXME (crowl): This allocator may be extracted for wider sharing later.  */
-
-template <typename Type>
-struct xcallocator
-{
-  static Type *data_alloc (size_t count);
-  static void data_free (Type *memory);
-};
-
-
-/* Allocate memory for COUNT data blocks.  */
-
-template <typename Type>
-inline Type *
-xcallocator <Type>::data_alloc (size_t count)
-{
-  return static_cast <Type *> (xcalloc (count, sizeof (Type)));
-}
-
-
-/* Free memory for data blocks.  */
-
-template <typename Type>
-inline void
-xcallocator <Type>::data_free (Type *memory)
-{
-  return ::free (memory);
-}
-
-
-/* Table of primes and their inversion information.  */
-
-struct prime_ent
-{
-  hashval_t prime;
-  hashval_t inv;
-  hashval_t inv_m2;     /* inverse of prime-2 */
-  hashval_t shift;
-};
-
-extern struct prime_ent const prime_tab[];
-
-/* Limit number of comparisons when calling hash_table<>::verify.  */
-extern unsigned int hash_table_sanitize_eq_limit;
-
-/* Functions for computing hash table indexes.  */
-
-extern unsigned int hash_table_higher_prime_index (unsigned long n)
-   ATTRIBUTE_PURE;
-
-extern ATTRIBUTE_NORETURN ATTRIBUTE_COLD void hashtab_chk_error ();
-
-/* Return X % Y using multiplicative inverse values INV and SHIFT.
-
-   The multiplicative inverses computed above are for 32-bit types,
-   and requires that we be able to compute a highpart multiply.
-
-   FIX: I am not at all convinced that
-     3 loads, 2 multiplications, 3 shifts, and 3 additions
-   will be faster than
-     1 load and 1 modulus
-   on modern systems running a compiler.  */
-
-inline hashval_t
-mul_mod (hashval_t x, hashval_t y, hashval_t inv, int shift)
-{
-   hashval_t t1, t2, t3, t4, q, r;
-
-   t1 = ((uint64_t)x * inv) >> 32;
-   t2 = x - t1;
-   t3 = t2 >> 1;
-   t4 = t1 + t3;
-   q  = t4 >> shift;
-   r  = x - (q * y);
-
-   return r;
-}
-
-/* Compute the primary table index for HASH given current prime index.  */
-
-inline hashval_t
-hash_table_mod1 (hashval_t hash, unsigned int index)
-{
-  const struct prime_ent *p = &prime_tab[index];
-  gcc_checking_assert (sizeof (hashval_t) * CHAR_BIT <= 32);
-  return mul_mod (hash, p->prime, p->inv, p->shift);
-}
-
-/* Compute the secondary table index for HASH given current prime index.  */
-
-inline hashval_t
-hash_table_mod2 (hashval_t hash, unsigned int index)
-{
-  const struct prime_ent *p = &prime_tab[index];
-  gcc_checking_assert (sizeof (hashval_t) * CHAR_BIT <= 32);
-  return 1 + mul_mod (hash, p->prime - 2, p->inv_m2, p->shift);
-}
-
-class mem_usage;
-
-/* User-facing hash table type.
-
-   The table stores elements of type Descriptor::value_type and uses
-   the static descriptor functions described at the top of the file
-   to hash, compare and remove elements.
-
-   Specify the template Allocator to allocate and free memory.
-     The default is xcallocator.
-
-     Storage is an implementation detail and should not be used outside the
-     hash table code.
-
-*/
-template <typename Descriptor, bool Lazy = false,
-	  template<typename Type> class Allocator = xcallocator>
-class hash_table
-{
-  typedef typename Descriptor::value_type value_type;
-  typedef typename Descriptor::compare_type compare_type;
-
-public:
-  explicit hash_table (size_t, bool ggc = false,
-		       bool sanitize_eq_and_hash = true,
-		       bool gather_mem_stats = GATHER_STATISTICS,
-		       mem_alloc_origin origin = HASH_TABLE_ORIGIN
-		       CXX_MEM_STAT_INFO);
-  explicit hash_table (const hash_table &, bool ggc = false,
-		       bool sanitize_eq_and_hash = true,
-		       bool gather_mem_stats = GATHER_STATISTICS,
-		       mem_alloc_origin origin = HASH_TABLE_ORIGIN
-		       CXX_MEM_STAT_INFO);
-  ~hash_table ();
-
-  /* Create a hash_table in gc memory.  */
-  static hash_table *
-  create_ggc (size_t n, bool sanitize_eq_and_hash = true CXX_MEM_STAT_INFO)
-  {
-    hash_table *table = ggc_alloc<hash_table> ();
-    new (table) hash_table (n, true, sanitize_eq_and_hash, GATHER_STATISTICS,
-			    HASH_TABLE_ORIGIN PASS_MEM_STAT);
-    return table;
-  }
-
-  /* Current size (in entries) of the hash table.  */
-  size_t size () const { return m_size; }
-
-  /* Return the current number of elements in this hash table. */
-  size_t elements () const { return m_n_elements - m_n_deleted; }
-
-  /* Return the current number of elements in this hash table. */
-  size_t elements_with_deleted () const { return m_n_elements; }
-
-  /* This function clears all entries in this hash table.  */
-  void empty () { if (elements ()) empty_slow (); }
-
-  /* Return true when there are no elements in this hash table.  */
-  bool is_empty () const { return elements () == 0; }
-
-  /* This function clears a specified SLOT in a hash table.  It is
-     useful when you've already done the lookup and don't want to do it
-     again. */
-  void clear_slot (value_type *);
-
-  /* This function searches for a hash table entry equal to the given
-     COMPARABLE element starting with the given HASH value.  It cannot
-     be used to insert or delete an element. */
-  value_type &find_with_hash (const compare_type &, hashval_t);
-
-  /* Like find_slot_with_hash, but compute the hash value from the element.  */
-  value_type &find (const value_type &value)
-    {
-      return find_with_hash (value, Descriptor::hash (value));
-    }
-
-  value_type *find_slot (const value_type &value, insert_option insert)
-    {
-      return find_slot_with_hash (value, Descriptor::hash (value), insert);
-    }
-
-  /* This function searches for a hash table slot containing an entry
-     equal to the given COMPARABLE element and starting with the given
-     HASH.  To delete an entry, call this with insert=NO_INSERT, then
-     call clear_slot on the slot returned (possibly after doing some
-     checks).  To insert an entry, call this with insert=INSERT, then
-     write the value you want into the returned slot.  When inserting an
-     entry, NULL may be returned if memory allocation fails. */
-  value_type *find_slot_with_hash (const compare_type &comparable,
-				   hashval_t hash, enum insert_option insert);
-
-  /* This function deletes an element with the given COMPARABLE value
-     from hash table starting with the given HASH.  If there is no
-     matching element in the hash table, this function does nothing. */
-  void remove_elt_with_hash (const compare_type &, hashval_t);
-
-  /* Like remove_elt_with_hash, but compute the hash value from the
-     element.  */
-  void remove_elt (const value_type &value)
-    {
-      remove_elt_with_hash (value, Descriptor::hash (value));
-    }
-
-  /* This function scans over the entire hash table calling CALLBACK for
-     each live entry.  If CALLBACK returns false, the iteration stops.
-     ARGUMENT is passed as CALLBACK's second argument. */
-  template <typename Argument,
-	    int (*Callback) (value_type *slot, Argument argument)>
-  void traverse_noresize (Argument argument);
-
-  /* Like traverse_noresize, but does resize the table when it is too empty
-     to improve effectivity of subsequent calls.  */
-  template <typename Argument,
-	    int (*Callback) (value_type *slot, Argument argument)>
-  void traverse (Argument argument);
-
-  class iterator
-  {
-  public:
-    iterator () : m_slot (NULL), m_limit (NULL) {}
-
-    iterator (value_type *slot, value_type *limit) :
-      m_slot (slot), m_limit (limit) {}
-
-    inline value_type &operator * () { return *m_slot; }
-    void slide ();
-    inline iterator &operator ++ ();
-    bool operator != (const iterator &other) const
-      {
-	return m_slot != other.m_slot || m_limit != other.m_limit;
-      }
-
-  private:
-    value_type *m_slot;
-    value_type *m_limit;
-  };
-
-  iterator begin () const
-    {
-      if (Lazy && m_entries == NULL)
-	return iterator ();
-      iterator iter (m_entries, m_entries + m_size);
-      iter.slide ();
-      return iter;
-    }
-
-  iterator end () const { return iterator (); }
-
-  double collisions () const
-    {
-      return m_searches ? static_cast <double> (m_collisions) / m_searches : 0;
-    }
-
-private:
-  /* FIXME: Make the class assignable.  See pr90959.  */
-  void operator= (hash_table&);
-
-  template<typename T> friend void gt_ggc_mx (hash_table<T> *);
-  template<typename T> friend void gt_pch_nx (hash_table<T> *);
-  template<typename T> friend void
-    hashtab_entry_note_pointers (void *, void *, gt_pointer_operator, void *);
-  template<typename T, typename U, typename V> friend void
-  gt_pch_nx (hash_map<T, U, V> *, gt_pointer_operator, void *);
-  template<typename T, typename U>
-  friend void gt_pch_nx (hash_set<T, false, U> *, gt_pointer_operator, void *);
-  template<typename T> friend void gt_pch_nx (hash_table<T> *,
-					      gt_pointer_operator, void *);
-
-  template<typename T> friend void gt_cleare_cache (hash_table<T> *);
-
-  void empty_slow ();
-
-  value_type *alloc_entries (size_t n CXX_MEM_STAT_INFO) const;
-  value_type *find_empty_slot_for_expand (hashval_t);
-  void verify (const compare_type &comparable, hashval_t hash);
-  bool too_empty_p (unsigned int);
-  void expand ();
-  static bool is_deleted (value_type &v)
-  {
-    return Descriptor::is_deleted (v);
-  }
-
-  static bool is_empty (value_type &v)
-  {
-    return Descriptor::is_empty (v);
-  }
-
-  static void mark_deleted (value_type &v)
-  {
-    Descriptor::mark_deleted (v);
-  }
-
-  static void mark_empty (value_type &v)
-  {
-    Descriptor::mark_empty (v);
-  }
-
-  /* Table itself.  */
-  typename Descriptor::value_type *m_entries;
-
-  size_t m_size;
-
-  /* Current number of elements including also deleted elements.  */
-  size_t m_n_elements;
-
-  /* Current number of deleted elements in the table.  */
-  size_t m_n_deleted;
-
-  /* The following member is used for debugging. Its value is number
-     of all calls of `htab_find_slot' for the hash table. */
-  unsigned int m_searches;
-
-  /* The following member is used for debugging.  Its value is number
-     of collisions fixed for time of work with the hash table. */
-  unsigned int m_collisions;
-
-  /* Current size (in entries) of the hash table, as an index into the
-     table of primes.  */
-  unsigned int m_size_prime_index;
-
-  /* if m_entries is stored in ggc memory.  */
-  bool m_ggc;
-
-  /* True if the table should be sanitized for equal and hash functions.  */
-  bool m_sanitize_eq_and_hash;
-
-  /* If we should gather memory statistics for the table.  */
-#if GATHER_STATISTICS
-  bool m_gather_mem_stats;
-#else
-  static const bool m_gather_mem_stats = false;
-#endif
-};
-
-/* As mem-stats.h heavily utilizes hash maps (hash tables), we have to include
-   mem-stats.h after hash_table declaration.  */
-
-#include "mem-stats.h"
-#include "hash-map.h"
-
-extern mem_alloc_description<mem_usage>& hash_table_usage (void);
-
-/* Support function for statistics.  */
-extern void dump_hash_table_loc_statistics (void);
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-hash_table<Descriptor, Lazy, Allocator>::hash_table (size_t size, bool ggc,
-						     bool sanitize_eq_and_hash,
-						     bool gather_mem_stats
-						     ATTRIBUTE_UNUSED,
-						     mem_alloc_origin origin
-						     MEM_STAT_DECL) :
-  m_n_elements (0), m_n_deleted (0), m_searches (0), m_collisions (0),
-  m_ggc (ggc), m_sanitize_eq_and_hash (sanitize_eq_and_hash)
-#if GATHER_STATISTICS
-  , m_gather_mem_stats (gather_mem_stats)
-#endif
-{
-  unsigned int size_prime_index;
-
-  size_prime_index = hash_table_higher_prime_index (size);
-  size = prime_tab[size_prime_index].prime;
-
-  if (m_gather_mem_stats)
-    hash_table_usage ().register_descriptor (this, origin, ggc
-					     FINAL_PASS_MEM_STAT);
-
-  if (Lazy)
-    m_entries = NULL;
-  else
-    m_entries = alloc_entries (size PASS_MEM_STAT);
-  m_size = size;
-  m_size_prime_index = size_prime_index;
-}
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-hash_table<Descriptor, Lazy, Allocator>::hash_table (const hash_table &h,
-						     bool ggc,
-						     bool sanitize_eq_and_hash,
-						     bool gather_mem_stats
-						     ATTRIBUTE_UNUSED,
-						     mem_alloc_origin origin
-						     MEM_STAT_DECL) :
-  m_n_elements (h.m_n_elements), m_n_deleted (h.m_n_deleted),
-  m_searches (0), m_collisions (0), m_ggc (ggc),
-  m_sanitize_eq_and_hash (sanitize_eq_and_hash)
-#if GATHER_STATISTICS
-  , m_gather_mem_stats (gather_mem_stats)
-#endif
-{
-  size_t size = h.m_size;
-
-  if (m_gather_mem_stats)
-    hash_table_usage ().register_descriptor (this, origin, ggc
-					  FINAL_PASS_MEM_STAT);
-
-  if (Lazy && h.m_entries == NULL)
-    m_entries = NULL;
-  else
-    {
-      value_type *nentries = alloc_entries (size PASS_MEM_STAT);
-      for (size_t i = 0; i < size; ++i)
-	{
-	  value_type &entry = h.m_entries[i];
-	  if (is_deleted (entry))
-	    mark_deleted (nentries[i]);
-	  else if (!is_empty (entry))
-	    new ((void*) (nentries + i)) value_type (entry);
-	}
-      m_entries = nentries;
-    }
-  m_size = size;
-  m_size_prime_index = h.m_size_prime_index;
-}
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-hash_table<Descriptor, Lazy, Allocator>::~hash_table ()
-{
-  if (!Lazy || m_entries)
-    {
-      for (size_t i = m_size - 1; i < m_size; i--)
-	if (!is_empty (m_entries[i]) && !is_deleted (m_entries[i]))
-	  Descriptor::remove (m_entries[i]);
-
-      if (!m_ggc)
-	Allocator <value_type> ::data_free (m_entries);
-      else
-	ggc_free (m_entries);
-      if (m_gather_mem_stats)
-	hash_table_usage ().release_instance_overhead (this,
-						       sizeof (value_type)
-						       * m_size, true);
-    }
-  else if (m_gather_mem_stats)
-    hash_table_usage ().unregister_descriptor (this);
-}
-
-/* This function returns an array of empty hash table elements.  */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-inline typename hash_table<Descriptor, Lazy, Allocator>::value_type *
-hash_table<Descriptor, Lazy,
-	   Allocator>::alloc_entries (size_t n MEM_STAT_DECL) const
-{
-  value_type *nentries;
-
-  if (m_gather_mem_stats)
-    hash_table_usage ().register_instance_overhead (sizeof (value_type) * n, this);
-
-  if (!m_ggc)
-    nentries = Allocator <value_type> ::data_alloc (n);
-  else
-    nentries = ::ggc_cleared_vec_alloc<value_type> (n PASS_MEM_STAT);
-
-  gcc_assert (nentries != NULL);
-  for (size_t i = 0; i < n; i++)
-    mark_empty (nentries[i]);
-
-  return nentries;
-}
-
-/* Similar to find_slot, but without several unwanted side effects:
-    - Does not call equal when it finds an existing entry.
-    - Does not change the count of elements/searches/collisions in the
-      hash table.
-   This function also assumes there are no deleted entries in the table.
-   HASH is the hash value for the element to be inserted.  */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-typename hash_table<Descriptor, Lazy, Allocator>::value_type *
-hash_table<Descriptor, Lazy,
-	   Allocator>::find_empty_slot_for_expand (hashval_t hash)
-{
-  hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
-  size_t size = m_size;
-  value_type *slot = m_entries + index;
-  hashval_t hash2;
-
-  if (is_empty (*slot))
-    return slot;
-  gcc_checking_assert (!is_deleted (*slot));
-
-  hash2 = hash_table_mod2 (hash, m_size_prime_index);
-  for (;;)
-    {
-      index += hash2;
-      if (index >= size)
-        index -= size;
-
-      slot = m_entries + index;
-      if (is_empty (*slot))
-        return slot;
-      gcc_checking_assert (!is_deleted (*slot));
-    }
-}
-
-/* Return true if the current table is excessively big for ELTS elements.  */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-inline bool
-hash_table<Descriptor, Lazy, Allocator>::too_empty_p (unsigned int elts)
-{
-  return elts * 8 < m_size && m_size > 32;
-}
-
-/* The following function changes size of memory allocated for the
-   entries and repeatedly inserts the table elements.  The occupancy
-   of the table after the call will be about 50%.  Naturally the hash
-   table must already exist.  Remember also that the place of the
-   table entries is changed.  If memory allocation fails, this function
-   will abort.  */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Lazy, Allocator>::expand ()
-{
-  value_type *oentries = m_entries;
-  unsigned int oindex = m_size_prime_index;
-  size_t osize = size ();
-  value_type *olimit = oentries + osize;
-  size_t elts = elements ();
-
-  /* Resize only when table after removal of unused elements is either
-     too full or too empty.  */
-  unsigned int nindex;
-  size_t nsize;
-  if (elts * 2 > osize || too_empty_p (elts))
-    {
-      nindex = hash_table_higher_prime_index (elts * 2);
-      nsize = prime_tab[nindex].prime;
-    }
-  else
-    {
-      nindex = oindex;
-      nsize = osize;
-    }
-
-  value_type *nentries = alloc_entries (nsize);
-
-  if (m_gather_mem_stats)
-    hash_table_usage ().release_instance_overhead (this, sizeof (value_type)
-						    * osize);
-
-  m_entries = nentries;
-  m_size = nsize;
-  m_size_prime_index = nindex;
-  m_n_elements -= m_n_deleted;
-  m_n_deleted = 0;
-
-  value_type *p = oentries;
-  do
-    {
-      value_type &x = *p;
-
-      if (!is_empty (x) && !is_deleted (x))
-        {
-          value_type *q = find_empty_slot_for_expand (Descriptor::hash (x));
-
-          *q = x;
-        }
-
-      p++;
-    }
-  while (p < olimit);
-
-  if (!m_ggc)
-    Allocator <value_type> ::data_free (oentries);
-  else
-    ggc_free (oentries);
-}
-
-/* Implements empty() in cases where it isn't a no-op.  */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Lazy, Allocator>::empty_slow ()
-{
-  size_t size = m_size;
-  size_t nsize = size;
-  value_type *entries = m_entries;
-  int i;
-
-  for (i = size - 1; i >= 0; i--)
-    if (!is_empty (entries[i]) && !is_deleted (entries[i]))
-      Descriptor::remove (entries[i]);
-
-  /* Instead of clearing megabyte, downsize the table.  */
-  if (size > 1024*1024 / sizeof (value_type))
-    nsize = 1024 / sizeof (value_type);
-  else if (too_empty_p (m_n_elements))
-    nsize = m_n_elements * 2;
-
-  if (nsize != size)
-    {
-      int nindex = hash_table_higher_prime_index (nsize);
-      int nsize = prime_tab[nindex].prime;
-
-      if (!m_ggc)
-	Allocator <value_type> ::data_free (m_entries);
-      else
-	ggc_free (m_entries);
-
-      m_entries = alloc_entries (nsize);
-      m_size = nsize;
-      m_size_prime_index = nindex;
-    }
-  else
-    {
-#ifndef BROKEN_VALUE_INITIALIZATION
-      for ( ; size; ++entries, --size)
-	*entries = value_type ();
-#else
-      memset (entries, 0, size * sizeof (value_type));
-#endif
-    }
-  m_n_deleted = 0;
-  m_n_elements = 0;
-}
-
-/* This function clears a specified SLOT in a hash table.  It is
-   useful when you've already done the lookup and don't want to do it
-   again. */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Lazy, Allocator>::clear_slot (value_type *slot)
-{
-  gcc_checking_assert (!(slot < m_entries || slot >= m_entries + size ()
-		         || is_empty (*slot) || is_deleted (*slot)));
-
-  Descriptor::remove (*slot);
-
-  mark_deleted (*slot);
-  m_n_deleted++;
-}
-
-/* This function searches for a hash table entry equal to the given
-   COMPARABLE element starting with the given HASH value.  It cannot
-   be used to insert or delete an element. */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-typename hash_table<Descriptor, Lazy, Allocator>::value_type &
-hash_table<Descriptor, Lazy, Allocator>
-::find_with_hash (const compare_type &comparable, hashval_t hash)
-{
-  m_searches++;
-  size_t size = m_size;
-  hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
-
-  if (Lazy && m_entries == NULL)
-    m_entries = alloc_entries (size);
-  value_type *entry = &m_entries[index];
-  if (is_empty (*entry)
-      || (!is_deleted (*entry) && Descriptor::equal (*entry, comparable)))
-    return *entry;
-
-  hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
-  for (;;)
-    {
-      m_collisions++;
-      index += hash2;
-      if (index >= size)
-        index -= size;
-
-      entry = &m_entries[index];
-      if (is_empty (*entry)
-          || (!is_deleted (*entry) && Descriptor::equal (*entry, comparable)))
-	{
-#if CHECKING_P
-	  if (m_sanitize_eq_and_hash)
-	    verify (comparable, hash);
-#endif
-	  return *entry;
-	}
-    }
-}
-
-/* This function searches for a hash table slot containing an entry
-   equal to the given COMPARABLE element and starting with the given
-   HASH.  To delete an entry, call this with insert=NO_INSERT, then
-   call clear_slot on the slot returned (possibly after doing some
-   checks).  To insert an entry, call this with insert=INSERT, then
-   write the value you want into the returned slot.  When inserting an
-   entry, NULL may be returned if memory allocation fails. */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-typename hash_table<Descriptor, Lazy, Allocator>::value_type *
-hash_table<Descriptor, Lazy, Allocator>
-::find_slot_with_hash (const compare_type &comparable, hashval_t hash,
-		       enum insert_option insert)
-{
-  if (Lazy && m_entries == NULL)
-    {
-      if (insert == INSERT)
-	m_entries = alloc_entries (m_size);
-      else
-	return NULL;
-    }
-  if (insert == INSERT && m_size * 3 <= m_n_elements * 4)
-    expand ();
-
-#if CHECKING_P
-  if (m_sanitize_eq_and_hash)
-    verify (comparable, hash);
-#endif
-
-  m_searches++;
-  value_type *first_deleted_slot = NULL;
-  hashval_t index = hash_table_mod1 (hash, m_size_prime_index);
-  hashval_t hash2 = hash_table_mod2 (hash, m_size_prime_index);
-  value_type *entry = &m_entries[index];
-  size_t size = m_size;
-  if (is_empty (*entry))
-    goto empty_entry;
-  else if (is_deleted (*entry))
-    first_deleted_slot = &m_entries[index];
-  else if (Descriptor::equal (*entry, comparable))
-    return &m_entries[index];
-
-  for (;;)
-    {
-      m_collisions++;
-      index += hash2;
-      if (index >= size)
-	index -= size;
-
-      entry = &m_entries[index];
-      if (is_empty (*entry))
-	goto empty_entry;
-      else if (is_deleted (*entry))
-	{
-	  if (!first_deleted_slot)
-	    first_deleted_slot = &m_entries[index];
-	}
-      else if (Descriptor::equal (*entry, comparable))
-	return &m_entries[index];
-    }
-
- empty_entry:
-  if (insert == NO_INSERT)
-    return NULL;
-
-  if (first_deleted_slot)
-    {
-      m_n_deleted--;
-      mark_empty (*first_deleted_slot);
-      return first_deleted_slot;
-    }
-
-  m_n_elements++;
-  return &m_entries[index];
-}
-
-/* Verify that all existing elements in th hash table which are
-   equal to COMPARABLE have an equal HASH value provided as argument.  */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Lazy, Allocator>
-::verify (const compare_type &comparable, hashval_t hash)
-{
-  for (size_t i = 0; i < MIN (hash_table_sanitize_eq_limit, m_size); i++)
-    {
-      value_type *entry = &m_entries[i];
-      if (!is_empty (*entry) && !is_deleted (*entry)
-	  && hash != Descriptor::hash (*entry)
-	  && Descriptor::equal (*entry, comparable))
-	hashtab_chk_error ();
-    }
-}
-
-/* This function deletes an element with the given COMPARABLE value
-   from hash table starting with the given HASH.  If there is no
-   matching element in the hash table, this function does nothing. */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Lazy, Allocator>
-::remove_elt_with_hash (const compare_type &comparable, hashval_t hash)
-{
-  value_type *slot = find_slot_with_hash (comparable, hash, NO_INSERT);
-  if (slot == NULL)
-    return;
-
-  Descriptor::remove (*slot);
-
-  mark_deleted (*slot);
-  m_n_deleted++;
-}
-
-/* This function scans over the entire hash table calling CALLBACK for
-   each live entry.  If CALLBACK returns false, the iteration stops.
-   ARGUMENT is passed as CALLBACK's second argument. */
-
-template<typename Descriptor, bool Lazy,
-	  template<typename Type> class Allocator>
-template<typename Argument,
-	 int (*Callback)
-	 (typename hash_table<Descriptor, Lazy, Allocator>::value_type *slot,
-	 Argument argument)>
-void
-hash_table<Descriptor, Lazy, Allocator>::traverse_noresize (Argument argument)
-{
-  if (Lazy && m_entries == NULL)
-    return;
-
-  value_type *slot = m_entries;
-  value_type *limit = slot + size ();
-
-  do
-    {
-      value_type &x = *slot;
-
-      if (!is_empty (x) && !is_deleted (x))
-        if (! Callback (slot, argument))
-          break;
-    }
-  while (++slot < limit);
-}
-
-/* Like traverse_noresize, but does resize the table when it is too empty
-   to improve effectivity of subsequent calls.  */
-
-template <typename Descriptor, bool Lazy,
-	  template <typename Type> class Allocator>
-template <typename Argument,
-	  int (*Callback)
-	  (typename hash_table<Descriptor, Lazy, Allocator>::value_type *slot,
-	  Argument argument)>
-void
-hash_table<Descriptor, Lazy, Allocator>::traverse (Argument argument)
-{
-  if (too_empty_p (elements ()) && (!Lazy || m_entries))
-    expand ();
-
-  traverse_noresize <Argument, Callback> (argument);
-}
-
-/* Slide down the iterator slots until an active entry is found.  */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-void
-hash_table<Descriptor, Lazy, Allocator>::iterator::slide ()
-{
-  for ( ; m_slot < m_limit; ++m_slot )
-    {
-      value_type &x = *m_slot;
-      if (!is_empty (x) && !is_deleted (x))
-        return;
-    }
-  m_slot = NULL;
-  m_limit = NULL;
-}
-
-/* Bump the iterator.  */
-
-template<typename Descriptor, bool Lazy,
-	 template<typename Type> class Allocator>
-inline typename hash_table<Descriptor, Lazy, Allocator>::iterator &
-hash_table<Descriptor, Lazy, Allocator>::iterator::operator ++ ()
-{
-  ++m_slot;
-  slide ();
-  return *this;
-}
-
-
-/* Iterate through the elements of hash_table HTAB,
-   using hash_table <....>::iterator ITER,
-   storing each element in RESULT, which is of type TYPE.  */
-
-#define FOR_EACH_HASH_TABLE_ELEMENT(HTAB, RESULT, TYPE, ITER) \
-  for ((ITER) = (HTAB).begin (); \
-       (ITER) != (HTAB).end () ? (RESULT = *(ITER) , true) : false; \
-       ++(ITER))
-
-/* ggc walking routines.  */
-
-template<typename E>
-static inline void
-gt_ggc_mx (hash_table<E> *h)
-{
-  typedef hash_table<E> table;
-
-  if (!ggc_test_and_set_mark (h->m_entries))
-    return;
-
-  for (size_t i = 0; i < h->m_size; i++)
-    {
-      if (table::is_empty (h->m_entries[i])
-	  || table::is_deleted (h->m_entries[i]))
-	continue;
-
-      /* Use ggc_maxbe_mx so we don't mark right away for cache tables; we'll
-	 mark in gt_cleare_cache if appropriate.  */
-      E::ggc_maybe_mx (h->m_entries[i]);
-    }
-}
-
-template<typename D>
-static inline void
-hashtab_entry_note_pointers (void *obj, void *h, gt_pointer_operator op,
-			     void *cookie)
-{
-  hash_table<D> *map = static_cast<hash_table<D> *> (h);
-  gcc_checking_assert (map->m_entries == obj);
-  for (size_t i = 0; i < map->m_size; i++)
-    {
-      typedef hash_table<D> table;
-      if (table::is_empty (map->m_entries[i])
-	  || table::is_deleted (map->m_entries[i]))
-	continue;
-
-      D::pch_nx (map->m_entries[i], op, cookie);
-    }
-}
-
-template<typename D>
-static void
-gt_pch_nx (hash_table<D> *h)
-{
-  bool success
-    = gt_pch_note_object (h->m_entries, h, hashtab_entry_note_pointers<D>);
-  gcc_checking_assert (success);
-  for (size_t i = 0; i < h->m_size; i++)
-    {
-      if (hash_table<D>::is_empty (h->m_entries[i])
-	  || hash_table<D>::is_deleted (h->m_entries[i]))
-	continue;
-
-      D::pch_nx (h->m_entries[i]);
-    }
-}
-
-template<typename D>
-static inline void
-gt_pch_nx (hash_table<D> *h, gt_pointer_operator op, void *cookie)
-{
-  op (&h->m_entries, cookie);
-}
-
-template<typename H>
-inline void
-gt_cleare_cache (hash_table<H> *h)
-{
-  typedef hash_table<H> table;
-  if (!h)
-    return;
-
-  for (typename table::iterator iter = h->begin (); iter != h->end (); ++iter)
-    if (!table::is_empty (*iter) && !table::is_deleted (*iter))
-      {
-	int res = H::keep_cache_entry (*iter);
-	if (res == 0)
-	  h->clear_slot (&*iter);
-	else if (res != -1)
-	  H::ggc_mx (*iter);
-      }
-}
-
-#endif /* TYPED_HASHTAB_H */
Index: hash-traits.h
===================================================================
--- hash-traits.h	(revision 275695)
+++ hash-traits.h	(nonexistent)
@@ -1,386 +0,0 @@ 
-/* Traits for hashable types.
-   Copyright (C) 2014-2019 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#ifndef hash_traits_h
-#define hash_traits_h
-
-/* Helpful type for removing with free.  */
-
-template <typename Type>
-struct typed_free_remove
-{
-  static inline void remove (Type *p);
-};
-
-
-/* Remove with free.  */
-
-template <typename Type>
-inline void
-typed_free_remove <Type>::remove (Type *p)
-{
-  free (p);
-}
-
-/* Helpful type for removing with delete.  */
-
-template <typename Type>
-struct typed_delete_remove
-{
-  static inline void remove (Type *p);
-};
-
-
-/* Remove with delete.  */
-
-template <typename Type>
-inline void
-typed_delete_remove <Type>::remove (Type *p)
-{
-  delete p;
-}
-
-/* Helpful type for a no-op remove.  */
-
-template <typename Type>
-struct typed_noop_remove
-{
-  static inline void remove (Type &);
-};
-
-
-/* Remove doing nothing.  */
-
-template <typename Type>
-inline void
-typed_noop_remove <Type>::remove (Type &)
-{
-}
-
-
-/* Hasher for integer type Type in which Empty is a spare value that can be
-   used to mark empty slots.  If Deleted != Empty then Deleted is another
-   spare value that can be used for deleted slots; if Deleted == Empty then
-   hash table entries cannot be deleted.  */
-
-template <typename Type, Type Empty, Type Deleted = Empty>
-struct int_hash : typed_noop_remove <Type>
-{
-  typedef Type value_type;
-  typedef Type compare_type;
-
-  static inline hashval_t hash (value_type);
-  static inline bool equal (value_type existing, value_type candidate);
-  static inline void mark_deleted (Type &);
-  static inline void mark_empty (Type &);
-  static inline bool is_deleted (Type);
-  static inline bool is_empty (Type);
-};
-
-template <typename Type, Type Empty, Type Deleted>
-inline hashval_t
-int_hash <Type, Empty, Deleted>::hash (value_type x)
-{
-  return x;
-}
-
-template <typename Type, Type Empty, Type Deleted>
-inline bool
-int_hash <Type, Empty, Deleted>::equal (value_type x, value_type y)
-{
-  return x == y;
-}
-
-template <typename Type, Type Empty, Type Deleted>
-inline void
-int_hash <Type, Empty, Deleted>::mark_deleted (Type &x)
-{
-  gcc_assert (Empty != Deleted);
-  x = Deleted;
-}
-
-template <typename Type, Type Empty, Type Deleted>
-inline void
-int_hash <Type, Empty, Deleted>::mark_empty (Type &x)
-{
-  x = Empty;
-}
-
-template <typename Type, Type Empty, Type Deleted>
-inline bool
-int_hash <Type, Empty, Deleted>::is_deleted (Type x)
-{
-  return Empty != Deleted && x == Deleted;
-}
-
-template <typename Type, Type Empty, Type Deleted>
-inline bool
-int_hash <Type, Empty, Deleted>::is_empty (Type x)
-{
-  return x == Empty;
-}
-
-/* Pointer hasher based on pointer equality.  Other types of pointer hash
-   can inherit this and override the hash and equal functions with some
-   other form of equality (such as string equality).  */
-
-template <typename Type>
-struct pointer_hash
-{
-  typedef Type *value_type;
-  typedef Type *compare_type;
-
-  static inline hashval_t hash (const value_type &);
-  static inline bool equal (const value_type &existing,
-			    const compare_type &candidate);
-  static inline void mark_deleted (Type *&);
-  static inline void mark_empty (Type *&);
-  static inline bool is_deleted (Type *);
-  static inline bool is_empty (Type *);
-};
-
-template <typename Type>
-inline hashval_t
-pointer_hash <Type>::hash (const value_type &candidate)
-{
-  /* This is a really poor hash function, but it is what the current code uses,
-     so I am reusing it to avoid an additional axis in testing.  */
-  return (hashval_t) ((intptr_t)candidate >> 3);
-}
-
-template <typename Type>
-inline bool
-pointer_hash <Type>::equal (const value_type &existing,
-			   const compare_type &candidate)
-{
-  return existing == candidate;
-}
-
-template <typename Type>
-inline void
-pointer_hash <Type>::mark_deleted (Type *&e)
-{
-  e = reinterpret_cast<Type *> (1);
-}
-
-template <typename Type>
-inline void
-pointer_hash <Type>::mark_empty (Type *&e)
-{
-  e = NULL;
-}
-
-template <typename Type>
-inline bool
-pointer_hash <Type>::is_deleted (Type *e)
-{
-  return e == reinterpret_cast<Type *> (1);
-}
-
-template <typename Type>
-inline bool
-pointer_hash <Type>::is_empty (Type *e)
-{
-  return e == NULL;
-}
-
-/* Hasher for "const char *" strings, using string rather than pointer
-   equality.  */
-
-struct string_hash : pointer_hash <const char>
-{
-  static inline hashval_t hash (const char *);
-  static inline bool equal (const char *, const char *);
-};
-
-inline hashval_t
-string_hash::hash (const char *id)
-{
-  return htab_hash_string (id);
-}
-
-inline bool
-string_hash::equal (const char *id1, const char *id2)
-{
-  return strcmp (id1, id2) == 0;
-}
-
-/* Remover and marker for entries in gc memory.  */
-
-template<typename T>
-struct ggc_remove
-{
-  static void remove (T &) {}
-
-  static void
-  ggc_mx (T &p)
-  {
-    extern void gt_ggc_mx (T &);
-    gt_ggc_mx (p);
-  }
-
-  /* Overridden in ggc_cache_remove.  */
-  static void
-  ggc_maybe_mx (T &p)
-  {
-    ggc_mx (p);
-  }
-
-  static void
-  pch_nx (T &p)
-  {
-    extern void gt_pch_nx (T &);
-    gt_pch_nx (p);
-  }
-
-  static void
-  pch_nx (T &p, gt_pointer_operator op, void *cookie)
-  {
-    op (&p, cookie);
-  }
-};
-
-/* Remover and marker for "cache" entries in gc memory.  These entries can
-   be deleted if there are no non-cache references to the data.  */
-
-template<typename T>
-struct ggc_cache_remove : ggc_remove<T>
-{
-  /* Entries are weakly held because this is for caches.  */
-  static void ggc_maybe_mx (T &) {}
-
-  static int
-  keep_cache_entry (T &e)
-  {
-    return ggc_marked_p (e) ? -1 : 0;
-  }
-};
-
-/* Traits for pointer elements that should not be freed when an element
-   is deleted.  */
-
-template <typename T>
-struct nofree_ptr_hash : pointer_hash <T>, typed_noop_remove <T *> {};
-
-/* Traits for pointer elements that should be freed via free() when an
-   element is deleted.  */
-
-template <typename T>
-struct free_ptr_hash : pointer_hash <T>, typed_free_remove <T> {};
-
-/* Traits for pointer elements that should be freed via delete operand when an
-   element is deleted.  */
-
-template <typename T>
-struct delete_ptr_hash : pointer_hash <T>, typed_delete_remove <T> {};
-
-/* Traits for elements that point to gc memory.  The pointed-to data
-   must be kept across collections.  */
-
-template <typename T>
-struct ggc_ptr_hash : pointer_hash <T>, ggc_remove <T *> {};
-
-/* Traits for elements that point to gc memory.  The elements don't
-   in themselves keep the pointed-to data alive and they can be deleted
-   if the pointed-to data is going to be collected.  */
-
-template <typename T>
-struct ggc_cache_ptr_hash : pointer_hash <T>, ggc_cache_remove <T *> {};
-
-/* Traits for string elements that should not be freed when an element
-   is deleted.  */
-
-struct nofree_string_hash : string_hash, typed_noop_remove <const char *> {};
-
-/* Traits for pairs of values, using the first to record empty and
-   deleted slots.  */
-
-template <typename T1, typename T2>
-struct pair_hash
-{
-  typedef std::pair <typename T1::value_type,
-		     typename T2::value_type> value_type;
-  typedef std::pair <typename T1::compare_type,
-		     typename T2::compare_type> 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 &);
-  static inline void mark_deleted (value_type &);
-  static inline void mark_empty (value_type &);
-  static inline bool is_deleted (const value_type &);
-  static inline bool is_empty (const value_type &);
-};
-
-template <typename T1, typename T2>
-inline hashval_t
-pair_hash <T1, T2>::hash (const value_type &x)
-{
-  return iterative_hash_hashval_t (T1::hash (x.first), T2::hash (x.second));
-}
-
-template <typename T1, typename T2>
-inline bool
-pair_hash <T1, T2>::equal (const value_type &x, const compare_type &y)
-{
-  return T1::equal (x.first, y.first) && T2::equal (x.second, y.second);
-}
-
-template <typename T1, typename T2>
-inline void
-pair_hash <T1, T2>::remove (value_type &x)
-{
-  T1::remove (x.first);
-  T2::remove (x.second);
-}
-
-template <typename T1, typename T2>
-inline void
-pair_hash <T1, T2>::mark_deleted (value_type &x)
-{
-  T1::mark_deleted (x.first);
-}
-
-template <typename T1, typename T2>
-inline void
-pair_hash <T1, T2>::mark_empty (value_type &x)
-{
-  T1::mark_empty (x.first);
-}
-
-template <typename T1, typename T2>
-inline bool
-pair_hash <T1, T2>::is_deleted (const value_type &x)
-{
-  return T1::is_deleted (x.first);
-}
-
-template <typename T1, typename T2>
-inline bool
-pair_hash <T1, T2>::is_empty (const value_type &x)
-{
-  return T1::is_empty (x.first);
-}
-
-template <typename T> struct default_hash_traits : T {};
-
-template <typename T>
-struct default_hash_traits <T *> : ggc_ptr_hash <T> {};
-
-#endif
Index: inchash.h
===================================================================
--- inchash.h	(revision 275695)
+++ inchash.h	(nonexistent)
@@ -1,211 +0,0 @@ 
-/* An incremental hash abstract data type.
-   Copyright (C) 2014-2019 Free Software Foundation, Inc.
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#ifndef INCHASH_H
-#define INCHASH_H 1
-
-
-/* This file implements an incremential hash function ADT, to be used
-   by code that incrementially hashes a lot of unrelated data
-   (not in a single memory block) into a single value. The goal
-   is to make it easy to plug in efficient hash algorithms.
-   Currently it just implements the plain old jhash based
-   incremental hash from gcc's tree.c.  */
-
-hashval_t iterative_hash_host_wide_int (HOST_WIDE_INT, hashval_t);
-hashval_t iterative_hash_hashval_t (hashval_t, hashval_t);
-
-namespace inchash
-{
-
-class hash
-{
- public:
-
-  /* Start incremential hashing, optionally with SEED.  */
-  hash (hashval_t seed = 0)
-  {
-    val = seed;
-    bits = 0;
-  }
-
-  /* End incremential hashing and provide the final value.  */
-  hashval_t end ()
-  {
-    return val;
-  }
-
-  /* Add unsigned value V.  */
-  void add_int (unsigned v)
-  {
-    val = iterative_hash_hashval_t (v, val);
-  }
-
-  /* Add polynomial value V, treating each element as an unsigned int.  */
-  template<unsigned int N, typename T>
-  void add_poly_int (const poly_int_pod<N, T> &v)
-  {
-    for (unsigned int i = 0; i < N; ++i)
-      add_int (v.coeffs[i]);
-  }
-
-  /* Add HOST_WIDE_INT value V.  */
-  void add_hwi (HOST_WIDE_INT v)
-  {
-    val = iterative_hash_host_wide_int (v, val);
-  }
-
-  /* Add polynomial value V, treating each element as a HOST_WIDE_INT.  */
-  template<unsigned int N, typename T>
-  void add_poly_hwi (const poly_int_pod<N, T> &v)
-  {
-    for (unsigned int i = 0; i < N; ++i)
-      add_hwi (v.coeffs[i]);
-  }
-
-  /* Add wide_int-based value V.  */
-  template<typename T>
-  void add_wide_int (const generic_wide_int<T> &x)
-  {
-    add_int (x.get_len ());
-    for (unsigned i = 0; i < x.get_len (); i++)
-      add_hwi (x.sext_elt (i));
-  }
-
-  /* Hash in pointer PTR.  */
-  void add_ptr (const void *ptr)
-  {
-    add (&ptr, sizeof (ptr));
-  }
-
-  /* Add a memory block DATA with size LEN.  */
-  void add (const void *data, size_t len)
-  {
-    val = iterative_hash (data, len, val);
-  }
-
-  /* Merge hash value OTHER.  */
-  void merge_hash (hashval_t other)
-  {
-    val = iterative_hash_hashval_t (other, val);
-  }
-
-  /* Hash in state from other inchash OTHER.  */
-  void merge (hash &other)
-  {
-    merge_hash (other.val);
-  }
-
-  template<class T> void add_object(T &obj)
-  {
-    add (&obj, sizeof(T));
-  }
-
-  /* Support for accumulating boolean flags */
-
-  void add_flag (bool flag)
-  {
-    bits = (bits << 1) | flag;
-  }
-
-  void commit_flag ()
-  {
-    add_int (bits);
-    bits = 0;
-  }
-
-  /* Support for commutative hashing. Add A and B in a defined order
-     based on their value. This is useful for hashing commutative
-     expressions, so that A+B and B+A get the same hash.  */
-
-  void add_commutative (hash &a, hash &b)
-  {
-    if (a.end() > b.end())
-      {
-	merge (b);
-	merge (a);
-      }
-    else
-      {
-	merge (a);
-	merge (b);
-      }
-  }
-
- private:
-  hashval_t val;
-  unsigned bits;
-};
-
-}
-
-/* Borrowed from hashtab.c iterative_hash implementation.  */
-#define mix(a,b,c) \
-{ \
-  a -= b; a -= c; a ^= (c>>13); \
-  b -= c; b -= a; b ^= (a<< 8); \
-  c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
-  a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
-  b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
-  c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
-  a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
-  b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
-  c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
-}
-
-
-/* Produce good hash value combining VAL and VAL2.  */
-inline
-hashval_t
-iterative_hash_hashval_t (hashval_t val, hashval_t val2)
-{
-  /* the golden ratio; an arbitrary value.  */
-  hashval_t a = 0x9e3779b9;
-
-  mix (a, val, val2);
-  return val2;
-}
-
-/* Produce good hash value combining VAL and VAL2.  */
-
-inline
-hashval_t
-iterative_hash_host_wide_int (HOST_WIDE_INT val, hashval_t val2)
-{
-  if (sizeof (HOST_WIDE_INT) == sizeof (hashval_t))
-    return iterative_hash_hashval_t (val, val2);
-  else
-    {
-      hashval_t a = (hashval_t) val;
-      /* Avoid warnings about shifting of more than the width of the type on
-         hosts that won't execute this path.  */
-      int zero = 0;
-      hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 8 + zero));
-      mix (a, b, val2);
-      if (sizeof (HOST_WIDE_INT) > 2 * sizeof (hashval_t))
-	{
-	  hashval_t a = (hashval_t) (val >> (sizeof (hashval_t) * 16 + zero));
-	  hashval_t b = (hashval_t) (val >> (sizeof (hashval_t) * 24 + zero));
-	  mix (a, b, val2);
-	}
-      return val2;
-    }
-}
-
-#endif
Index: input.c
===================================================================
--- input.c	(revision 275695)
+++ input.c	(working copy)
@@ -25,6 +25,7 @@ 
 #include "diagnostic-core.h"
 #include "selftest.h"
 #include "cpplib.h"
+#include "vec.h"
 
 #ifndef HAVE_ICONV
 #define HAVE_ICONV 0
Index: ipa-prop.c
===================================================================
--- ipa-prop.c	(revision 275695)
+++ ipa-prop.c	(working copy)
@@ -3718,9 +3718,9 @@ 
       = (new (ggc_cleared_alloc <ipa_edge_args_sum_t> ())
 	 ipa_edge_args_sum_t (symtab, true));
   if (!ipa_bits_hash_table)
-    ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
+    ipa_bits_hash_table = hash_table_ggc<ipa_bit_ggc_hash_traits>::create_ggc (37);
   if (!ipa_vr_hash_table)
-    ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
+    ipa_vr_hash_table = hash_table_ggc<ipa_vr_ggc_hash_traits>::create_ggc (37);
 }
 
 /* Free all ipa_edge structures.  */
@@ -3751,9 +3751,9 @@ 
 ipcp_transformation_initialize (void)
 {
   if (!ipa_bits_hash_table)
-    ipa_bits_hash_table = hash_table<ipa_bit_ggc_hash_traits>::create_ggc (37);
+    ipa_bits_hash_table = hash_table_ggc<ipa_bit_ggc_hash_traits>::create_ggc (37);
   if (!ipa_vr_hash_table)
-    ipa_vr_hash_table = hash_table<ipa_vr_ggc_hash_traits>::create_ggc (37);
+    ipa_vr_hash_table = hash_table_ggc<ipa_vr_ggc_hash_traits>::create_ggc (37);
   if (ipcp_transformation_sum == NULL)
     ipcp_transformation_sum = ipcp_transformation_t::create_ggc (symtab);
 }
Index: json.h
===================================================================
--- json.h	(revision 275695)
+++ json.h	(working copy)
@@ -21,6 +21,8 @@ 
 #ifndef GCC_JSON_H
 #define GCC_JSON_H
 
+#include "vec.h"
+
 /* Implementation of JSON, a lightweight data-interchange format.
 
    See http://www.json.org/
Index: lto/lto-common.c
===================================================================
--- lto/lto-common.c	(revision 275695)
+++ lto/lto-common.c	(working copy)
@@ -1959,7 +1959,7 @@ 
 
   /* Read in per-function decl states and enter them in hash table.  */
   decl_data->function_decl_states
-    = hash_table<decl_state_hasher>::create_ggc (37);
+    = hash_table_ggc<decl_state_hasher>::create_ggc (37);
 
   for (i = 1; i < num_decl_states; i++)
     {
Index: mem-stats-traits.h
===================================================================
--- mem-stats-traits.h	(revision 275695)
+++ mem-stats-traits.h	(nonexistent)
@@ -1,41 +0,0 @@ 
-/* A memory statistics traits.
-   Copyright (C) 2015-2019 Free Software Foundation, Inc.
-   Contributed by Martin Liska  <mliska@suse.cz>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#ifndef GCC_MEM_STATS_TRAITS_H
-#define GCC_MEM_STATS_TRAITS_H
-
-/* Memory allocation origin.  */
-enum mem_alloc_origin
-{
-  HASH_TABLE_ORIGIN,
-  HASH_MAP_ORIGIN,
-  HASH_SET_ORIGIN,
-  VEC_ORIGIN,
-  BITMAP_ORIGIN,
-  GGC_ORIGIN,
-  ALLOC_POOL_ORIGIN,
-  MEM_ALLOC_ORIGIN_LENGTH
-};
-
-/* Verbose names of the memory allocation origin.  */
-static const char * mem_alloc_origin_names[] = { "Hash tables", "Hash maps",
-  "Hash sets", "Heap vectors", "Bitmaps", "GGC memory", "Allocation pool" };
-
-#endif // GCC_MEM_STATS_TRAITS_H
Index: objc/objc-act.c
===================================================================
--- objc/objc-act.c	(revision 275695)
+++ objc/objc-act.c	(working copy)
@@ -5792,7 +5792,7 @@ 
   alias_name_map = objc_map_alloc_ggc (200);
 
   /* Initialize the hash table used to hold the constant string objects.  */
-  string_htab = hash_table<objc_string_hasher>::create_ggc (31);
+  string_htab = hash_table_ggc<objc_string_hasher>::create_ggc (31);
 }
 
 /* Use the following to add a method to class_method_map or
Index: opt-suggestions.h
===================================================================
--- opt-suggestions.h	(revision 275695)
+++ opt-suggestions.h	(working copy)
@@ -21,6 +21,8 @@ 
 #ifndef GCC_OPT_PROPOSER_H
 #define GCC_OPT_PROPOSER_H
 
+#include "vec.h"
+
 /* Option proposer is class used by driver in order to provide hints
    for wrong options provided.  And it's used by --complete option that's
    intended to be invoked by BASH in order to provide better option
Index: optabs-libfuncs.c
===================================================================
--- optabs-libfuncs.c	(revision 275695)
+++ optabs-libfuncs.c	(working copy)
@@ -760,7 +760,7 @@ 
   hashval_t hash;
 
   if (libfunc_decls == NULL)
-    libfunc_decls = hash_table<libfunc_decl_hasher>::create_ggc (37);
+    libfunc_decls = hash_table_ggc<libfunc_decl_hasher>::create_ggc (37);
 
   /* See if we have already created a libfunc decl for this function.  */
   id = get_identifier (name);
@@ -865,7 +865,7 @@ 
   if (libfunc_hash)
     libfunc_hash->empty ();
   else
-    libfunc_hash = hash_table<libfunc_hasher>::create_ggc (10);
+    libfunc_hash = hash_table_ggc<libfunc_hasher>::create_ggc (10);
 
   /* Fill in the optabs with the insns we support.  */
   init_all_optabs (this_fn_optabs);
Index: opts.h
===================================================================
--- opts.h	(revision 275695)
+++ opts.h	(working copy)
@@ -21,6 +21,7 @@ 
 #define GCC_OPTS_H
 
 #include "obstack.h"
+#include "vec.h"
 
 /* Specifies how a switch's VAR_VALUE relates to its FLAG_VAR.  */
 enum cl_var_type {
Index: rtl.h
===================================================================
--- rtl.h	(revision 275695)
+++ rtl.h	(working copy)
@@ -35,6 +35,7 @@ 
 #endif  /* GENERATOR_FILE */
 
 #include "hard-reg-set.h"
+#include "vec.h"
 
 /* Value used by some passes to "recognize" noop moves as valid
  instructions.  */
Index: statistics.c
===================================================================
--- statistics.c	(revision 275695)
+++ statistics.c	(nonexistent)
@@ -1,363 +0,0 @@ 
-/* Optimization statistics functions.
-   Copyright (C) 2008-2019 Free Software Foundation, Inc.
-   Contributed by Richard Guenther  <rguenther@suse.de>
-
-This file is part of GCC.
-
-GCC is free software; you can redistribute it and/or modify it under
-the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 3, or (at your option) any later
-version.
-
-GCC is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or
-FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-for more details.
-
-You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING3.  If not see
-<http://www.gnu.org/licenses/>.  */
-
-#include "config.h"
-#include "system.h"
-#include "coretypes.h"
-#include "function.h"
-#include "tree-pass.h"
-#include "context.h"
-#include "pass_manager.h"
-
-static int statistics_dump_nr;
-static dump_flags_t statistics_dump_flags;
-static FILE *statistics_dump_file;
-
-/* Statistics entry.  A integer counter associated to a string ID
-   and value.  */
-
-struct statistics_counter {
-  const char *id;
-  int val;
-  bool histogram_p;
-  unsigned HOST_WIDE_INT count;
-  unsigned HOST_WIDE_INT prev_dumped_count;
-};
-
-/* Hashtable helpers.  */
-
-struct stats_counter_hasher : pointer_hash <statistics_counter>
-{
-  static inline hashval_t hash (const statistics_counter *);
-  static inline bool equal (const statistics_counter *,
-			    const statistics_counter *);
-  static inline void remove (statistics_counter *);
-};
-
-/* Hash a statistic counter by its string ID.  */
-
-inline hashval_t
-stats_counter_hasher::hash (const statistics_counter *c)
-{
-  return htab_hash_string (c->id) + c->val;
-}
-
-/* Compare two statistic counters by their string IDs.  */
-
-inline bool
-stats_counter_hasher::equal (const statistics_counter *c1,
-			     const statistics_counter *c2)
-{
-  return c1->val == c2->val && strcmp (c1->id, c2->id) == 0;
-}
-
-/* Free a statistics entry.  */
-
-inline void
-stats_counter_hasher::remove (statistics_counter *v)
-{
-  free (CONST_CAST (char *, v->id));
-  free (v);
-}
-
-typedef hash_table<stats_counter_hasher> stats_counter_table_type;
-
-/* Array of statistic hashes, indexed by pass id.  */
-static stats_counter_table_type **statistics_hashes;
-static unsigned nr_statistics_hashes;
-
-/* Return the current hashtable to be used for recording or printing
-   statistics.  */
-
-static stats_counter_table_type *
-curr_statistics_hash (void)
-{
-  unsigned idx;
-
-  gcc_assert (current_pass->static_pass_number >= 0);
-  idx = current_pass->static_pass_number;
-
-  if (idx < nr_statistics_hashes
-      && statistics_hashes[idx])
-    return statistics_hashes[idx];
-
-  if (idx >= nr_statistics_hashes)
-    {
-      statistics_hashes = XRESIZEVEC (stats_counter_table_type *,
-				      statistics_hashes, idx+1);
-      memset (statistics_hashes + nr_statistics_hashes, 0,
-	      (idx + 1 - nr_statistics_hashes)
-	      * sizeof (stats_counter_table_type *));
-      nr_statistics_hashes = idx + 1;
-    }
-
-  statistics_hashes[idx] = new stats_counter_table_type (15);
-
-  return statistics_hashes[idx];
-}
-
-/* Helper for statistics_fini_pass.  Print the counter difference
-   since the last dump for the pass dump files.  */
-
-int
-statistics_fini_pass_1 (statistics_counter **slot,
-			void *data ATTRIBUTE_UNUSED)
-{
-  statistics_counter *counter = *slot;
-  unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
-  if (count == 0)
-    return 1;
-  if (counter->histogram_p)
-    fprintf (dump_file, "%s == %d: " HOST_WIDE_INT_PRINT_DEC "\n",
-	     counter->id, counter->val, count);
-  else
-    fprintf (dump_file, "%s: " HOST_WIDE_INT_PRINT_DEC "\n",
-	     counter->id, count);
-  counter->prev_dumped_count = counter->count;
-  return 1;
-}
-
-/* Helper for statistics_fini_pass.  Print the counter difference
-   since the last dump for the statistics dump.  */
-
-int
-statistics_fini_pass_2 (statistics_counter **slot,
-			void *data ATTRIBUTE_UNUSED)
-{
-  statistics_counter *counter = *slot;
-  unsigned HOST_WIDE_INT count = counter->count - counter->prev_dumped_count;
-  if (count == 0)
-    return 1;
-  counter->prev_dumped_count = counter->count;
-  if (counter->histogram_p)
-    fprintf (statistics_dump_file,
-	     "%d %s \"%s == %d\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
-	     current_pass->static_pass_number,
-	     current_pass->name,
-	     counter->id, counter->val,
-	     current_function_name (),
-	     count);
-  else
-    fprintf (statistics_dump_file,
-	     "%d %s \"%s\" \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
-	     current_pass->static_pass_number,
-	     current_pass->name,
-	     counter->id,
-	     current_function_name (),
-	     count);
-  counter->prev_dumped_count = counter->count;
-  return 1;
-}
-
-/* Helper for statistics_fini_pass, reset the counters.  */
-
-int
-statistics_fini_pass_3 (statistics_counter **slot,
-			void *data ATTRIBUTE_UNUSED)
-{
-  statistics_counter *counter = *slot;
-  counter->prev_dumped_count = counter->count;
-  return 1;
-}
-
-/* Dump the current statistics incrementally.  */
-
-void
-statistics_fini_pass (void)
-{
-  if (current_pass->static_pass_number == -1)
-    return;
-
-  if (dump_file
-      && dump_flags & TDF_STATS)
-    {
-      fprintf (dump_file, "\n");
-      fprintf (dump_file, "Pass statistics of \"%s\": ", current_pass->name);
-      fprintf (dump_file, "----------------\n");
-      curr_statistics_hash ()
-	->traverse_noresize <void *, statistics_fini_pass_1> (NULL);
-      fprintf (dump_file, "\n");
-    }
-  if (statistics_dump_file
-      && !(statistics_dump_flags & TDF_STATS
-	   || statistics_dump_flags & TDF_DETAILS))
-    curr_statistics_hash ()
-      ->traverse_noresize <void *, statistics_fini_pass_2> (NULL);
-  curr_statistics_hash ()
-    ->traverse_noresize <void *, statistics_fini_pass_3> (NULL);
-}
-
-/* Helper for printing summary information.  */
-
-int
-statistics_fini_1 (statistics_counter **slot, opt_pass *pass)
-{
-  statistics_counter *counter = *slot;
-  if (counter->count == 0)
-    return 1;
-  if (counter->histogram_p)
-    fprintf (statistics_dump_file,
-	     "%d %s \"%s == %d\" " HOST_WIDE_INT_PRINT_DEC "\n",
-	     pass->static_pass_number,
-	     pass->name,
-	     counter->id, counter->val,
-	     counter->count);
-  else
-    fprintf (statistics_dump_file,
-	     "%d %s \"%s\" " HOST_WIDE_INT_PRINT_DEC "\n",
-	     pass->static_pass_number,
-	     pass->name,
-	     counter->id,
-	     counter->count);
-  return 1;
-}
-
-/* Finish the statistics and dump summary information.  */
-
-void
-statistics_fini (void)
-{
-  gcc::pass_manager *passes = g->get_passes ();
-  if (!statistics_dump_file)
-    return;
-
-  if (statistics_dump_flags & TDF_STATS)
-    {
-      unsigned i;
-      for (i = 0; i < nr_statistics_hashes; ++i)
-	if (statistics_hashes[i]
-	    && passes->get_pass_for_id (i) != NULL)
-	  statistics_hashes[i]
-	    ->traverse_noresize <opt_pass *, statistics_fini_1>
-	    (passes->get_pass_for_id (i));
-    }
-
-  dump_end (statistics_dump_nr, statistics_dump_file);
-}
-
-/* Register the statistics dump file.  */
-
-void
-statistics_early_init (void)
-{
-  gcc::dump_manager *dumps = g->get_dumps ();
-  statistics_dump_nr = dumps->dump_register (".statistics", "statistics",
-					     "statistics", DK_tree,
-					     OPTGROUP_NONE,
-					     false);
-}
-
-/* Init the statistics.  */
-
-void
-statistics_init (void)
-{
-  gcc::dump_manager *dumps = g->get_dumps ();
-  statistics_dump_file = dump_begin (statistics_dump_nr, NULL);
-  statistics_dump_flags = dumps->get_dump_file_info (statistics_dump_nr)->pflags;
-}
-
-/* Lookup or add a statistics counter in the hashtable HASH with ID, VAL
-   and HISTOGRAM_P.  */
-
-static statistics_counter *
-lookup_or_add_counter (stats_counter_table_type *hash, const char *id, int val,
-		       bool histogram_p)
-{
-  statistics_counter **counter;
-  statistics_counter c;
-  c.id = id;
-  c.val = val;
-  counter = hash->find_slot (&c, INSERT);
-  if (!*counter)
-    {
-      *counter = XNEW (statistics_counter);
-      (*counter)->id = xstrdup (id);
-      (*counter)->val = val;
-      (*counter)->histogram_p = histogram_p;
-      (*counter)->prev_dumped_count = 0;
-      (*counter)->count = 0;
-    }
-  return *counter;
-}
-
-/* Add statistics information about event ID in function FN.
-   This will increment the counter associated with ID by INCR.
-   It will also dump the event to the global statistics file if requested.  */
-
-void
-statistics_counter_event (struct function *fn, const char *id, int incr)
-{
-  statistics_counter *counter;
-
-  if ((!(dump_flags & TDF_STATS)
-       && !statistics_dump_file)
-      || incr == 0)
-    return;
-
-  if (current_pass
-      && current_pass->static_pass_number != -1)
-    {
-      counter = lookup_or_add_counter (curr_statistics_hash (), id, 0, false);
-      gcc_assert (!counter->histogram_p);
-      counter->count += incr;
-    }
-
-  if (!statistics_dump_file
-      || !(statistics_dump_flags & TDF_DETAILS))
-    return;
-
-  fprintf (statistics_dump_file,
-	   "%d %s \"%s\" \"%s\" %d\n",
-	   current_pass ? current_pass->static_pass_number : -1,
-	   current_pass ? current_pass->name : "none",
-	   id,
-	   function_name (fn),
-	   incr);
-}
-
-/* Add statistics information about event ID in function FN with the
-   histogram value VAL.
-   It will dump the event to the global statistics file if requested.  */
-
-void
-statistics_histogram_event (struct function *fn, const char *id, int val)
-{
-  statistics_counter *counter;
-
-  if (!(dump_flags & TDF_STATS)
-      && !statistics_dump_file)
-    return;
-
-  counter = lookup_or_add_counter (curr_statistics_hash (), id, val, true);
-  gcc_assert (counter->histogram_p);
-  counter->count += 1;
-
-  if (!statistics_dump_file
-      || !(statistics_dump_flags & TDF_DETAILS))
-    return;
-
-  fprintf (statistics_dump_file,
-	   "%d %s \"%s == %d\" \"%s\" 1\n",
-	   current_pass->static_pass_number,
-	   current_pass->name,
-	   id, val,
-	   function_name (fn));
-}
Index: statistics.h
===================================================================
--- statistics.h	(revision 275695)
+++ statistics.h	(nonexistent)
@@ -1,71 +0,0 @@ 
-/* Memory and optimization statistics helpers.
-   Copyright (C) 2004-2019 Free Software Foundation, Inc.
-   Contributed by Cygnus Solutions.
-
-   This file is part of GCC.
-
-   GCC is free software; you can redistribute it and/or modify it
-   under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 3, or (at your option)
-   any later version.
-
-   GCC is distributed in the hope that it will be useful, but WITHOUT
-   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-   or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
-   License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with GCC; see the file COPYING3.  If not see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef GCC_STATISTICS
-#define GCC_STATISTICS
-
-#if ! defined GATHER_STATISTICS
-#error GATHER_STATISTICS must be defined
-#endif
-
-#define GCC_MEM_STAT_ARGUMENTS const char * ARG_UNUSED (_loc_name), int ARG_UNUSED (_loc_line), const char * ARG_UNUSED (_loc_function)
-#if GATHER_STATISTICS
-#define ALONE_MEM_STAT_DECL GCC_MEM_STAT_ARGUMENTS
-#define ALONE_FINAL_MEM_STAT_DECL ALONE_MEM_STAT_DECL
-#define ALONE_PASS_MEM_STAT _loc_name, _loc_line,  _loc_function
-#define ALONE_FINAL_PASS_MEM_STAT ALONE_PASS_MEM_STAT
-#define ALONE_MEM_STAT_INFO __FILE__, __LINE__, __FUNCTION__
-#define MEM_STAT_DECL , ALONE_MEM_STAT_DECL
-#define FINAL_MEM_STAT_DECL , ALONE_FINAL_MEM_STAT_DECL
-#define PASS_MEM_STAT , ALONE_PASS_MEM_STAT
-#define FINAL_PASS_MEM_STAT , ALONE_FINAL_PASS_MEM_STAT
-#define MEM_STAT_INFO , ALONE_MEM_STAT_INFO
-#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
-#define ALONE_CXX_MEM_STAT_INFO const char * _loc_name = __builtin_FILE (), int _loc_line = __builtin_LINE (), const char * _loc_function = __builtin_FUNCTION ()
-#else
-#define ALONE_CXX_MEM_STAT_INFO const char * _loc_name = __FILE__, int _loc_line = __LINE__, const char * _loc_function = NULL
-#endif
-#define CXX_MEM_STAT_INFO , ALONE_CXX_MEM_STAT_INFO
-#else
-#define ALONE_MEM_STAT_DECL void
-#define ALONE_FINAL_MEM_STAT_DECL GCC_MEM_STAT_ARGUMENTS
-#define ALONE_PASS_MEM_STAT
-#define ALONE_FINAL_PASS_MEM_STAT 0,0,0
-#define ALONE_MEM_STAT_INFO
-#define MEM_STAT_DECL
-#define FINAL_MEM_STAT_DECL , ALONE_FINAL_MEM_STAT_DECL
-#define PASS_MEM_STAT
-#define FINAL_PASS_MEM_STAT , ALONE_FINAL_PASS_MEM_STAT
-#define MEM_STAT_INFO ALONE_MEM_STAT_INFO
-#define ALONE_CXX_MEM_STAT_INFO
-#define CXX_MEM_STAT_INFO
-#endif
-
-struct function;
-
-/* In statistics.c */
-extern void statistics_early_init (void);
-extern void statistics_init (void);
-extern void statistics_fini (void);
-extern void statistics_fini_pass (void);
-extern void statistics_counter_event (struct function *, const char *, int);
-extern void statistics_histogram_event (struct function *, const char *, int);
-
-#endif
Index: symtab.c
===================================================================
--- symtab.c	(revision 275695)
+++ symtab.c	(working copy)
@@ -261,7 +261,7 @@ 
   symtab_node *node;
   if (!assembler_name_hash)
     {
-      assembler_name_hash = hash_table<asmname_hasher>::create_ggc (10);
+      assembler_name_hash = hash_table_ggc<asmname_hasher>::create_ggc (10);
       FOR_EACH_SYMBOL (node)
 	insert_to_assembler_name_hash (node, false);
     }
@@ -1570,7 +1570,7 @@ 
       return;
     }
   if (!symtab->section_hash)
-    symtab->section_hash = hash_table<section_name_hasher>::create_ggc (10);
+    symtab->section_hash = hash_table_ggc<section_name_hasher>::create_ggc (10);
   slot = symtab->section_hash->find_slot_with_hash (section,
 						    htab_hash_string (section),
 						    INSERT);
Index: target.h
===================================================================
--- target.h	(revision 275695)
+++ target.h	(working copy)
@@ -51,6 +51,7 @@ 
 #include "insn-codes.h"
 #include "tm.h"
 #include "hard-reg-set.h"
+#include "vec.h"
 
 #if CHECKING_P
 
Index: timevar.c
===================================================================
--- timevar.c	(revision 275695)
+++ timevar.c	(working copy)
@@ -23,6 +23,7 @@ 
 #include "coretypes.h"
 #include "timevar.h"
 #include "options.h"
+#include "vec.h"
 
 #ifndef HAVE_CLOCK_T
 typedef int clock_t;
Index: trans-mem.c
===================================================================
--- trans-mem.c	(revision 275695)
+++ trans-mem.c	(working copy)
@@ -479,7 +479,7 @@ 
   DECL_UNINLINABLE (from) = 1;
 
   if (tm_wrap_map == NULL)
-    tm_wrap_map = hash_table<tm_wrapper_hasher>::create_ggc (32);
+    tm_wrap_map = hash_table_ggc<tm_wrapper_hasher>::create_ggc (32);
 
   h = ggc_alloc<tree_map> ();
   h->hash = htab_hash_pointer (from);
@@ -3192,7 +3192,7 @@ 
   // Record the need for the edge for the benefit of the rtl passes.
   if (cfun->gimple_df->tm_restart == NULL)
     cfun->gimple_df->tm_restart
-      = hash_table<tm_restart_hasher>::create_ggc (31);
+      = hash_table_ggc<tm_restart_hasher>::create_ggc (31);
 
   struct tm_restart_node dummy;
   dummy.stmt = stmt;
@@ -3278,7 +3278,7 @@ 
 
       if (cfun->gimple_df->tm_restart == NULL)
 	cfun->gimple_df->tm_restart
-	  = hash_table<tm_restart_hasher>::create_ggc (31);
+	  = hash_table_ggc<tm_restart_hasher>::create_ggc (31);
 
       // All TM builtins have an abnormal edge to the outer-most transaction.
       // We never restart inner transactions.
Index: tree-core.h
===================================================================
--- tree-core.h	(revision 275695)
+++ tree-core.h	(working copy)
@@ -21,6 +21,7 @@ 
 #define GCC_TREE_CORE_H
 
 #include "symtab.h"
+#include "vec.h"
 
 /* This file contains all the data structures that define the 'tree' type.
    There are no accessor macros nor functions in this file. Only the
Index: tree-scalar-evolution.c
===================================================================
--- tree-scalar-evolution.c	(revision 275695)
+++ tree-scalar-evolution.c	(working copy)
@@ -2982,7 +2982,7 @@ 
 
   gcc_assert (! scev_initialized_p ());
 
-  scalar_evolution_info = hash_table<scev_info_hasher>::create_ggc (100);
+  scalar_evolution_info = hash_table_ggc<scev_info_hasher>::create_ggc (100);
 
   FOR_EACH_LOOP (loop, 0)
     {
Index: tree-ssa.c
===================================================================
--- tree-ssa.c	(revision 275695)
+++ tree-ssa.c	(working copy)
@@ -1218,7 +1218,7 @@ 
 init_tree_ssa (struct function *fn)
 {
   fn->gimple_df = ggc_cleared_alloc<gimple_df> ();
-  fn->gimple_df->default_defs = hash_table<ssa_name_hasher>::create_ggc (20);
+  fn->gimple_df->default_defs = hash_table_ggc<ssa_name_hasher>::create_ggc (20);
   pt_solution_reset (&fn->gimple_df->escaped);
   init_ssanames (fn, 0);
 }
Index: tree.c
===================================================================
--- tree.c	(revision 275695)
+++ tree.c	(working copy)
@@ -672,21 +672,21 @@ 
 {
   /* Initialize the hash table of types.  */
   type_hash_table
-    = hash_table<type_cache_hasher>::create_ggc (TYPE_HASH_INITIAL_SIZE);
+    = hash_table_ggc<type_cache_hasher>::create_ggc (TYPE_HASH_INITIAL_SIZE);
 
   debug_expr_for_decl
-    = hash_table<tree_decl_map_cache_hasher>::create_ggc (512);
+    = hash_table_ggc<tree_decl_map_cache_hasher>::create_ggc (512);
 
   value_expr_for_decl
-    = hash_table<tree_decl_map_cache_hasher>::create_ggc (512);
+    = hash_table_ggc<tree_decl_map_cache_hasher>::create_ggc (512);
 
-  int_cst_hash_table = hash_table<int_cst_hasher>::create_ggc (1024);
+  int_cst_hash_table = hash_table_ggc<int_cst_hasher>::create_ggc (1024);
 
-  poly_int_cst_hash_table = hash_table<poly_int_cst_hasher>::create_ggc (64);
+  poly_int_cst_hash_table = hash_table_ggc<poly_int_cst_hasher>::create_ggc (64);
 
   int_cst_node = make_int_cst (1, 1);
 
-  cl_option_hash_table = hash_table<cl_option_hasher>::create_ggc (64);
+  cl_option_hash_table = hash_table_ggc<cl_option_hasher>::create_ggc (64);
 
   cl_optimization_node = make_node (OPTIMIZATION_NODE);
   cl_target_option_node = make_node (TARGET_OPTION_NODE);
@@ -6852,7 +6852,7 @@ 
   if (DECL_HAS_DEBUG_ARGS_P (from))
     return decl_debug_args_lookup (from);
   if (debug_args_for_decl == NULL)
-    debug_args_for_decl = hash_table<tree_vec_map_cache_hasher>::create_ggc (64);
+    debug_args_for_decl = hash_table_ggc<tree_vec_map_cache_hasher>::create_ggc (64);
   h = ggc_alloc<tree_vec_map> ();
   h->base.from = from;
   h->to = NULL;
Index: typed-splay-tree.c
===================================================================
--- typed-splay-tree.c	(revision 275695)
+++ typed-splay-tree.c	(working copy)
@@ -22,6 +22,7 @@ 
 #include "coretypes.h"
 #include "typed-splay-tree.h"
 #include "selftest.h"
+#include "vec.h"
 
 #if CHECKING_P
 
Index: ubsan.c
===================================================================
--- ubsan.c	(revision 275695)
+++ ubsan.c	(working copy)
@@ -90,7 +90,7 @@ 
   if (decl_tree_for_type == NULL)
     {
       decl_tree_for_type
-	= hash_table<tree_type_map_cache_hasher>::create_ggc (10);
+	= hash_table_ggc<tree_type_map_cache_hasher>::create_ggc (10);
       /* That also means we don't have to bother with the lookup.  */
       return NULL_TREE;
     }
Index: varasm.c
===================================================================
--- varasm.c	(revision 275695)
+++ varasm.c	(working copy)
@@ -3788,7 +3788,7 @@ 
   struct rtx_constant_pool *pool;
 
   pool = ggc_alloc<rtx_constant_pool> ();
-  pool->const_rtx_htab = hash_table<const_rtx_desc_hasher>::create_ggc (31);
+  pool->const_rtx_htab = hash_table_ggc<const_rtx_desc_hasher>::create_ggc (31);
   pool->first = NULL;
   pool->last = NULL;
   pool->offset = 0;
@@ -6050,7 +6050,7 @@ 
   struct tree_map **slot, *h;
 
   if (tm_clone_hash == NULL)
-    tm_clone_hash = hash_table<tm_clone_hasher>::create_ggc (32);
+    tm_clone_hash = hash_table_ggc<tm_clone_hasher>::create_ggc (32);
 
   h = ggc_alloc<tree_map> ();
   h->hash = htab_hash_pointer (o);
@@ -6280,9 +6280,9 @@ 
 void
 init_varasm_once (void)
 {
-  section_htab = hash_table<section_hasher>::create_ggc (31);
-  object_block_htab = hash_table<object_block_hasher>::create_ggc (31);
-  const_desc_htab = hash_table<tree_descriptor_hasher>::create_ggc (1009);
+  section_htab = hash_table_ggc<section_hasher>::create_ggc (31);
+  object_block_htab = hash_table_ggc<object_block_hasher>::create_ggc (31);
+  const_desc_htab = hash_table_ggc<tree_descriptor_hasher>::create_ggc (1009);
 
   shared_constant_pool = create_constant_pool ();
 
Index: vec.c
===================================================================
--- vec.c	(revision 275695)
+++ vec.c	(working copy)
@@ -31,6 +31,7 @@ 
 #include "coretypes.h"
 #include "hash-table.h"
 #include "selftest.h"
+#include "vec.h"
 #ifdef GENERATOR_FILE
 #include "errors.h"
 #else
Index: vector-builder.h
===================================================================
--- vector-builder.h	(revision 275695)
+++ vector-builder.h	(working copy)
@@ -20,6 +20,8 @@ 
 #ifndef GCC_VECTOR_BUILDER_H
 #define GCC_VECTOR_BUILDER_H
 
+#include "vec.h"
+
 /* This class is a wrapper around auto_vec<T> for building vectors of T.
    It aims to encode each vector as npatterns interleaved patterns,
    where each pattern represents a sequence:
Index: vtable-verify.h
===================================================================
--- vtable-verify.h	(revision 275695)
+++ vtable-verify.h	(working copy)
@@ -22,6 +22,7 @@ 
 #define VTABLE_VERIFY_H
 
 #include "sbitmap.h"
+#include "vec.h"
 
 /* The function decl used to create calls to __VLTVtableVerify.  It must
    be global because it needs to be initialized in the C++ front end, but