This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] add hash_set


On Tue, Jul 29, 2014 at 2:50 PM,  <tsaunders@mozilla.com> wrote:
> From: Trevor Saunders <tsaunders@mozilla.com>
>
> Hi,
>
> this adds a hash_set wrapper around hash_table, and then replaces usage of pointer_set with it.
>
> bootstrapped +regtested on x86_64-unknown-linux-gnu, ok?

Ok.

Thanks,
Richard.

> Trev
>
> ada/
>
>         * gcc-interface/trans.c: Use hash_set instead of pointer_set.
>
> c-family/
>
>         * c-gimplify.c: Use hash_set instead of pointer_set.
>
> c/
>
>         * c-decl.c: Use hash_set instead of pointer_set.
>
> cp/
>
>         * class.c, cp-gimplify.c, cp-tree.h, decl.c, decl2.c, error.c,
>         method.c, name-lookup.c, pt.c, semantics.c, tree.c: Use hash_set
>         instead of pointer_set.
>
> fortran/
>
>         * openmp.c, trans-decl.c: Use hash_set instead of pointer_set.
>
> gcc/
>
>         * hash-set.h: new File.
>         * cfgexpand.c, cfgloop.c, cgraph.c, cgraphbuild.c, cgraphunit.c,
>         cprop.c, cse.c, gimple-walk.c, gimple-walk.h, gimplify.c, godump.c,
>         ipa-devirt.c, ipa-pure-const.c, ipa-visibility.c, ipa.c, lto-cgraph.c,
>         lto-streamer-out.c, stmt.c, tree-cfg.c, tree-core.h, tree-eh.c,
>         tree-inline.c, tree-inline.h, tree-nested.c, tree-pretty-print.c,
>         tree-ssa-loop-niter.c, tree-ssa-phiopt.c, tree-ssa-threadedge.c,
>         tree-ssa-uninit.c, tree.c, tree.h, value-prof.c, varasm.c,
>         varpool.c: Use hash_set instead of pointer_set.
>
> lto/
>
>         * lto-partition.c, lto-partition.h: Use hash_set instead of
>         pointer_set.
> diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
> index f42ac7f..6961838 100644
> --- a/gcc/ada/gcc-interface/trans.c
> +++ b/gcc/ada/gcc-interface/trans.c
> @@ -36,7 +36,7 @@
>  #include "output.h"
>  #include "libfuncs.h"  /* For set_stack_check_libfunc.  */
>  #include "tree-iterator.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "gimple-expr.h"
>  #include "gimplify.h"
>  #include "bitmap.h"
> @@ -3054,7 +3054,7 @@ struct nrv_data
>    bitmap nrv;
>    tree result;
>    Node_Id gnat_ret;
> -  struct pointer_set_t *visited;
> +  hash_set<tree> *visited;
>  };
>
>  /* Return true if T is a Named Return Value.  */
> @@ -3188,7 +3188,7 @@ finalize_nrv_r (tree *tp, int *walk_subtrees, void *data)
>    /* Avoid walking into the same tree more than once.  Unfortunately, we
>       can't just use walk_tree_without_duplicates because it would only
>       call us for the first occurrence of NRVs in the function body.  */
> -  if (pointer_set_insert (dp->visited, *tp))
> +  if (dp->visited->add (*tp))
>      *walk_subtrees = 0;
>
>    return NULL_TREE;
> @@ -3328,7 +3328,7 @@ finalize_nrv_unc_r (tree *tp, int *walk_subtrees, void *data)
>    /* Avoid walking into the same tree more than once.  Unfortunately, we
>       can't just use walk_tree_without_duplicates because it would only
>       call us for the first occurrence of NRVs in the function body.  */
> -  if (pointer_set_insert (dp->visited, *tp))
> +  if (dp->visited->add (*tp))
>      *walk_subtrees = 0;
>
>    return NULL_TREE;
> @@ -3376,13 +3376,13 @@ finalize_nrv (tree fndecl, bitmap nrv, vec<tree, va_gc> *other, Node_Id gnat_ret
>    data.nrv = nrv;
>    data.result = DECL_RESULT (fndecl);
>    data.gnat_ret = gnat_ret;
> -  data.visited = pointer_set_create ();
> +  data.visited = new hash_set<tree>;
>    if (TYPE_RETURN_UNCONSTRAINED_P (TREE_TYPE (fndecl)))
>      func = finalize_nrv_unc_r;
>    else
>      func = finalize_nrv_r;
>    walk_tree (&DECL_SAVED_TREE (fndecl), func, &data, NULL);
> -  pointer_set_destroy (data.visited);
> +  delete data.visited;
>  }
>
>  /* Return true if RET_VAL can be used as a Named Return Value for the
> diff --git a/gcc/c-family/c-gimplify.c b/gcc/c-family/c-gimplify.c
> index 2b5ce5b..4898217 100644
> --- a/gcc/c-family/c-gimplify.c
> +++ b/gcc/c-family/c-gimplify.c
> @@ -74,7 +74,7 @@ along with GCC; see the file COPYING3.  If not see
>  static tree
>  ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data)
>  {
> -  struct pointer_set_t *pset = (struct pointer_set_t *) data;
> +  hash_set<tree> *pset = (hash_set<tree> *) data;
>
>    /* Since walk_tree doesn't call the callback function on the decls
>       in BIND_EXPR_VARS, we have to walk them manually.  */
> @@ -116,10 +116,9 @@ c_genericize (tree fndecl)
>
>    if (flag_sanitize & SANITIZE_BOUNDS)
>      {
> -      struct pointer_set_t *pset = pointer_set_create ();
> -      walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, pset,
> -                pset);
> -      pointer_set_destroy (pset);
> +      hash_set<tree> pset;
> +      walk_tree (&DECL_SAVED_TREE (fndecl), ubsan_walk_array_refs_r, &pset,
> +                &pset);
>      }
>
>    /* Dump the C-specific tree IR.  */
> diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
> index 2a4b439..050ddff 100644
> --- a/gcc/c/c-decl.c
> +++ b/gcc/c/c-decl.c
> @@ -59,7 +59,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "cgraph.h"
>  #include "hash-table.h"
>  #include "langhooks-def.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "plugin.h"
>  #include "c-family/c-ada-spec.h"
>  #include "cilk.h"
> @@ -7221,17 +7221,17 @@ warn_cxx_compat_finish_struct (tree fieldlist)
>    if (!struct_parse_info->typedefs_seen.is_empty ()
>        && fieldlist != NULL_TREE)
>      {
> -      /* Use a pointer_set using the name of the typedef.  We can use
> -        a pointer_set because identifiers are interned.  */
> -      struct pointer_set_t *tset = pointer_set_create ();
> +      /* Use a hash_set<tree> using the name of the typedef.  We can use
> +        a hash_set<tree> because identifiers are interned.  */
> +      hash_set<tree> tset;
>
>        FOR_EACH_VEC_ELT (struct_parse_info->typedefs_seen, ix, x)
> -       pointer_set_insert (tset, DECL_NAME (x));
> +       tset.add (DECL_NAME (x));
>
>        for (x = fieldlist; x != NULL_TREE; x = DECL_CHAIN (x))
>         {
>           if (DECL_NAME (x) != NULL_TREE
> -             && pointer_set_contains (tset, DECL_NAME (x)))
> +             && tset.contains (DECL_NAME (x)))
>             {
>               warning_at (DECL_SOURCE_LOCATION (x), OPT_Wc___compat,
>                           ("using %qD as both field and typedef name is "
> @@ -7241,8 +7241,6 @@ warn_cxx_compat_finish_struct (tree fieldlist)
>                  the typedef name is used.  */
>             }
>         }
> -
> -      pointer_set_destroy (tset);
>      }
>
>    /* For each field which has a binding and which was not defined in
> @@ -8189,7 +8187,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
>    struct c_binding *b;
>    tree parm, decl, last;
>    tree parmids = arg_info->parms;
> -  struct pointer_set_t *seen_args = pointer_set_create ();
> +  hash_set<tree> seen_args;
>
>    if (!in_system_header_at (input_location))
>      warning_at (DECL_SOURCE_LOCATION (fndecl),
> @@ -8220,7 +8218,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
>                       "%qD declared as a non-parameter", decl);
>           /* If the declaration is already marked, we have a duplicate
>              name.  Complain and ignore the duplicate.  */
> -         else if (pointer_set_contains (seen_args, decl))
> +         else if (seen_args.contains (decl))
>             {
>               error_at (DECL_SOURCE_LOCATION (decl),
>                         "multiple parameters named %qD", decl);
> @@ -8269,7 +8267,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
>         }
>
>        TREE_PURPOSE (parm) = decl;
> -      pointer_set_insert (seen_args, decl);
> +      seen_args.add (decl);
>      }
>
>    /* Now examine the parms chain for incomplete declarations
> @@ -8289,7 +8287,7 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
>           TREE_TYPE (parm) = error_mark_node;
>         }
>
> -      if (!pointer_set_contains (seen_args, parm))
> +      if (!seen_args.contains (parm))
>         {
>           error_at (DECL_SOURCE_LOCATION (parm),
>                     "declaration for parameter %qD but no such parameter",
> @@ -8324,8 +8322,6 @@ store_parm_decls_oldstyle (tree fndecl, const struct c_arg_info *arg_info)
>        DECL_CHAIN (last) = 0;
>      }
>
> -  pointer_set_destroy (seen_args);
> -
>    /* If there was a previous prototype,
>       set the DECL_ARG_TYPE of each argument according to
>       the type previously specified, and report any mismatches.  */
> diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
> index 2f0ae71..b20be10 100644
> --- a/gcc/cfgexpand.c
> +++ b/gcc/cfgexpand.c
> @@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "expr.h"
>  #include "langhooks.h"
>  #include "bitmap.h"
> +#include "hash-set.h"
>  #include "pointer-set.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
> @@ -594,7 +595,7 @@ stack_var_cmp (const void *a, const void *b)
>  static void
>  add_partitioned_vars_to_ptset (struct pt_solution *pt,
>                                struct pointer_map_t *decls_to_partitions,
> -                              struct pointer_set_t *visited, bitmap temp)
> +                              hash_set<bitmap> *visited, bitmap temp)
>  {
>    bitmap_iterator bi;
>    unsigned i;
> @@ -604,7 +605,7 @@ add_partitioned_vars_to_ptset (struct pt_solution *pt,
>        || pt->vars == NULL
>        /* The pointed-to vars bitmap is shared, it is enough to
>          visit it once.  */
> -      || pointer_set_insert (visited, pt->vars))
> +      || visited->add (pt->vars))
>      return;
>
>    bitmap_clear (temp);
> @@ -684,7 +685,7 @@ update_alias_info_with_stack_vars (void)
>    if (decls_to_partitions)
>      {
>        unsigned i;
> -      struct pointer_set_t *visited = pointer_set_create ();
> +      hash_set<bitmap> visited;
>        bitmap temp = BITMAP_ALLOC (&stack_var_bitmap_obstack);
>
>        for (i = 1; i < num_ssa_names; i++)
> @@ -696,13 +697,12 @@ update_alias_info_with_stack_vars (void)
>               && POINTER_TYPE_P (TREE_TYPE (name))
>               && ((pi = SSA_NAME_PTR_INFO (name)) != NULL))
>             add_partitioned_vars_to_ptset (&pi->pt, decls_to_partitions,
> -                                          visited, temp);
> +                                          &visited, temp);
>         }
>
>        add_partitioned_vars_to_ptset (&cfun->gimple_df->escaped,
> -                                    decls_to_partitions, visited, temp);
> +                                    decls_to_partitions, &visited, temp);
>
> -      pointer_set_destroy (visited);
>        pointer_map_destroy (decls_to_partitions);
>        BITMAP_FREE (temp);
>      }
> diff --git a/gcc/cfgloop.c b/gcc/cfgloop.c
> index 73f79ef..8f7e265 100644
> --- a/gcc/cfgloop.c
> +++ b/gcc/cfgloop.c
> @@ -28,7 +28,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "diagnostic-core.h"
>  #include "flags.h"
>  #include "tree.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
>  #include "gimple-expr.h"
> @@ -650,11 +650,11 @@ find_subloop_latch_edge (struct loop *loop)
>  /* Callback for make_forwarder_block.  Returns true if the edge E is marked
>     in the set MFB_REIS_SET.  */
>
> -static struct pointer_set_t *mfb_reis_set;
> +static hash_set<edge> *mfb_reis_set;
>  static bool
>  mfb_redirect_edges_in_set (edge e)
>  {
> -  return pointer_set_contains (mfb_reis_set, e);
> +  return mfb_reis_set->contains (e);
>  }
>
>  /* Creates a subloop of LOOP with latch edge LATCH.  */
> @@ -666,15 +666,15 @@ form_subloop (struct loop *loop, edge latch)
>    edge e, new_entry;
>    struct loop *new_loop;
>
> -  mfb_reis_set = pointer_set_create ();
> +  mfb_reis_set = new hash_set<edge>;
>    FOR_EACH_EDGE (e, ei, loop->header->preds)
>      {
>        if (e != latch)
> -       pointer_set_insert (mfb_reis_set, e);
> +       mfb_reis_set->add (e);
>      }
>    new_entry = make_forwarder_block (loop->header, mfb_redirect_edges_in_set,
>                                     NULL);
> -  pointer_set_destroy (mfb_reis_set);
> +  delete mfb_reis_set;
>
>    loop->header = new_entry->src;
>
> @@ -705,12 +705,12 @@ merge_latch_edges (struct loop *loop)
>        if (dump_file)
>         fprintf (dump_file, "Merged latch edges of loop %d\n", loop->num);
>
> -      mfb_reis_set = pointer_set_create ();
> +      mfb_reis_set = new hash_set<edge>;
>        FOR_EACH_VEC_ELT (latches, i, e)
> -       pointer_set_insert (mfb_reis_set, e);
> +       mfb_reis_set->add (e);
>        latch = make_forwarder_block (loop->header, mfb_redirect_edges_in_set,
>                                     NULL);
> -      pointer_set_destroy (mfb_reis_set);
> +      delete mfb_reis_set;
>
>        loop->header = latch->dest;
>        loop->latch = latch->src;
> diff --git a/gcc/cgraph.c b/gcc/cgraph.c
> index a5d0749..7c72399 100644
> --- a/gcc/cgraph.c
> +++ b/gcc/cgraph.c
> @@ -34,6 +34,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree-inline.h"
>  #include "langhooks.h"
>  #include "hashtab.h"
> +#include "hash-set.h"
>  #include "toplev.h"
>  #include "flags.h"
>  #include "debug.h"
> @@ -2871,7 +2872,7 @@ cgraph_node::verify_node (void)
>      {
>        if (this_cfun->cfg)
>         {
> -         pointer_set_t *stmts = pointer_set_create ();
> +         hash_set<gimple> stmts;
>           int i;
>           struct ipa_ref *ref = NULL;
>
> @@ -2881,13 +2882,13 @@ cgraph_node::verify_node (void)
>             {
>               for (gsi = gsi_start_phis (this_block);
>                    !gsi_end_p (gsi); gsi_next (&gsi))
> -               pointer_set_insert (stmts, gsi_stmt (gsi));
> +               stmts.add (gsi_stmt (gsi));
>               for (gsi = gsi_start_bb (this_block);
>                    !gsi_end_p (gsi);
>                    gsi_next (&gsi))
>                 {
>                   gimple stmt = gsi_stmt (gsi);
> -                 pointer_set_insert (stmts, stmt);
> +                 stmts.add (stmt);
>                   if (is_gimple_call (stmt))
>                     {
>                       struct cgraph_edge *e = get_edge (stmt);
> @@ -2931,13 +2932,12 @@ cgraph_node::verify_node (void)
>                 }
>               }
>             for (i = 0; iterate_reference (i, ref); i++)
> -             if (ref->stmt && !pointer_set_contains (stmts, ref->stmt))
> +             if (ref->stmt && !stmts.contains (ref->stmt))
>                 {
>                   error ("reference to dead statement");
>                   cgraph_debug_gimple_stmt (this_cfun, ref->stmt);
>                   error_found = true;
>                 }
> -           pointer_set_destroy (stmts);
>         }
>        else
>         /* No CFG available?!  */
> diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
> index 91811d7..a04958f 100644
> --- a/gcc/cgraphbuild.c
> +++ b/gcc/cgraphbuild.c
> @@ -322,7 +322,6 @@ pass_build_cgraph_edges::execute (function *fun)
>  {
>    basic_block bb;
>    struct cgraph_node *node = cgraph_node::get (current_function_decl);
> -  struct pointer_set_t *visited_nodes = pointer_set_create ();
>    gimple_stmt_iterator gsi;
>    tree decl;
>    unsigned ix;
> @@ -386,7 +385,6 @@ pass_build_cgraph_edges::execute (function *fun)
>        varpool_node::finalize_decl (decl);
>    record_eh_tables (node, fun);
>
> -  pointer_set_destroy (visited_nodes);
>    return 0;
>  }
>
> @@ -405,15 +403,14 @@ make_pass_build_cgraph_edges (gcc::context *ctxt)
>  void
>  record_references_in_initializer (tree decl, bool only_vars)
>  {
> -  struct pointer_set_t *visited_nodes = pointer_set_create ();
>    varpool_node *node = varpool_node::get_create (decl);
> +  hash_set<tree> visited_nodes;
>    struct record_reference_ctx ctx = {false, NULL};
>
>    ctx.varpool_node = node;
>    ctx.only_vars = only_vars;
>    walk_tree (&DECL_INITIAL (decl), record_reference,
> -             &ctx, visited_nodes);
> -  pointer_set_destroy (visited_nodes);
> +             &ctx, &visited_nodes);
>  }
>
>  /* Rebuild cgraph edges for current function node.  This needs to be run after
> diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
> index 3080b9a..220b953 100644
> --- a/gcc/cgraphunit.c
> +++ b/gcc/cgraphunit.c
> @@ -845,7 +845,7 @@ varpool_node::finalize_decl (tree decl)
>     avoid udplicate work.  */
>
>  static void
> -walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
> +walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
>                                struct cgraph_edge *edge)
>  {
>    unsigned int i;
> @@ -855,8 +855,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
>      = possible_polymorphic_call_targets
>         (edge, &final, &cache_token);
>
> -  if (!pointer_set_insert (reachable_call_targets,
> -                          cache_token))
> +  if (!reachable_call_targets->add (cache_token))
>      {
>        if (cgraph_dump_file)
>         dump_possible_polymorphic_call_targets
> @@ -936,7 +935,7 @@ analyze_functions (void)
>    struct cgraph_node *first_handled = first_analyzed;
>    static varpool_node *first_analyzed_var;
>    varpool_node *first_handled_var = first_analyzed_var;
> -  struct pointer_set_t *reachable_call_targets = pointer_set_create ();
> +  hash_set<void *> reachable_call_targets;
>
>    symtab_node *node;
>    symtab_node *next;
> @@ -1035,7 +1034,7 @@ analyze_functions (void)
>                     {
>                       next = edge->next_callee;
>                       if (edge->indirect_info->polymorphic)
> -                       walk_polymorphic_call_targets (reachable_call_targets,
> +                       walk_polymorphic_call_targets (&reachable_call_targets,
>                                                        edge);
>                     }
>                 }
> @@ -1123,7 +1122,6 @@ analyze_functions (void)
>        symtab_node::dump_table (cgraph_dump_file);
>      }
>    bitmap_obstack_release (NULL);
> -  pointer_set_destroy (reachable_call_targets);
>    ggc_collect ();
>    /* Initialize assembler name hash, in particular we want to trigger C++
>       mangling and same body alias creation before we free DECL_ARGUMENTS
> diff --git a/gcc/cp/class.c b/gcc/cp/class.c
> index 0f611e1..d9b34f7 100644
> --- a/gcc/cp/class.c
> +++ b/gcc/cp/class.c
> @@ -5359,15 +5359,15 @@ finalize_literal_type_property (tree t)
>  void
>  explain_non_literal_class (tree t)
>  {
> -  static struct pointer_set_t *diagnosed;
> +  static hash_set<tree> *diagnosed;
>
>    if (!CLASS_TYPE_P (t))
>      return;
>    t = TYPE_MAIN_VARIANT (t);
>
>    if (diagnosed == NULL)
> -    diagnosed = pointer_set_create ();
> -  if (pointer_set_insert (diagnosed, t) != 0)
> +    diagnosed = new hash_set<tree>;
> +  if (diagnosed->add (t))
>      /* Already explained.  */
>      return;
>
> diff --git a/gcc/cp/cp-gimplify.c b/gcc/cp/cp-gimplify.c
> index a35177b..3cfcbc6 100644
> --- a/gcc/cp/cp-gimplify.c
> +++ b/gcc/cp/cp-gimplify.c
> @@ -871,7 +871,7 @@ omp_cxx_notice_variable (struct cp_genericize_omp_taskreg *omp_ctx, tree decl)
>
>  struct cp_genericize_data
>  {
> -  struct pointer_set_t *p_set;
> +  hash_set<tree> *p_set;
>    vec<tree> bind_expr_stack;
>    struct cp_genericize_omp_taskreg *omp_ctx;
>  };
> @@ -884,7 +884,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
>  {
>    tree stmt = *stmt_p;
>    struct cp_genericize_data *wtd = (struct cp_genericize_data *) data;
> -  struct pointer_set_t *p_set = wtd->p_set;
> +  hash_set<tree> *p_set = wtd->p_set;
>
>    /* If in an OpenMP context, note var uses.  */
>    if (__builtin_expect (wtd->omp_ctx != NULL, 0)
> @@ -924,7 +924,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
>      }
>
>    /* Other than invisiref parms, don't walk the same tree twice.  */
> -  if (pointer_set_contains (p_set, stmt))
> +  if (p_set->contains (stmt))
>      {
>        *walk_subtrees = 0;
>        return NULL_TREE;
> @@ -1199,7 +1199,7 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data)
>        return NULL;
>      }
>
> -  pointer_set_insert (p_set, *stmt_p);
> +  p_set->add (*stmt_p);
>
>    return NULL;
>  }
> @@ -1211,11 +1211,11 @@ cp_genericize_tree (tree* t_p)
>  {
>    struct cp_genericize_data wtd;
>
> -  wtd.p_set = pointer_set_create ();
> +  wtd.p_set = new hash_set<tree>;
>    wtd.bind_expr_stack.create (0);
>    wtd.omp_ctx = NULL;
>    cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL);
> -  pointer_set_destroy (wtd.p_set);
> +  delete wtd.p_set;
>    wtd.bind_expr_stack.release ();
>  }
>
> diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
> index 0c0d804..622de9c 100644
> --- a/gcc/cp/cp-tree.h
> +++ b/gcc/cp/cp-tree.h
> @@ -6028,7 +6028,7 @@ extern void verify_stmt_tree                      (tree);
>  extern linkage_kind decl_linkage               (tree);
>  extern duration_kind decl_storage_duration     (tree);
>  extern tree cp_walk_subtrees (tree*, int*, walk_tree_fn,
> -                             void*, struct pointer_set_t*);
> +                             void*, hash_set<tree> *);
>  #define cp_walk_tree(tp,func,data,pset) \
>         walk_tree_1 (tp, func, data, pset, cp_walk_subtrees)
>  #define cp_walk_tree_without_duplicates(tp,func,data) \
> diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
> index aafb917..f70684f 100644
> --- a/gcc/cp/decl.c
> +++ b/gcc/cp/decl.c
> @@ -8198,7 +8198,7 @@ check_static_variable_definition (tree decl, tree type)
>  static tree
>  stabilize_save_expr_r (tree *expr_p, int *walk_subtrees, void *data)
>  {
> -  struct pointer_set_t *pset = (struct pointer_set_t *)data;
> +  hash_set<tree> *pset = (hash_set<tree> *)data;
>    tree expr = *expr_p;
>    if (TREE_CODE (expr) == SAVE_EXPR)
>      {
> @@ -8218,10 +8218,9 @@ stabilize_save_expr_r (tree *expr_p, int *walk_subtrees, void *data)
>  static void
>  stabilize_vla_size (tree size)
>  {
> -  struct pointer_set_t *pset = pointer_set_create ();
> +  hash_set<tree> pset;
>    /* Break out any function calls into temporary variables.  */
> -  cp_walk_tree (&size, stabilize_save_expr_r, pset, pset);
> -  pointer_set_destroy (pset);
> +  cp_walk_tree (&size, stabilize_save_expr_r, &pset, &pset);
>  }
>
>  /* Helper function for compute_array_index_type.  Look for SIZEOF_EXPR
> diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
> index 8fa3145..d79665e 100644
> --- a/gcc/cp/decl2.c
> +++ b/gcc/cp/decl2.c
> @@ -3938,11 +3938,11 @@ generate_ctor_and_dtor_functions_for_priority (splay_tree_node n, void * data)
>     supported, collect and return all the functions for which we should
>     emit a hidden alias.  */
>
> -static struct pointer_set_t *
> +static hash_set<tree> *
>  collect_candidates_for_java_method_aliases (void)
>  {
>    struct cgraph_node *node;
> -  struct pointer_set_t *candidates = NULL;
> +  hash_set<tree> *candidates = NULL;
>
>  #ifndef HAVE_GAS_HIDDEN
>    return candidates;
> @@ -3957,8 +3957,8 @@ collect_candidates_for_java_method_aliases (void)
>           && TARGET_USE_LOCAL_THUNK_ALIAS_P (fndecl))
>         {
>           if (candidates == NULL)
> -           candidates = pointer_set_create ();
> -         pointer_set_insert (candidates, fndecl);
> +           candidates = new hash_set<tree>;
> +         candidates->add (fndecl);
>         }
>      }
>
> @@ -3973,7 +3973,7 @@ collect_candidates_for_java_method_aliases (void)
>     by collect_candidates_for_java_method_aliases.  */
>
>  static void
> -build_java_method_aliases (struct pointer_set_t *candidates)
> +build_java_method_aliases (hash_set<tree> *candidates)
>  {
>    struct cgraph_node *node;
>
> @@ -3986,7 +3986,7 @@ build_java_method_aliases (struct pointer_set_t *candidates)
>        tree fndecl = node->decl;
>
>        if (TREE_ASM_WRITTEN (fndecl)
> -         && pointer_set_contains (candidates, fndecl))
> +         && candidates->contains (fndecl))
>         {
>           /* Mangle the name in a predictable way; we need to reference
>              this from a java compiled object file.  */
> @@ -4296,7 +4296,7 @@ cp_write_global_declarations (void)
>    unsigned ssdf_count = 0;
>    int retries = 0;
>    tree decl;
> -  struct pointer_set_t *candidates;
> +  hash_set<tree> *candidates;
>
>    locus = input_location;
>    at_eof = 1;
> @@ -4713,7 +4713,7 @@ cp_write_global_declarations (void)
>    if (candidates)
>      {
>        build_java_method_aliases (candidates);
> -      pointer_set_destroy (candidates);
> +      delete candidates;
>      }
>
>    finish_repo ();
> diff --git a/gcc/cp/error.c b/gcc/cp/error.c
> index fa3bdc4..c8987ee 100644
> --- a/gcc/cp/error.c
> +++ b/gcc/cp/error.c
> @@ -1325,7 +1325,7 @@ dump_template_decl (cxx_pretty_printer *pp, tree t, int flags)
>
>  struct find_typenames_t
>  {
> -  struct pointer_set_t *p_set;
> +  hash_set<tree> *p_set;
>    vec<tree, va_gc> *typenames;
>  };
>
> @@ -1351,7 +1351,7 @@ find_typenames_r (tree *tp, int *walk_subtrees, void *data)
>        return NULL_TREE;
>      }
>
> -  if (mv && (mv == *tp || !pointer_set_insert (d->p_set, mv)))
> +  if (mv && (mv == *tp || !d->p_set->add (mv)))
>      vec_safe_push (d->typenames, mv);
>
>    /* Search into class template arguments, which cp_walk_subtrees
> @@ -1367,11 +1367,11 @@ static vec<tree, va_gc> *
>  find_typenames (tree t)
>  {
>    struct find_typenames_t ft;
> -  ft.p_set = pointer_set_create ();
> +  ft.p_set = new hash_set<tree>;
>    ft.typenames = NULL;
>    cp_walk_tree (&TREE_TYPE (DECL_TEMPLATE_RESULT (t)),
>                 find_typenames_r, &ft, ft.p_set);
> -  pointer_set_destroy (ft.p_set);
> +  delete ft.p_set;
>    return ft.typenames;
>  }
>
> diff --git a/gcc/cp/method.c b/gcc/cp/method.c
> index e5fa0c1..65c5621 100644
> --- a/gcc/cp/method.c
> +++ b/gcc/cp/method.c
> @@ -1480,7 +1480,7 @@ maybe_explain_implicit_delete (tree decl)
>    if (DECL_DEFAULTED_FN (decl))
>      {
>        /* Not marked GTY; it doesn't need to be GC'd or written to PCH.  */
> -      static struct pointer_set_t *explained;
> +      static hash_set<tree> *explained;
>
>        special_function_kind sfk;
>        location_t loc;
> @@ -1488,8 +1488,8 @@ maybe_explain_implicit_delete (tree decl)
>        tree ctype;
>
>        if (!explained)
> -       explained = pointer_set_create ();
> -      if (pointer_set_insert (explained, decl))
> +       explained = new hash_set<tree>;
> +      if (explained->add (decl))
>         return true;
>
>        sfk = special_function_p (decl);
> diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
> index 75b46ac..6e779a6 100644
> --- a/gcc/cp/name-lookup.c
> +++ b/gcc/cp/name-lookup.c
> @@ -35,7 +35,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "debug.h"
>  #include "c-family/c-pragma.h"
>  #include "params.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>
>  /* The bindings for a particular name in a particular scope.  */
>
> @@ -5152,7 +5152,7 @@ struct arg_lookup
>    vec<tree, va_gc> *namespaces;
>    vec<tree, va_gc> *classes;
>    tree functions;
> -  struct pointer_set_t *fn_set;
> +  hash_set<tree> *fn_set;
>  };
>
>  static bool arg_assoc (struct arg_lookup*, tree);
> @@ -5175,7 +5175,7 @@ add_function (struct arg_lookup *k, tree fn)
>    if (!is_overloaded_fn (fn))
>      /* All names except those of (possibly overloaded) functions and
>         function templates are ignored.  */;
> -  else if (k->fn_set && pointer_set_insert (k->fn_set, fn))
> +  else if (k->fn_set && k->fn_set->add (fn))
>      /* It's already in the list.  */;
>    else if (!k->functions)
>      k->functions = fn;
> @@ -5639,9 +5639,9 @@ lookup_arg_dependent_1 (tree name, tree fns, vec<tree, va_gc> *args)
>        /* We shouldn't be here if lookup found something other than
>          namespace-scope functions.  */
>        gcc_assert (DECL_NAMESPACE_SCOPE_P (OVL_CURRENT (fns)));
> -      k.fn_set = pointer_set_create ();
> +      k.fn_set = new hash_set<tree>;
>        for (ovl = fns; ovl; ovl = OVL_NEXT (ovl))
> -       pointer_set_insert (k.fn_set, OVL_CURRENT (ovl));
> +       k.fn_set->add (OVL_CURRENT (ovl));
>      }
>    else
>      k.fn_set = NULL;
> @@ -5661,8 +5661,7 @@ lookup_arg_dependent_1 (tree name, tree fns, vec<tree, va_gc> *args)
>
>    release_tree_vector (k.classes);
>    release_tree_vector (k.namespaces);
> -  if (k.fn_set)
> -    pointer_set_destroy (k.fn_set);
> +  delete k.fn_set;
>
>    return fns;
>  }
> diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
> index b32cf6c..9b156f5 100644
> --- a/gcc/cp/pt.c
> +++ b/gcc/cp/pt.c
> @@ -147,7 +147,7 @@ static tree convert_nontype_argument (tree, tree, tsubst_flags_t);
>  static tree convert_template_argument (tree, tree, tree,
>                                        tsubst_flags_t, int, tree);
>  static int for_each_template_parm (tree, tree_fn_t, void*,
> -                                  struct pointer_set_t*, bool);
> +                                  hash_set<tree> *, bool);
>  static tree expand_template_argument_pack (tree);
>  static tree build_template_parm_index (int, int, int, tree, tree);
>  static bool inline_needs_template_parms (tree, bool);
> @@ -3080,7 +3080,7 @@ struct find_parameter_pack_data
>    tree* parameter_packs;
>
>    /* Set of AST nodes that have been visited by the traversal.  */
> -  struct pointer_set_t *visited;
> +  hash_set<tree> *visited;
>  };
>
>  /* Identifies all of the argument packs that occur in a template
> @@ -3243,9 +3243,9 @@ uses_parameter_packs (tree t)
>    tree parameter_packs = NULL_TREE;
>    struct find_parameter_pack_data ppd;
>    ppd.parameter_packs = &parameter_packs;
> -  ppd.visited = pointer_set_create ();
> +  ppd.visited = new hash_set<tree>;
>    cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
> -  pointer_set_destroy (ppd.visited);
> +  delete ppd.visited;
>    return parameter_packs != NULL_TREE;
>  }
>
> @@ -3292,7 +3292,7 @@ make_pack_expansion (tree arg)
>
>        /* Determine which parameter packs will be used by the base
>           class expansion.  */
> -      ppd.visited = pointer_set_create ();
> +      ppd.visited = new hash_set<tree>;
>        ppd.parameter_packs = &parameter_packs;
>        cp_walk_tree (&TREE_PURPOSE (arg), &find_parameter_packs_r,
>                      &ppd, ppd.visited);
> @@ -3300,7 +3300,7 @@ make_pack_expansion (tree arg)
>        if (parameter_packs == NULL_TREE)
>          {
>            error ("base initializer expansion %<%T%> contains no parameter packs", arg);
> -          pointer_set_destroy (ppd.visited);
> +          delete ppd.visited;
>            return error_mark_node;
>          }
>
> @@ -3317,7 +3317,7 @@ make_pack_expansion (tree arg)
>              }
>          }
>
> -      pointer_set_destroy (ppd.visited);
> +      delete ppd.visited;
>
>        /* Create the pack expansion type for the base type.  */
>        purpose = cxx_make_type (TYPE_PACK_EXPANSION);
> @@ -3352,9 +3352,9 @@ make_pack_expansion (tree arg)
>
>    /* Determine which parameter packs will be expanded.  */
>    ppd.parameter_packs = &parameter_packs;
> -  ppd.visited = pointer_set_create ();
> +  ppd.visited = new hash_set<tree>;
>    cp_walk_tree (&arg, &find_parameter_packs_r, &ppd, ppd.visited);
> -  pointer_set_destroy (ppd.visited);
> +  delete ppd.visited;
>
>    /* Make sure we found some parameter packs.  */
>    if (parameter_packs == NULL_TREE)
> @@ -3399,9 +3399,9 @@ check_for_bare_parameter_packs (tree t)
>      t = TREE_TYPE (t);
>
>    ppd.parameter_packs = &parameter_packs;
> -  ppd.visited = pointer_set_create ();
> +  ppd.visited = new hash_set<tree>;
>    cp_walk_tree (&t, &find_parameter_packs_r, &ppd, ppd.visited);
> -  pointer_set_destroy (ppd.visited);
> +  delete ppd.visited;
>
>    if (parameter_packs)
>      {
> @@ -4381,11 +4381,11 @@ fixed_parameter_pack_p (tree parm)
>    tree parameter_packs = NULL_TREE;
>    struct find_parameter_pack_data ppd;
>    ppd.parameter_packs = &parameter_packs;
> -  ppd.visited = pointer_set_create ();
> +  ppd.visited = new hash_set<tree>;
>
>    fixed_parameter_pack_p_1 (parm, &ppd);
>
> -  pointer_set_destroy (ppd.visited);
> +  delete ppd.visited;
>    return parameter_packs;
>  }
>
> @@ -7907,7 +7907,7 @@ struct pair_fn_data
>    /* True when we should also visit template parameters that occur in
>       non-deduced contexts.  */
>    bool include_nondeduced_p;
> -  struct pointer_set_t *visited;
> +  hash_set<tree> *visited;
>  };
>
>  /* Called from for_each_template_parm via walk_tree.  */
> @@ -8107,7 +8107,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d)
>
>  static int
>  for_each_template_parm (tree t, tree_fn_t fn, void* data,
> -                       struct pointer_set_t *visited,
> +                       hash_set<tree> *visited,
>                         bool include_nondeduced_p)
>  {
>    struct pair_fn_data pfd;
> @@ -8126,7 +8126,7 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
>    if (visited)
>      pfd.visited = visited;
>    else
> -    pfd.visited = pointer_set_create ();
> +    pfd.visited = new hash_set<tree>;
>    result = cp_walk_tree (&t,
>                          for_each_template_parm_r,
>                          &pfd,
> @@ -8135,7 +8135,7 @@ for_each_template_parm (tree t, tree_fn_t fn, void* data,
>    /* Clean up.  */
>    if (!visited)
>      {
> -      pointer_set_destroy (pfd.visited);
> +      delete pfd.visited;
>        pfd.visited = 0;
>      }
>
> diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
> index c87764d..735284e 100644
> --- a/gcc/cp/semantics.c
> +++ b/gcc/cp/semantics.c
> @@ -8031,7 +8031,7 @@ register_constexpr_fundef (tree fun, tree body)
>  void
>  explain_invalid_constexpr_fn (tree fun)
>  {
> -  static struct pointer_set_t *diagnosed;
> +  static hash_set<tree> *diagnosed;
>    tree body;
>    location_t save_loc;
>    /* Only diagnose defaulted functions or instantiations.  */
> @@ -8039,8 +8039,8 @@ explain_invalid_constexpr_fn (tree fun)
>        && !is_instantiation_of_constexpr (fun))
>      return;
>    if (diagnosed == NULL)
> -    diagnosed = pointer_set_create ();
> -  if (pointer_set_insert (diagnosed, fun) != 0)
> +    diagnosed = new hash_set<tree>;
> +  if (diagnosed->add (fun))
>      /* Already explained.  */
>      return;
>
> diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
> index f6c5693..697a02b 100644
> --- a/gcc/cp/tree.c
> +++ b/gcc/cp/tree.c
> @@ -3485,7 +3485,7 @@ cxx_type_hash_eq (const_tree typea, const_tree typeb)
>
>  tree
>  cp_walk_subtrees (tree *tp, int *walk_subtrees_p, walk_tree_fn func,
> -                 void *data, struct pointer_set_t *pset)
> +                 void *data, hash_set<tree> *pset)
>  {
>    enum tree_code code = TREE_CODE (*tp);
>    tree result;
> diff --git a/gcc/cprop.c b/gcc/cprop.c
> index 6291c91..4234afa 100644
> --- a/gcc/cprop.c
> +++ b/gcc/cprop.c
> @@ -167,7 +167,7 @@ reg_available_p (const_rtx x, const_rtx insn ATTRIBUTE_UNUSED)
>     ??? May need to make things more elaborate.  Later, as necessary.  */
>
>  static unsigned int
> -hash_set (int regno, int hash_table_size)
> +hash_mod (int regno, int hash_table_size)
>  {
>    return (unsigned) regno % hash_table_size;
>  }
> @@ -187,7 +187,7 @@ insert_set_in_table (rtx dest, rtx src, rtx insn, struct hash_table_d *table,
>    struct expr *cur_expr, *last_expr = NULL;
>    struct occr *cur_occr;
>
> -  hash = hash_set (REGNO (dest), table->size);
> +  hash = hash_mod (REGNO (dest), table->size);
>
>    for (cur_expr = table->table[hash]; cur_expr;
>         cur_expr = cur_expr->next_same_hash)
> @@ -483,7 +483,7 @@ compute_hash_table (struct hash_table_d *table)
>  static struct expr *
>  lookup_set (unsigned int regno, struct hash_table_d *table)
>  {
> -  unsigned int hash = hash_set (regno, table->size);
> +  unsigned int hash = hash_mod (regno, table->size);
>    struct expr *expr;
>
>    expr = table->table[hash];
> diff --git a/gcc/cse.c b/gcc/cse.c
> index 34f9364..dd9a076 100644
> --- a/gcc/cse.c
> +++ b/gcc/cse.c
> @@ -41,7 +41,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree-pass.h"
>  #include "df.h"
>  #include "dbgcnt.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>
>  /* The basic idea of common subexpression elimination is to go
>     through the code, keeping a record of expressions that would
> @@ -2906,7 +2906,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
>                       enum machine_mode *pmode1, enum machine_mode *pmode2)
>  {
>    rtx arg1, arg2;
> -  struct pointer_set_t *visited = NULL;
> +  hash_set<rtx> *visited = NULL;
>    /* Set nonzero when we find something of interest.  */
>    rtx x = NULL;
>
> @@ -2923,8 +2923,8 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
>        if (x)
>         {
>           if (!visited)
> -           visited = pointer_set_create ();
> -         pointer_set_insert (visited, x);
> +           visited = new hash_set<rtx>;
> +         visited->add (x);
>           x = 0;
>         }
>
> @@ -3005,7 +3005,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
>             continue;
>
>           /* If it's a comparison we've used before, skip it.  */
> -         if (visited && pointer_set_contains (visited, p->exp))
> +         if (visited && visited->contains (p->exp))
>             continue;
>
>           if (GET_CODE (p->exp) == COMPARE
> @@ -3087,7 +3087,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
>    *parg1 = fold_rtx (arg1, 0), *parg2 = fold_rtx (arg2, 0);
>
>    if (visited)
> -    pointer_set_destroy (visited);
> +    delete visited;
>    return code;
>  }
>
> diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
> index 68ba70f..410efb1 100644
> --- a/gcc/fortran/openmp.c
> +++ b/gcc/fortran/openmp.c
> @@ -26,7 +26,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "arith.h"
>  #include "match.h"
>  #include "parse.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>
>  /* Match an end of OpenMP directive.  End of OpenMP directive is optional
>     whitespace, followed by '\n' or comment '!'.  */
> @@ -3013,8 +3013,8 @@ resolve_omp_atomic (gfc_code *code)
>  struct omp_context
>  {
>    gfc_code *code;
> -  struct pointer_set_t *sharing_clauses;
> -  struct pointer_set_t *private_iterators;
> +  hash_set<gfc_symbol *> *sharing_clauses;
> +  hash_set<gfc_symbol *> *private_iterators;
>    struct omp_context *previous;
>  } *omp_current_ctx;
>  static gfc_code *omp_current_do_code;
> @@ -3057,8 +3057,8 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
>    int list;
>
>    ctx.code = code;
> -  ctx.sharing_clauses = pointer_set_create ();
> -  ctx.private_iterators = pointer_set_create ();
> +  ctx.sharing_clauses = new hash_set<gfc_symbol *>;
> +  ctx.private_iterators = new hash_set<gfc_symbol *>;
>    ctx.previous = omp_current_ctx;
>    omp_current_ctx = &ctx;
>
> @@ -3072,7 +3072,7 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
>        case OMP_LIST_REDUCTION:
>        case OMP_LIST_LINEAR:
>         for (n = omp_clauses->lists[list]; n; n = n->next)
> -         pointer_set_insert (ctx.sharing_clauses, n->sym);
> +         ctx.sharing_clauses->add (n->sym);
>         break;
>        default:
>         break;
> @@ -3097,8 +3097,8 @@ gfc_resolve_omp_parallel_blocks (gfc_code *code, gfc_namespace *ns)
>      }
>
>    omp_current_ctx = ctx.previous;
> -  pointer_set_destroy (ctx.sharing_clauses);
> -  pointer_set_destroy (ctx.private_iterators);
> +  delete ctx.sharing_clauses;
> +  delete ctx.private_iterators;
>  }
>
>
> @@ -3154,10 +3154,10 @@ gfc_resolve_do_iterator (gfc_code *code, gfc_symbol *sym)
>    if (omp_current_ctx == NULL)
>      return;
>
> -  if (pointer_set_contains (omp_current_ctx->sharing_clauses, sym))
> +  if (omp_current_ctx->sharing_clauses->contains (sym))
>      return;
>
> -  if (! pointer_set_insert (omp_current_ctx->private_iterators, sym))
> +  if (! omp_current_ctx->private_iterators->add (sym))
>      {
>        gfc_omp_clauses *omp_clauses = omp_current_ctx->code->ext.omp_clauses;
>        gfc_omp_namelist *p;
> diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
> index 8b56151..babe48f 100644
> --- a/gcc/fortran/trans-decl.c
> +++ b/gcc/fortran/trans-decl.c
> @@ -40,7 +40,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "cgraph.h"
>  #include "debug.h"
>  #include "gfortran.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "constructor.h"
>  #include "trans.h"
>  #include "trans-types.h"
> @@ -63,7 +63,7 @@ static GTY(()) tree parent_fake_result_decl;
>  static GTY(()) tree saved_function_decls;
>  static GTY(()) tree saved_parent_function_decls;
>
> -static struct pointer_set_t *nonlocal_dummy_decl_pset;
> +static hash_set<tree> *nonlocal_dummy_decl_pset;
>  static GTY(()) tree nonlocal_dummy_decls;
>
>  /* Holds the variable DECLs that are locals.  */
> @@ -1094,9 +1094,9 @@ gfc_nonlocal_dummy_array_decl (gfc_symbol *sym)
>    tree decl, dummy;
>
>    if (! nonlocal_dummy_decl_pset)
> -    nonlocal_dummy_decl_pset = pointer_set_create ();
> +    nonlocal_dummy_decl_pset = new hash_set<tree>;
>
> -  if (pointer_set_insert (nonlocal_dummy_decl_pset, sym->backend_decl))
> +  if (nonlocal_dummy_decl_pset->add (sym->backend_decl))
>      return;
>
>    dummy = GFC_DECL_SAVED_DESCRIPTOR (sym->backend_decl);
> @@ -5861,7 +5861,7 @@ gfc_generate_function_code (gfc_namespace * ns)
>      {
>        BLOCK_VARS (DECL_INITIAL (fndecl))
>         = chainon (BLOCK_VARS (DECL_INITIAL (fndecl)), nonlocal_dummy_decls);
> -      pointer_set_destroy (nonlocal_dummy_decl_pset);
> +      delete nonlocal_dummy_decl_pset;
>        nonlocal_dummy_decls = NULL;
>        nonlocal_dummy_decl_pset = NULL;
>      }
> diff --git a/gcc/gimple-walk.c b/gcc/gimple-walk.c
> index b6f0495..f4f6757 100644
> --- a/gcc/gimple-walk.c
> +++ b/gcc/gimple-walk.c
> @@ -180,7 +180,7 @@ tree
>  walk_gimple_op (gimple stmt, walk_tree_fn callback_op,
>                 struct walk_stmt_info *wi)
>  {
> -  struct pointer_set_t *pset = (wi) ? wi->pset : NULL;
> +  hash_set<tree> *pset = (wi) ? wi->pset : NULL;
>    unsigned i;
>    tree ret = NULL_TREE;
>
> diff --git a/gcc/gimple-walk.h b/gcc/gimple-walk.h
> index 555eb18..5b75fdc 100644
> --- a/gcc/gimple-walk.h
> +++ b/gcc/gimple-walk.h
> @@ -36,7 +36,7 @@ struct walk_stmt_info
>    /* Pointer map used to mark visited tree nodes when calling
>       walk_tree on each operand.  If set to NULL, duplicate tree nodes
>       will be visited more than once.  */
> -  struct pointer_set_t *pset;
> +  hash_set<tree> *pset;
>
>    /* Operand returned by the callbacks.  This is set when calling
>       walk_gimple_seq.  If the walk_stmt_fn or walk_tree_fn callback
> diff --git a/gcc/gimplify.c b/gcc/gimplify.c
> index 4ab36d0..c0ae7cc 100644
> --- a/gcc/gimplify.c
> +++ b/gcc/gimplify.c
> @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "coretypes.h"
>  #include "tree.h"
>  #include "expr.h"
> +#include "hash-set.h"
>  #include "pointer-set.h"
>  #include "hash-table.h"
>  #include "basic-block.h"
> @@ -134,7 +135,7 @@ struct gimplify_omp_ctx
>  {
>    struct gimplify_omp_ctx *outer_context;
>    splay_tree variables;
> -  struct pointer_set_t *privatized_types;
> +  hash_set<tree> *privatized_types;
>    location_t location;
>    enum omp_clause_default_kind default_kind;
>    enum omp_region_type region_type;
> @@ -352,7 +353,7 @@ new_omp_context (enum omp_region_type region_type)
>    c = XCNEW (struct gimplify_omp_ctx);
>    c->outer_context = gimplify_omp_ctxp;
>    c->variables = splay_tree_new (splay_tree_compare_decl_uid, 0, 0);
> -  c->privatized_types = pointer_set_create ();
> +  c->privatized_types = new hash_set<tree>;
>    c->location = input_location;
>    c->region_type = region_type;
>    if ((region_type & ORT_TASK) == 0)
> @@ -369,7 +370,7 @@ static void
>  delete_omp_context (struct gimplify_omp_ctx *c)
>  {
>    splay_tree_delete (c->variables);
> -  pointer_set_destroy (c->privatized_types);
> +  delete c->privatized_types;
>    XDELETE (c);
>  }
>
> @@ -744,7 +745,7 @@ mostly_copy_tree_r (tree *tp, int *walk_subtrees, void *data)
>       copy their subtrees if we can make sure to do it only once.  */
>    if (code == SAVE_EXPR || code == TARGET_EXPR || code == BIND_EXPR)
>      {
> -      if (data && !pointer_set_insert ((struct pointer_set_t *)data, t))
> +      if (data && !((hash_set<tree> *)data)->add (t))
>         ;
>        else
>         *walk_subtrees = 0;
> @@ -829,15 +830,14 @@ unshare_body (tree fndecl)
>    struct cgraph_node *cgn = cgraph_node::get (fndecl);
>    /* If the language requires deep unsharing, we need a pointer set to make
>       sure we don't repeatedly unshare subtrees of unshareable nodes.  */
> -  struct pointer_set_t *visited
> -    = lang_hooks.deep_unsharing ? pointer_set_create () : NULL;
> +  hash_set<tree> *visited
> +    = lang_hooks.deep_unsharing ? new hash_set<tree> : NULL;
>
>    copy_if_shared (&DECL_SAVED_TREE (fndecl), visited);
>    copy_if_shared (&DECL_SIZE (DECL_RESULT (fndecl)), visited);
>    copy_if_shared (&DECL_SIZE_UNIT (DECL_RESULT (fndecl)), visited);
>
> -  if (visited)
> -    pointer_set_destroy (visited);
> +  delete visited;
>
>    if (cgn)
>      for (cgn = cgn->nested; cgn; cgn = cgn->next_nested)
> @@ -1733,7 +1733,7 @@ gimplify_conversion (tree *expr_p)
>  }
>
>  /* Nonlocal VLAs seen in the current function.  */
> -static struct pointer_set_t *nonlocal_vlas;
> +static hash_set<tree> *nonlocal_vlas;
>
>  /* The VAR_DECLs created for nonlocal VLAs for debug info purposes.  */
>  static tree nonlocal_vla_vars;
> @@ -1784,7 +1784,7 @@ gimplify_var_or_parm_decl (tree *expr_p)
>                  && (ctx->region_type == ORT_WORKSHARE
>                      || ctx->region_type == ORT_SIMD))
>             ctx = ctx->outer_context;
> -         if (!ctx && !pointer_set_insert (nonlocal_vlas, decl))
> +         if (!ctx && !nonlocal_vlas->add (decl))
>             {
>               tree copy = copy_node (decl);
>
> @@ -5463,7 +5463,7 @@ omp_firstprivatize_type_sizes (struct gimplify_omp_ctx *ctx, tree type)
>      return;
>    type = TYPE_MAIN_VARIANT (type);
>
> -  if (pointer_set_insert (ctx->privatized_types, type))
> +  if (ctx->privatized_types->add (type))
>      return;
>
>    switch (TREE_CODE (type))
> @@ -8766,7 +8766,7 @@ gimplify_body (tree fndecl, bool do_parms)
>
>    cgn = cgraph_node::get (fndecl);
>    if (cgn && cgn->origin)
> -    nonlocal_vlas = pointer_set_create ();
> +    nonlocal_vlas = new hash_set<tree>;
>
>    /* Make sure input_location isn't set to something weird.  */
>    input_location = DECL_SOURCE_LOCATION (fndecl);
> @@ -8830,7 +8830,7 @@ gimplify_body (tree fndecl, bool do_parms)
>                          nonlocal_vla_vars);
>           nonlocal_vla_vars = NULL_TREE;
>         }
> -      pointer_set_destroy (nonlocal_vlas);
> +      delete nonlocal_vlas;
>        nonlocal_vlas = NULL;
>      }
>
> diff --git a/gcc/godump.c b/gcc/godump.c
> index 2afd7f1..7566f4d 100644
> --- a/gcc/godump.c
> +++ b/gcc/godump.c
> @@ -33,7 +33,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "diagnostic-core.h"
>  #include "tree.h"
>  #include "ggc.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "obstack.h"
>  #include "debug.h"
>  #include "wide-int-print.h"
> @@ -525,11 +525,11 @@ go_type_decl (tree decl, int local)
>  struct godump_container
>  {
>    /* DECLs that we have already seen.  */
> -  struct pointer_set_t *decls_seen;
> +  hash_set<tree> decls_seen;
>
>    /* Types which may potentially have to be defined as dummy
>       types.  */
> -  struct pointer_set_t *pot_dummy_types;
> +  hash_set<const char *> pot_dummy_types;
>
>    /* Go keywords.  */
>    htab_t keyword_hash;
> @@ -569,8 +569,8 @@ go_format_type (struct godump_container *container, tree type,
>    ob = &container->type_obstack;
>
>    if (TYPE_NAME (type) != NULL_TREE
> -      && (pointer_set_contains (container->decls_seen, type)
> -         || pointer_set_contains (container->decls_seen, TYPE_NAME (type)))
> +      && (container->decls_seen.contains (type)
> +         || container->decls_seen.contains (TYPE_NAME (type)))
>        && (AGGREGATE_TYPE_P (type)
>           || POINTER_TYPE_P (type)
>           || TREE_CODE (type) == FUNCTION_TYPE))
> @@ -590,7 +590,7 @@ go_format_type (struct godump_container *container, tree type,
>        return ret;
>      }
>
> -  pointer_set_insert (container->decls_seen, type);
> +  container->decls_seen.add (type);
>
>    switch (TREE_CODE (type))
>      {
> @@ -697,8 +697,7 @@ go_format_type (struct godump_container *container, tree type,
>              definition.  So this struct or union is a potential dummy
>              type.  */
>           if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (type)))
> -           pointer_set_insert (container->pot_dummy_types,
> -                               IDENTIFIER_POINTER (name));
> +           container->pot_dummy_types.add (IDENTIFIER_POINTER (name));
>
>           return ret;
>          }
> @@ -948,10 +947,10 @@ go_output_typedef (struct godump_container *container, tree decl)
>       separately.  */
>    if (TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE
>        && TYPE_SIZE (TREE_TYPE (decl)) != 0
> -      && !pointer_set_contains (container->decls_seen, TREE_TYPE (decl))
> +      && !container->decls_seen.contains (TREE_TYPE (decl))
>        && (TYPE_CANONICAL (TREE_TYPE (decl)) == NULL_TREE
> -         || !pointer_set_contains (container->decls_seen,
> -                                   TYPE_CANONICAL (TREE_TYPE (decl)))))
> +         || !container->decls_seen.contains
> +                                   (TYPE_CANONICAL (TREE_TYPE (decl)))))
>      {
>        tree element;
>
> @@ -988,10 +987,9 @@ go_output_typedef (struct godump_container *container, tree decl)
>           mhval->value = xstrdup (buf);
>           *slot = mhval;
>         }
> -      pointer_set_insert (container->decls_seen, TREE_TYPE (decl));
> +      container->decls_seen.add (TREE_TYPE (decl));
>        if (TYPE_CANONICAL (TREE_TYPE (decl)) != NULL_TREE)
> -       pointer_set_insert (container->decls_seen,
> -                           TYPE_CANONICAL (TREE_TYPE (decl)));
> +       container->decls_seen.add (TYPE_CANONICAL (TREE_TYPE (decl)));
>      }
>
>    if (DECL_NAME (decl) != NULL_TREE)
> @@ -1027,7 +1025,7 @@ go_output_typedef (struct godump_container *container, tree decl)
>                      size);
>         }
>
> -      pointer_set_insert (container->decls_seen, decl);
> +      container->decls_seen.add (decl);
>      }
>    else if (RECORD_OR_UNION_TYPE_P (TREE_TYPE (decl)))
>      {
> @@ -1072,11 +1070,11 @@ go_output_var (struct godump_container *container, tree decl)
>  {
>    bool is_valid;
>
> -  if (pointer_set_contains (container->decls_seen, decl)
> -      || pointer_set_contains (container->decls_seen, DECL_NAME (decl)))
> +  if (container->decls_seen.contains (decl)
> +      || container->decls_seen.contains (DECL_NAME (decl)))
>      return;
> -  pointer_set_insert (container->decls_seen, decl);
> -  pointer_set_insert (container->decls_seen, DECL_NAME (decl));
> +  container->decls_seen.add (decl);
> +  container->decls_seen.add (DECL_NAME (decl));
>
>    is_valid = go_format_type (container, TREE_TYPE (decl), true, false);
>    if (is_valid
> @@ -1103,11 +1101,10 @@ go_output_var (struct godump_container *container, tree decl)
>      {
>        tree type_name = TYPE_NAME (TREE_TYPE (decl));
>        if (TREE_CODE (type_name) == IDENTIFIER_NODE)
> -       pointer_set_insert (container->pot_dummy_types,
> -                           IDENTIFIER_POINTER (type_name));
> +       container->pot_dummy_types.add (IDENTIFIER_POINTER (type_name));
>        else if (TREE_CODE (type_name) == TYPE_DECL)
> -       pointer_set_insert (container->pot_dummy_types,
> -                           IDENTIFIER_POINTER (DECL_NAME (type_name)));
> +       container->pot_dummy_types.add
> +                           (IDENTIFIER_POINTER (DECL_NAME (type_name)));
>      }
>  }
>
> @@ -1147,10 +1144,10 @@ keyword_hash_init (struct godump_container *container)
>
>  /* Traversing the pot_dummy_types and seeing which types are present
>     in the global types hash table and creating dummy definitions if
> -   not found.  This function is invoked by pointer_set_traverse.  */
> +   not found.  This function is invoked by hash_set::traverse.  */
>
> -static bool
> -find_dummy_types (const void *ptr, void *adata)
> +bool
> +find_dummy_types (const char *const &ptr, godump_container *adata)
>  {
>    struct godump_container *data = (struct godump_container *) adata;
>    const char *type = (const char *) ptr;
> @@ -1175,8 +1172,6 @@ go_finish (const char *filename)
>
>    real_debug_hooks->finish (filename);
>
> -  container.decls_seen = pointer_set_create ();
> -  container.pot_dummy_types = pointer_set_create ();
>    container.type_hash = htab_create (100, htab_hash_string,
>                                       string_hash_eq, NULL);
>    container.invalid_hash = htab_create (10, htab_hash_string,
> @@ -1211,11 +1206,9 @@ go_finish (const char *filename)
>    htab_traverse_noresize (macro_hash, go_print_macro, NULL);
>
>    /* To emit dummy definitions.  */
> -  pointer_set_traverse (container.pot_dummy_types, find_dummy_types,
> -                        (void *) &container);
> +  container.pot_dummy_types.traverse<godump_container *, find_dummy_types>
> +                        (&container);
>
> -  pointer_set_destroy (container.decls_seen);
> -  pointer_set_destroy (container.pot_dummy_types);
>    htab_delete (container.type_hash);
>    htab_delete (container.invalid_hash);
>    htab_delete (container.keyword_hash);
> diff --git a/gcc/hash-set.h b/gcc/hash-set.h
> new file mode 100644
> index 0000000..47bae9e
> --- /dev/null
> +++ b/gcc/hash-set.h
> @@ -0,0 +1,173 @@
> +/* A type-safe hash set.
> +   Copyright (C) 2014 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_set_h
> +#define hash_set_h
> +
> +#include "hash-table.h"
> +
> +/* implement default behavior for traits when types allow it.  */
> +
> +struct default_hashset_traits
> +{
> +  /* Hashes the passed in key.  */
> +
> +  template<typename T>
> +  static hashval_t
> +  hash (T *p)
> +    {
> +      return uintptr_t(p) >> 3;
> +    }
> +
> +  template<typename T> static hashval_t hash(const T &v) { return v; }
> +
> +  /* Return true if the two keys passed as arguments are equal.  */
> +
> +  template<typename T>
> +  static bool
> +  equal (const T &a, const T &b)
> +    {
> +      return a == b;
> +    }
> +
> +  /* Called to dispose of the key before marking the entry as deleted.  */
> +
> +  template<typename T> static void remove (T &v) { v.~T (); }
> +
> +  /* Mark the passed in entry as being deleted.  */
> +
> +  template<typename T>
> +  static void
> +  mark_deleted (T *&e)
> +    {
> +      e = reinterpret_cast<void *> (1);
> +    }
> +
> +  /* Mark the passed in entry as being empty.  */
> +
> +  template<typename T>
> +  static void
> +  mark_empty (T *&e)
> +    {
> +      e = NULL;
> +    }
> +
> +  /* Return true if the passed in entry is marked as deleted.  */
> +
> +  template<typename T>
> +  static bool
> +  is_deleted (T *e)
> +    {
> +      return e == reinterpret_cast<void *> (1);
> +    }
> +
> +  /* Return true if the passed in entry is marked as empty.  */
> +
> +  template<typename T> static bool is_empty (T *e) { return e == NULL; }
> +};
> +
> +template<typename Key, typename Traits = default_hashset_traits>
> +class hash_set
> +{
> +  struct hash_entry
> +  {
> +    Key m_key;
> +
> +    typedef hash_entry value_type;
> +    typedef Key compare_type;
> +    typedef int store_values_directly;
> +
> +    static hashval_t hash (const hash_entry &e)
> +      {
> +               return Traits::hash (e.m_key);
> +      }
> +
> +    static bool equal (const hash_entry &a, const Key &b)
> +               {
> +         return Traits::equal (a.m_key, b);
> +               }
> +
> +    static void remove (hash_entry &e) { Traits::remove (e.m_key); }
> +
> +    static void
> +    mark_deleted (hash_entry &e)
> +      {
> +               Traits::mark_deleted (e.m_key);
> +      }
> +
> +    static bool is_deleted (const hash_entry &e)
> +      {
> +               return Traits::is_deleted (e.m_key);
> +      }
> +
> +    static void
> +    mark_empty (hash_entry &e)
> +      {
> +       Traits::mark_empty (e.m_key);
> +      }
> +
> +    static bool
> +    is_empty (const hash_entry &e)
> +      {
> +       return Traits::is_empty (e.m_key);
> +      }
> +  };
> +
> +public:
> +  explicit hash_set (size_t n = 13) : m_table (n) {}
> +
> +  /* If key k isn't already in the map add it to the map, and
> +     return false.  Otherwise return true.  */
> +
> +  bool add (const Key &k)
> +    {
> +      hash_entry *e = m_table.find_slot_with_hash (k, Traits::hash (k),
> +                                                  INSERT);
> +      bool existed = !hash_entry::is_empty (*e);
> +      if (!existed)
> +       e->m_key = k;
> +
> +      return existed;
> +    }
> +
> +  /* if the passed in key is in the map return its value otherwise NULL.  */
> +
> +  bool contains (const Key &k)
> +    {
> +      hash_entry &e = m_table.find_with_hash (k, Traits::hash (k));
> +      return !Traits::is_empty (e.m_key);
> +    }
> +
> +  /* Call the call back on each pair of key and value with the passed in
> +     arg.  */
> +
> +  template<typename Arg, bool (*f)(const Key &, Arg)>
> +  void traverse (Arg a) const
> +    {
> +      for (typename hash_table<hash_entry>::iterator iter = m_table.begin ();
> +          iter != m_table.end (); ++iter)
> +       f ((*iter).m_key, a);
> +    }
> +
> +private:
> +  hash_table<hash_entry> m_table;
> +};
> +
> +#endif
> diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
> index 127d58d..70a70a7 100644
> --- a/gcc/ipa-devirt.c
> +++ b/gcc/ipa-devirt.c
> @@ -115,7 +115,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "cgraph.h"
>  #include "expr.h"
>  #include "tree-pass.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "target.h"
>  #include "hash-table.h"
>  #include "inchash.h"
> @@ -134,7 +134,8 @@ along with GCC; see the file COPYING3.  If not see
>  #include "stor-layout.h"
>  #include "intl.h"
>
> -static bool odr_types_equivalent_p (tree, tree, bool, bool *, pointer_set_t *);
> +static bool odr_types_equivalent_p (tree, tree, bool, bool *,
> +                                   hash_set<tree> *);
>
>  static bool odr_violation_reported = false;
>
> @@ -144,7 +145,7 @@ const ipa_polymorphic_call_context ipa_dummy_polymorphic_call_context
>     = {0, NULL, false, true};
>
>  /* Pointer set of all call targets appearing in the cache.  */
> -static pointer_set_t *cached_polymorphic_call_targets;
> +static hash_set<cgraph_node *> *cached_polymorphic_call_targets;
>
>  /* The node of type inheritance graph.  For each type unique in
>     One Defintion Rule (ODR) sense, we produce one node linking all
> @@ -163,7 +164,7 @@ struct GTY(()) odr_type_d
>    /* All equivalent types, if more than one.  */
>    vec<tree, va_gc> *types;
>    /* Set of all equivalent types, if NON-NULL.  */
> -  pointer_set_t * GTY((skip)) types_set;
> +  hash_set<tree> * GTY((skip)) types_set;
>
>    /* Unique ID indexing the type in odr_types array.  */
>    int id;
> @@ -409,7 +410,7 @@ odr_hasher::remove (value_type *v)
>    v->bases.release ();
>    v->derived_types.release ();
>    if (v->types_set)
> -    pointer_set_destroy (v->types_set);
> +    delete v->types_set;
>    ggc_free (v);
>  }
>
> @@ -439,7 +440,7 @@ set_type_binfo (tree type, tree binfo)
>  /* Compare T2 and T2 based on name or structure.  */
>
>  static bool
> -odr_subtypes_equivalent_p (tree t1, tree t2, pointer_set_t *visited)
> +odr_subtypes_equivalent_p (tree t1, tree t2, hash_set<tree> *visited)
>  {
>    bool an1, an2;
>
> @@ -473,7 +474,7 @@ odr_subtypes_equivalent_p (tree t1, tree t2, pointer_set_t *visited)
>        /* This should really be a pair hash, but for the moment we do not need
>          100% reliability and it would be better to compare all ODR types so
>          recursion here is needed only for component types.  */
> -      if (pointer_set_insert (visited, t1))
> +      if (visited->add (t1))
>         return true;
>        return odr_types_equivalent_p (t1, t2, false, NULL, visited);
>      }
> @@ -562,7 +563,7 @@ warn_types_mismatch (tree t1, tree t2)
>     gimple_canonical_types_compatible_p.  */
>
>  static bool
> -odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, pointer_set_t *visited)
> +odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, hash_set<tree> *visited)
>  {
>    /* Check first for the obvious case of pointer identity.  */
>    if (t1 == t2)
> @@ -938,7 +939,7 @@ add_type_duplicate (odr_type val, tree type)
>  {
>    bool build_bases = false;
>    if (!val->types_set)
> -    val->types_set = pointer_set_create ();
> +    val->types_set = new hash_set<tree>;
>
>    /* Always prefer complete type to be the leader.  */
>    if (!COMPLETE_TYPE_P (val->type)
> @@ -952,20 +953,20 @@ add_type_duplicate (odr_type val, tree type)
>      }
>
>    /* See if this duplicate is new.  */
> -  if (!pointer_set_insert (val->types_set, type))
> +  if (!val->types_set->add (type))
>      {
>        bool merge = true;
>        bool base_mismatch = false;
>        unsigned int i,j;
>        bool warned = false;
> -      pointer_set_t *visited = pointer_set_create ();
> +      hash_set<tree> visited;
>
>        gcc_assert (in_lto_p);
>        vec_safe_push (val->types, type);
>
>        /* First we compare memory layout.  */
>        if (!odr_types_equivalent_p (val->type, type, !flag_ltrans && !val->odr_violated,
> -                                  &warned, visited))
> +                                  &warned, &visited))
>         {
>           merge = false;
>           odr_violation_reported = true;
> @@ -980,7 +981,6 @@ add_type_duplicate (odr_type val, tree type)
>               putc ('\n',cgraph_dump_file);
>             }
>         }
> -      pointer_set_destroy (visited);
>
>        /* Next sanity check that bases are the same.  If not, we will end
>          up producing wrong answers.  */
> @@ -1356,7 +1356,7 @@ referenced_from_vtable_p (struct cgraph_node *node)
>
>  static void
>  maybe_record_node (vec <cgraph_node *> &nodes,
> -                  tree target, pointer_set_t *inserted,
> +                  tree target, hash_set<tree> *inserted,
>                    bool can_refer,
>                    bool *completep)
>  {
> @@ -1422,10 +1422,9 @@ maybe_record_node (vec <cgraph_node *> &nodes,
>      {
>        gcc_assert (!target_node->global.inlined_to);
>        gcc_assert (target_node->real_symbol_p ());
> -      if (!pointer_set_insert (inserted, target_node->decl))
> +      if (!inserted->add (target))
>         {
> -         pointer_set_insert (cached_polymorphic_call_targets,
> -                             target_node);
> +         cached_polymorphic_call_targets->add (target_node);
>           nodes.safe_push (target_node);
>         }
>      }
> @@ -1465,8 +1464,8 @@ record_target_from_binfo (vec <cgraph_node *> &nodes,
>                           HOST_WIDE_INT otr_token,
>                           tree outer_type,
>                           HOST_WIDE_INT offset,
> -                         pointer_set_t *inserted,
> -                         pointer_set_t *matched_vtables,
> +                         hash_set<tree> *inserted,
> +                         hash_set<tree> *matched_vtables,
>                           bool anonymous,
>                           bool *completep)
>  {
> @@ -1519,8 +1518,8 @@ record_target_from_binfo (vec <cgraph_node *> &nodes,
>         }
>        gcc_assert (inner_binfo);
>        if (bases_to_consider
> -         ? !pointer_set_contains (matched_vtables, BINFO_VTABLE (inner_binfo))
> -         : !pointer_set_insert (matched_vtables, BINFO_VTABLE (inner_binfo)))
> +         ? !matched_vtables->contains (BINFO_VTABLE (inner_binfo))
> +         : !matched_vtables->add (BINFO_VTABLE (inner_binfo)))
>         {
>           bool can_refer;
>           tree target = gimple_get_virt_method_for_binfo (otr_token,
> @@ -1559,8 +1558,8 @@ record_target_from_binfo (vec <cgraph_node *> &nodes,
>
>  static void
>  possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes,
> -                                    pointer_set_t *inserted,
> -                                    pointer_set_t *matched_vtables,
> +                                    hash_set<tree> *inserted,
> +                                    hash_set<tree> *matched_vtables,
>                                      tree otr_type,
>                                      odr_type type,
>                                      HOST_WIDE_INT otr_token,
> @@ -1684,7 +1683,7 @@ free_polymorphic_call_targets_hash ()
>      {
>        delete polymorphic_call_target_hash;
>        polymorphic_call_target_hash = NULL;
> -      pointer_set_destroy (cached_polymorphic_call_targets);
> +      delete cached_polymorphic_call_targets;
>        cached_polymorphic_call_targets = NULL;
>      }
>  }
> @@ -1695,7 +1694,7 @@ static void
>  devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED)
>  {
>    if (cached_polymorphic_call_targets
> -      && pointer_set_contains (cached_polymorphic_call_targets, n))
> +      && cached_polymorphic_call_targets->contains (n))
>      free_polymorphic_call_targets_hash ();
>  }
>
> @@ -2277,8 +2276,8 @@ record_targets_from_bases (tree otr_type,
>                            tree outer_type,
>                            HOST_WIDE_INT offset,
>                            vec <cgraph_node *> &nodes,
> -                          pointer_set_t *inserted,
> -                          pointer_set_t *matched_vtables,
> +                          hash_set<tree> *inserted,
> +                          hash_set<tree> *matched_vtables,
>                            bool *completep)
>  {
>    while (true)
> @@ -2319,7 +2318,7 @@ record_targets_from_bases (tree otr_type,
>           return;
>         }
>        gcc_assert (base_binfo);
> -      if (!pointer_set_insert (matched_vtables, BINFO_VTABLE (base_binfo)))
> +      if (!matched_vtables->add (BINFO_VTABLE (base_binfo)))
>         {
>           bool can_refer;
>           tree target = gimple_get_virt_method_for_binfo (otr_token,
> @@ -2327,7 +2326,7 @@ record_targets_from_bases (tree otr_type,
>                                                           &can_refer);
>           if (!target || ! DECL_CXX_DESTRUCTOR_P (target))
>             maybe_record_node (nodes, target, inserted, can_refer, completep);
> -         pointer_set_insert (matched_vtables, BINFO_VTABLE (base_binfo));
> +         matched_vtables->add (BINFO_VTABLE (base_binfo));
>         }
>      }
>  }
> @@ -2377,8 +2376,6 @@ possible_polymorphic_call_targets (tree otr_type,
>                                    int *nonconstruction_targetsp)
>  {
>    static struct cgraph_node_hook_list *node_removal_hook_holder;
> -  pointer_set_t *inserted;
> -  pointer_set_t *matched_vtables;
>    vec <cgraph_node *> nodes = vNULL;
>    vec <tree> bases_to_consider = vNULL;
>    odr_type type, outer_type;
> @@ -2457,7 +2454,7 @@ possible_polymorphic_call_targets (tree otr_type,
>    /* Initialize query cache.  */
>    if (!cached_polymorphic_call_targets)
>      {
> -      cached_polymorphic_call_targets = pointer_set_create ();
> +      cached_polymorphic_call_targets = new hash_set<cgraph_node *>;
>        polymorphic_call_target_hash
>                 = new polymorphic_call_target_hash_type (23);
>        if (!node_removal_hook_holder)
> @@ -2496,8 +2493,8 @@ possible_polymorphic_call_targets (tree otr_type,
>    (*slot)->otr_token = otr_token;
>    (*slot)->context = context;
>
> -  inserted = pointer_set_create ();
> -  matched_vtables = pointer_set_create ();
> +  hash_set<tree> inserted;
> +  hash_set<tree> matched_vtables;
>
>    /* First see virtual method of type itself.  */
>    binfo = get_binfo_at_offset (TYPE_BINFO (outer_type->type),
> @@ -2526,7 +2523,7 @@ possible_polymorphic_call_targets (tree otr_type,
>
>    /* If OUTER_TYPE is abstract, we know we are not seeing its instance.  */
>    if (type_possibly_instantiated_p (outer_type->type))
> -    maybe_record_node (nodes, target, inserted, can_refer, &complete);
> +    maybe_record_node (nodes, target, &inserted, can_refer, &complete);
>    else
>      {
>        skipped = true;
> @@ -2534,7 +2531,7 @@ possible_polymorphic_call_targets (tree otr_type,
>      }
>
>    if (binfo)
> -    pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo));
> +    matched_vtables.add (BINFO_VTABLE (binfo));
>
>    /* Next walk recursively all derived types.  */
>    if (context.maybe_derived_type)
> @@ -2544,8 +2541,8 @@ possible_polymorphic_call_targets (tree otr_type,
>        if (!type->all_derivations_known)
>         complete = false;
>        for (i = 0; i < outer_type->derived_types.length(); i++)
> -       possible_polymorphic_call_targets_1 (nodes, inserted,
> -                                            matched_vtables,
> +       possible_polymorphic_call_targets_1 (nodes, &inserted,
> +                                            &matched_vtables,
>                                              otr_type,
>                                              outer_type->derived_types[i],
>                                              otr_token, outer_type->type,
> @@ -2571,12 +2568,12 @@ possible_polymorphic_call_targets (tree otr_type,
>               || (context.maybe_derived_type
>                   && !type_all_derivations_known_p (outer_type->type))))
>         record_targets_from_bases (otr_type, otr_token, outer_type->type,
> -                                  context.offset, nodes, inserted,
> -                                  matched_vtables, &complete);
> +                                  context.offset, nodes, &inserted,
> +                                  &matched_vtables, &complete);
>        if (skipped)
> -        maybe_record_node (nodes, target, inserted, can_refer, &complete);
> +        maybe_record_node (nodes, target, &inserted, can_refer, &complete);
>        for (i = 0; i < bases_to_consider.length(); i++)
> -        maybe_record_node (nodes, bases_to_consider[i], inserted, can_refer, &complete);
> +        maybe_record_node (nodes, bases_to_consider[i], &inserted, can_refer, &complete);
>      }
>    bases_to_consider.release();
>
> @@ -2587,8 +2584,6 @@ possible_polymorphic_call_targets (tree otr_type,
>    if (nonconstruction_targetsp)
>      *nonconstruction_targetsp = (*slot)->nonconstruction_targets;
>
> -  pointer_set_destroy (inserted);
> -  pointer_set_destroy (matched_vtables);
>    timevar_pop (TV_IPA_VIRTUAL_CALL);
>    return nodes;
>  }
> @@ -2744,7 +2739,7 @@ static unsigned int
>  ipa_devirt (void)
>  {
>    struct cgraph_node *n;
> -  struct pointer_set_t *bad_call_targets = pointer_set_create ();
> +  hash_set<void *> bad_call_targets;
>    struct cgraph_edge *e;
>
>    int npolymorphic = 0, nspeculated = 0, nconverted = 0, ncold = 0;
> @@ -2792,8 +2787,7 @@ ipa_devirt (void)
>                 if (!dump_file)
>                   continue;
>               }
> -           if (pointer_set_contains (bad_call_targets,
> -                                     cache_token))
> +           if (bad_call_targets.contains (cache_token))
>               {
>                 if (dump_file)
>                   fprintf (dump_file, "Target list is known to be useless\n\n");
> @@ -2818,7 +2812,7 @@ ipa_devirt (void)
>                 }
>             if (!likely_target)
>               {
> -               pointer_set_insert (bad_call_targets, cache_token);
> +               bad_call_targets.add (cache_token);
>                 continue;
>               }
>             /* This is reached only when dumping; check if we agree or disagree
> @@ -2905,7 +2899,6 @@ ipa_devirt (void)
>        if (update)
>         inline_update_overall_summary (n);
>      }
> -  pointer_set_destroy (bad_call_targets);
>
>    if (dump_file)
>      fprintf (dump_file,
> diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
> index 2c281be..b964502 100644
> --- a/gcc/ipa-pure-const.c
> +++ b/gcc/ipa-pure-const.c
> @@ -65,8 +65,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree-scalar-evolution.h"
>  #include "intl.h"
>  #include "opts.h"
> -
> -static struct pointer_set_t *visited_nodes;
> +#include "hash-set.h"
>
>  /* Lattice values for const and pure functions.  Everything starts out
>     being const, then may drop to pure and then neither depending on
> @@ -133,13 +132,13 @@ function_always_visible_to_compiler_p (tree decl)
>
>  /* Emit suggestion about attribute ATTRIB_NAME for DECL.  KNOWN_FINITE
>     is true if the function is known to be finite.  The diagnostic is
> -   controlled by OPTION.  WARNED_ABOUT is a pointer_set unique for
> +   controlled by OPTION.  WARNED_ABOUT is a hash_set<tree> unique for
>     OPTION, this function may initialize it and it is always returned
>     by the function.  */
>
> -static struct pointer_set_t *
> +static hash_set<tree> *
>  suggest_attribute (int option, tree decl, bool known_finite,
> -                  struct pointer_set_t *warned_about,
> +                  hash_set<tree> *warned_about,
>                    const char * attrib_name)
>  {
>    if (!option_enabled (option, &global_options))
> @@ -149,10 +148,10 @@ suggest_attribute (int option, tree decl, bool known_finite,
>      return warned_about;
>
>    if (!warned_about)
> -    warned_about = pointer_set_create ();
> -  if (pointer_set_contains (warned_about, decl))
> +    warned_about = new hash_set<tree>;
> +  if (warned_about->contains (decl))
>      return warned_about;
> -  pointer_set_insert (warned_about, decl);
> +  warned_about->add (decl);
>    warning_at (DECL_SOURCE_LOCATION (decl),
>               option,
>               known_finite
> @@ -168,7 +167,7 @@ suggest_attribute (int option, tree decl, bool known_finite,
>  static void
>  warn_function_pure (tree decl, bool known_finite)
>  {
> -  static struct pointer_set_t *warned_about;
> +  static hash_set<tree> *warned_about;
>
>    warned_about
>      = suggest_attribute (OPT_Wsuggest_attribute_pure, decl,
> @@ -181,7 +180,7 @@ warn_function_pure (tree decl, bool known_finite)
>  static void
>  warn_function_const (tree decl, bool known_finite)
>  {
> -  static struct pointer_set_t *warned_about;
> +  static hash_set<tree> *warned_about;
>    warned_about
>      = suggest_attribute (OPT_Wsuggest_attribute_const, decl,
>                          known_finite, warned_about, "const");
> @@ -190,7 +189,7 @@ warn_function_const (tree decl, bool known_finite)
>  static void
>  warn_function_noreturn (tree decl)
>  {
> -  static struct pointer_set_t *warned_about;
> +  static hash_set<tree> *warned_about;
>    if (!lang_hooks.missing_noreturn_ok_p (decl)
>        && targetm.warn_func_return (decl))
>      warned_about
> @@ -846,11 +845,8 @@ add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
>       static declarations.  We do not need to scan them more than once
>       since all we would be interested in are the addressof
>       operations.  */
> -  visited_nodes = pointer_set_create ();
>    if (node->get_availability () > AVAIL_INTERPOSABLE)
>      set_function_state (node, analyze_function (node, true));
> -  pointer_set_destroy (visited_nodes);
> -  visited_nodes = NULL;
>  }
>
>  /* Called when new clone is inserted to callgraph late.  */
> @@ -912,12 +908,6 @@ pure_const_generate_summary (void)
>
>    register_hooks ();
>
> -  /* There are some shared nodes, in particular the initializers on
> -     static declarations.  We do not need to scan them more than once
> -     since all we would be interested in are the addressof
> -     operations.  */
> -  visited_nodes = pointer_set_create ();
> -
>    /* Process all of the functions.
>
>       We process AVAIL_INTERPOSABLE functions.  We can not use the results
> @@ -927,9 +917,6 @@ pure_const_generate_summary (void)
>    FOR_EACH_DEFINED_FUNCTION (node)
>      if (node->get_availability () >= AVAIL_INTERPOSABLE)
>        set_function_state (node, analyze_function (node, true));
> -
> -  pointer_set_destroy (visited_nodes);
> -  visited_nodes = NULL;
>  }
>
>
> diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c
> index 4720ee9..bca2bc7 100644
> --- a/gcc/ipa-visibility.c
> +++ b/gcc/ipa-visibility.c
> @@ -687,12 +687,11 @@ function_and_variable_visibility (bool whole_program)
>               }
>           if (found)
>             {
> -             struct pointer_set_t *visited_nodes = pointer_set_create ();
> +             hash_set<tree> visited_nodes;
>
>               vnode->get_constructor ();
>               walk_tree (&DECL_INITIAL (vnode->decl),
> -                        update_vtable_references, NULL, visited_nodes);
> -             pointer_set_destroy (visited_nodes);
> +                        update_vtable_references, NULL, &visited_nodes);
>               vnode->remove_all_references ();
>               record_references_in_initializer (vnode->decl, false);
>             }
> diff --git a/gcc/ipa.c b/gcc/ipa.c
> index 8198b17..1081e89 100644
> --- a/gcc/ipa.c
> +++ b/gcc/ipa.c
> @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "cgraph.h"
>  #include "tree-pass.h"
>  #include "hash-map.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "gimple-expr.h"
>  #include "gimplify.h"
>  #include "flags.h"
> @@ -84,14 +84,14 @@ update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined
>
>  static void
>  enqueue_node (symtab_node *node, symtab_node **first,
> -             struct pointer_set_t *reachable)
> +             hash_set<symtab_node *> *reachable)
>  {
>    /* Node is still in queue; do nothing.  */
>    if (node->aux && node->aux != (void *) 2)
>      return;
>    /* Node was already processed as unreachable, re-enqueue
>       only if it became reachable now.  */
> -  if (node->aux == (void *)2 && !pointer_set_contains (reachable, node))
> +  if (node->aux == (void *)2 && !reachable->contains (node))
>      return;
>    node->aux = *first;
>    *first = node;
> @@ -103,7 +103,7 @@ static void
>  process_references (symtab_node *snode,
>                     symtab_node **first,
>                     bool before_inlining_p,
> -                   struct pointer_set_t *reachable)
> +                   hash_set<symtab_node *> *reachable)
>  {
>    int i;
>    struct ipa_ref *ref = NULL;
> @@ -124,7 +124,7 @@ process_references (symtab_node *snode,
>                       && flag_wpa
>                       && ctor_for_folding (node->decl)
>                          != error_mark_node))))
> -       pointer_set_insert (reachable, node);
> +       reachable->add (node);
>        enqueue_node (node, first, reachable);
>      }
>  }
> @@ -138,10 +138,11 @@ process_references (symtab_node *snode,
>     possible.  */
>
>  static void
> -walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
> +walk_polymorphic_call_targets (hash_set<void *> *reachable_call_targets,
>                                struct cgraph_edge *edge,
>                                symtab_node **first,
> -                              pointer_set_t *reachable, bool before_inlining_p)
> +                              hash_set<symtab_node *> *reachable,
> +                              bool before_inlining_p)
>  {
>    unsigned int i;
>    void *cache_token;
> @@ -150,8 +151,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
>      = possible_polymorphic_call_targets
>         (edge, &final, &cache_token);
>
> -  if (!pointer_set_insert (reachable_call_targets,
> -                          cache_token))
> +  if (!reachable_call_targets->add (cache_token))
>      {
>        for (i = 0; i < targets.length (); i++)
>         {
> @@ -172,7 +172,7 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
>                    && (cgraph_state < CGRAPH_STATE_IPA_SSA
>                        || !lookup_attribute ("always_inline",
>                                              DECL_ATTRIBUTES (n->decl)))))
> -            pointer_set_insert (reachable, n);
> +            reachable->add (n);
>
>           /* Even after inlining we want to keep the possible targets in the
>              boundary, so late passes can still produce direct call even if
> @@ -276,9 +276,9 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>    struct cgraph_node *node, *next;
>    varpool_node *vnode, *vnext;
>    bool changed = false;
> -  struct pointer_set_t *reachable = pointer_set_create ();
> -  struct pointer_set_t *body_needed_for_clonning = pointer_set_create ();
> -  struct pointer_set_t *reachable_call_targets = pointer_set_create ();
> +  hash_set<symtab_node *> reachable;
> +  hash_set<tree> body_needed_for_clonning;
> +  hash_set<void *> reachable_call_targets;
>
>    timevar_push (TV_IPA_UNREACHABLE);
>    if (optimize && flag_devirtualize)
> @@ -304,8 +304,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>           && !node->can_remove_if_no_direct_calls_and_refs_p ())
>         {
>           gcc_assert (!node->global.inlined_to);
> -         pointer_set_insert (reachable, node);
> -         enqueue_node (node, &first, reachable);
> +         reachable.add (node);
> +         enqueue_node (node, &first, &reachable);
>         }
>        else
>         gcc_assert (!node->aux);
> @@ -316,14 +316,14 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>      if (!vnode->can_remove_if_no_refs_p()
>         && !vnode->in_other_partition)
>        {
> -       pointer_set_insert (reachable, vnode);
> -       enqueue_node (vnode, &first, reachable);
> +       reachable.add (vnode);
> +       enqueue_node (vnode, &first, &reachable);
>        }
>
>    /* Perform reachability analysis.  */
>    while (first != (symtab_node *) (void *) 1)
>      {
> -      bool in_boundary_p = !pointer_set_contains (reachable, first);
> +      bool in_boundary_p = !reachable.contains (first);
>        symtab_node *node = first;
>
>        first = (symtab_node *)first->aux;
> @@ -340,7 +340,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>               struct cgraph_node *origin_node
>               = cgraph_node::get_create (DECL_ABSTRACT_ORIGIN (node->decl));
>               origin_node->used_as_abstract_origin = true;
> -             enqueue_node (origin_node, &first, reachable);
> +             enqueue_node (origin_node, &first, &reachable);
>             }
>           /* If any symbol in a comdat group is reachable, force
>              all externally visible symbols in the same comdat
> @@ -353,11 +353,11 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>                    next != node;
>                    next = next->same_comdat_group)
>                 if (!next->comdat_local_p ()
> -                   && !pointer_set_insert (reachable, next))
> -                 enqueue_node (next, &first, reachable);
> +                   && !reachable.add (next))
> +                 enqueue_node (next, &first, &reachable);
>             }
>           /* Mark references as reachable.  */
> -         process_references (node, &first, before_inlining_p, reachable);
> +         process_references (node, &first, before_inlining_p, &reachable);
>         }
>
>        if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
> @@ -375,8 +375,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>                     {
>                       next = e->next_callee;
>                       if (e->indirect_info->polymorphic)
> -                       walk_polymorphic_call_targets (reachable_call_targets,
> -                                                      e, &first, reachable,
> +                       walk_polymorphic_call_targets (&reachable_call_targets,
> +                                                      e, &first, &reachable,
>                                                        before_inlining_p);
>                     }
>                 }
> @@ -394,17 +394,16 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>                       if (DECL_EXTERNAL (e->callee->decl)
>                           && e->callee->alias
>                           && before_inlining_p)
> -                       pointer_set_insert (reachable,
> -                                           e->callee->function_symbol ());
> -                     pointer_set_insert (reachable, e->callee);
> +                       reachable.add (e->callee->function_symbol ());
> +                     reachable.add (e->callee);
>                     }
> -                 enqueue_node (e->callee, &first, reachable);
> +                 enqueue_node (e->callee, &first, &reachable);
>                 }
>
>               /* When inline clone exists, mark body to be preserved so when removing
>                  offline copy of the function we don't kill it.  */
>               if (cnode->global.inlined_to)
> -               pointer_set_insert (body_needed_for_clonning, cnode->decl);
> +               body_needed_for_clonning.add (cnode->decl);
>
>               /* For non-inline clones, force their origins to the boundary and ensure
>                  that body is not removed.  */
> @@ -414,8 +413,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>                   cnode = cnode->clone_of;
>                   if (noninline)
>                     {
> -                     pointer_set_insert (body_needed_for_clonning, cnode->decl);
> -                     enqueue_node (cnode, &first, reachable);
> +                     body_needed_for_clonning.add (cnode->decl);
> +                     enqueue_node (cnode, &first, &reachable);
>                     }
>                 }
>
> @@ -429,8 +428,8 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>                    next;
>                    next = next->simdclone->next_clone)
>                 if (in_boundary_p
> -                   || !pointer_set_insert (reachable, next))
> -                 enqueue_node (next, &first, reachable);
> +                   || !reachable.add (next))
> +                 enqueue_node (next, &first, &reachable);
>             }
>         }
>        /* When we see constructor of external variable, keep referred nodes in the
> @@ -444,7 +443,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>         {
>           struct ipa_ref *ref = NULL;
>           for (int i = 0; node->iterate_reference (i, ref); i++)
> -           enqueue_node (ref->referred, &first, reachable);
> +           enqueue_node (ref->referred, &first, &reachable);
>         }
>      }
>
> @@ -462,9 +461,9 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>           changed = true;
>         }
>        /* If node is unreachable, remove its body.  */
> -      else if (!pointer_set_contains (reachable, node))
> +      else if (!reachable.contains (node))
>          {
> -         if (!pointer_set_contains (body_needed_for_clonning, node->decl))
> +         if (!body_needed_for_clonning.contains (node->decl))
>             node->release_body ();
>           else if (!node->clone_of)
>             gcc_assert (in_lto_p || DECL_RESULT (node->decl));
> @@ -530,7 +529,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>           vnode->remove ();
>           changed = true;
>         }
> -      else if (!pointer_set_contains (reachable, vnode))
> +      else if (!reachable.contains (vnode))
>          {
>           tree init;
>           if (vnode->definition)
> @@ -557,10 +556,6 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
>         vnode->aux = NULL;
>      }
>
> -  pointer_set_destroy (reachable);
> -  pointer_set_destroy (body_needed_for_clonning);
> -  pointer_set_destroy (reachable_call_targets);
> -
>    /* Now update address_taken flags and try to promote functions to be local.  */
>    if (file)
>      fprintf (file, "\nClearing address taken flags:");
> diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
> index b1fcf67..42b0790 100644
> --- a/gcc/lto-cgraph.c
> +++ b/gcc/lto-cgraph.c
> @@ -37,6 +37,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "params.h"
>  #include "input.h"
>  #include "hashtab.h"
> +#include "hash-set.h"
>  #include "langhooks.h"
>  #include "bitmap.h"
>  #include "function.h"
> @@ -819,7 +820,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
>    int i;
>    lto_symtab_encoder_t encoder;
>    lto_symtab_encoder_iterator lsei;
> -  struct pointer_set_t *reachable_call_targets = pointer_set_create ();
> +  hash_set<void *> reachable_call_targets;
>
>    encoder = lto_symtab_encoder_new (false);
>
> @@ -902,8 +903,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
>               vec <cgraph_node *>targets
>                 = possible_polymorphic_call_targets
>                     (edge, &final, &cache_token);
> -             if (!pointer_set_insert (reachable_call_targets,
> -                                      cache_token))
> +             if (!reachable_call_targets.add (cache_token))
>                 {
>                   for (i = 0; i < targets.length (); i++)
>                     {
> @@ -923,7 +923,6 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
>             }
>      }
>    lto_symtab_encoder_delete (in_encoder);
> -  pointer_set_destroy (reachable_call_targets);
>    return encoder;
>  }
>
> diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
> index 271fbd5..3fd9147 100644
> --- a/gcc/lto-streamer-out.c
> +++ b/gcc/lto-streamer-out.c
> @@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "params.h"
>  #include "input.h"
>  #include "hashtab.h"
> +#include "hash-set.h"
>  #include "basic-block.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
> @@ -2433,7 +2434,7 @@ lto_out_decl_state_written_size (struct lto_out_decl_state *state)
>  static void
>  write_symbol (struct streamer_tree_cache_d *cache,
>               struct lto_output_stream *stream,
> -             tree t, struct pointer_set_t *seen, bool alias)
> +             tree t, hash_set<const char *> *seen, bool alias)
>  {
>    const char *name;
>    enum gcc_plugin_symbol_kind kind;
> @@ -2461,9 +2462,8 @@ write_symbol (struct streamer_tree_cache_d *cache,
>       same name manipulations that ASM_OUTPUT_LABELREF does. */
>    name = IDENTIFIER_POINTER ((*targetm.asm_out.mangle_assembler_name) (name));
>
> -  if (pointer_set_contains (seen, name))
> +  if (seen->add (name))
>      return;
> -  pointer_set_insert (seen, name);
>
>    streamer_tree_cache_lookup (cache, t, &slot_num);
>    gcc_assert (slot_num != (unsigned)-1);
> @@ -2588,7 +2588,6 @@ produce_symtab (struct output_block *ob)
>  {
>    struct streamer_tree_cache_d *cache = ob->writer_cache;
>    char *section_name = lto_get_section_name (LTO_section_symtab, NULL, NULL);
> -  struct pointer_set_t *seen;
>    struct lto_output_stream stream;
>    lto_symtab_encoder_t encoder = ob->decl_state->symtab_node_encoder;
>    lto_symtab_encoder_iterator lsei;
> @@ -2596,7 +2595,7 @@ produce_symtab (struct output_block *ob)
>    lto_begin_section (section_name, false);
>    free (section_name);
>
> -  seen = pointer_set_create ();
> +  hash_set<const char *> seen;
>    memset (&stream, 0, sizeof (stream));
>
>    /* Write the symbol table.
> @@ -2609,7 +2608,7 @@ produce_symtab (struct output_block *ob)
>
>        if (!output_symbol_p (node) || DECL_EXTERNAL (node->decl))
>         continue;
> -      write_symbol (cache, &stream, node->decl, seen, false);
> +      write_symbol (cache, &stream, node->decl, &seen, false);
>      }
>    for (lsei = lsei_start (encoder);
>         !lsei_end_p (lsei); lsei_next (&lsei))
> @@ -2618,11 +2617,10 @@ produce_symtab (struct output_block *ob)
>
>        if (!output_symbol_p (node) || !DECL_EXTERNAL (node->decl))
>         continue;
> -      write_symbol (cache, &stream, node->decl, seen, false);
> +      write_symbol (cache, &stream, node->decl, &seen, false);
>      }
>
>    lto_write_stream (&stream);
> -  pointer_set_destroy (seen);
>
>    lto_end_section ();
>  }
> diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
> index cb08a88..a5bcf92 100644
> --- a/gcc/lto/lto-partition.c
> +++ b/gcc/lto/lto-partition.c
> @@ -66,7 +66,7 @@ free_ltrans_partitions (void)
>    for (idx = 0; ltrans_partitions.iterate (idx, &part); idx++)
>      {
>        if (part->initializers_visited)
> -       pointer_set_destroy (part->initializers_visited);
> +       delete part->initializers_visited;
>        /* Symtab encoder is freed after streaming.  */
>        free (part);
>      }
> @@ -101,8 +101,8 @@ add_references_to_partition (ltrans_partition part, symtab_node *node)
>              && !lto_symtab_encoder_in_partition_p (part->encoder, ref->referred))
>        {
>         if (!part->initializers_visited)
> -         part->initializers_visited = pointer_set_create ();
> -       if (!pointer_set_insert (part->initializers_visited, ref->referred))
> +         part->initializers_visited = new hash_set<symtab_node *>;
> +       if (!part->initializers_visited->add (ref->referred))
>           add_references_to_partition (part, ref->referred);
>        }
>  }
> @@ -250,7 +250,7 @@ undo_partition (ltrans_partition partition, unsigned int n_nodes)
>
>        /* After UNDO we no longer know what was visited.  */
>        if (partition->initializers_visited)
> -       pointer_set_destroy (partition->initializers_visited);
> +       delete partition->initializers_visited;
>        partition->initializers_visited = NULL;
>
>        if (!node->alias && (cnode = dyn_cast <cgraph_node *> (node)))
> diff --git a/gcc/lto/lto-partition.h b/gcc/lto/lto-partition.h
> index 8db61b3..50ec2fa 100644
> --- a/gcc/lto/lto-partition.h
> +++ b/gcc/lto/lto-partition.h
> @@ -17,6 +17,7 @@ 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 "hash-set.h"
>
>  /* Structure describing ltrans partitions.  */
>
> @@ -25,7 +26,7 @@ struct ltrans_partition_def
>    lto_symtab_encoder_t encoder;
>    const char * name;
>    int insns;
> -  pointer_set_t *initializers_visited;
> +  hash_set<symtab_node *> *initializers_visited;
>  };
>
>  typedef struct ltrans_partition_def *ltrans_partition;
> diff --git a/gcc/stmt.c b/gcc/stmt.c
> index 0aae085..55ec279 100644
> --- a/gcc/stmt.c
> +++ b/gcc/stmt.c
> @@ -47,6 +47,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "predict.h"
>  #include "optabs.h"
>  #include "target.h"
> +#include "hash-set.h"
>  #include "pointer-set.h"
>  #include "basic-block.h"
>  #include "tree-ssa-alias.h"
> @@ -1183,7 +1184,7 @@ expand_case (gimple stmt)
>       how to expand this switch().  */
>    uniq = 0;
>    count = 0;
> -  struct pointer_set_t *seen_labels = pointer_set_create ();
> +  hash_set<tree> seen_labels;
>    compute_cases_per_edge (stmt);
>
>    for (i = ncases - 1; i >= 1; --i)
> @@ -1203,7 +1204,7 @@ expand_case (gimple stmt)
>
>        /* If we have not seen this label yet, then increase the
>          number of unique case node targets seen.  */
> -      if (!pointer_set_insert (seen_labels, lab))
> +      if (!seen_labels.add (lab))
>         uniq++;
>
>        /* The bounds on the case range, LOW and HIGH, have to be converted
> @@ -1231,7 +1232,6 @@ expand_case (gimple stmt)
>            case_edge->probability / (intptr_t)(case_edge->aux),
>            case_node_pool);
>      }
> -  pointer_set_destroy (seen_labels);
>    reset_out_edges_aux (bb);
>
>    /* cleanup_tree_cfg removes all SWITCH_EXPR with a single
> diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> index 6fee8a4..e034762 100644
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -4691,7 +4691,7 @@ tree_node_can_be_shared (tree t)
>  static tree
>  verify_node_sharing_1 (tree *tp, int *walk_subtrees, void *data)
>  {
> -  struct pointer_set_t *visited = (struct pointer_set_t *) data;
> +  hash_set<void *> *visited = (hash_set<void *> *) data;
>
>    if (tree_node_can_be_shared (*tp))
>      {
> @@ -4699,7 +4699,7 @@ verify_node_sharing_1 (tree *tp, int *walk_subtrees, void *data)
>        return NULL;
>      }
>
> -  if (pointer_set_insert (visited, *tp))
> +  if (visited->add (*tp))
>      return *tp;
>
>    return NULL;
> @@ -4719,9 +4719,9 @@ static int
>  verify_eh_throw_stmt_node (void **slot, void *data)
>  {
>    struct throw_stmt_node *node = (struct throw_stmt_node *)*slot;
> -  struct pointer_set_t *visited = (struct pointer_set_t *) data;
> +  hash_set<void *> *visited = (hash_set<void *> *) data;
>
> -  if (!pointer_set_contains (visited, node->stmt))
> +  if (!visited->contains (node->stmt))
>      {
>        error ("dead STMT in EH table");
>        debug_gimple_stmt (node->stmt);
> @@ -4733,11 +4733,11 @@ verify_eh_throw_stmt_node (void **slot, void *data)
>  /* Verify if the location LOCs block is in BLOCKS.  */
>
>  static bool
> -verify_location (pointer_set_t *blocks, location_t loc)
> +verify_location (hash_set<tree> *blocks, location_t loc)
>  {
>    tree block = LOCATION_BLOCK (loc);
>    if (block != NULL_TREE
> -      && !pointer_set_contains (blocks, block))
> +      && !blocks->contains (block))
>      {
>        error ("location references block not in block tree");
>        return true;
> @@ -4770,7 +4770,7 @@ verify_expr_no_block (tree *tp, int *walk_subtrees, void *)
>  static tree
>  verify_expr_location_1 (tree *tp, int *walk_subtrees, void *data)
>  {
> -  struct pointer_set_t *blocks = (struct pointer_set_t *) data;
> +  hash_set<tree> *blocks = (hash_set<tree> *) data;
>
>    if (TREE_CODE (*tp) == VAR_DECL
>        && DECL_HAS_DEBUG_EXPR_P (*tp))
> @@ -4816,12 +4816,12 @@ verify_expr_location (tree *tp, int *walk_subtrees, void *data)
>  /* Insert all subblocks of BLOCK into BLOCKS and recurse.  */
>
>  static void
> -collect_subblocks (pointer_set_t *blocks, tree block)
> +collect_subblocks (hash_set<tree> *blocks, tree block)
>  {
>    tree t;
>    for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
>      {
> -      pointer_set_insert (blocks, t);
> +      blocks->add (t);
>        collect_subblocks (blocks, t);
>      }
>  }
> @@ -4833,18 +4833,17 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
>  {
>    basic_block bb;
>    bool err = false;
> -  struct pointer_set_t *visited, *visited_stmts, *blocks;
>
>    timevar_push (TV_TREE_STMT_VERIFY);
> -  visited = pointer_set_create ();
> -  visited_stmts = pointer_set_create ();
> +  hash_set<void *> visited;
> +  hash_set<gimple> visited_stmts;
>
>    /* Collect all BLOCKs referenced by the BLOCK tree of FN.  */
> -  blocks = pointer_set_create ();
> +  hash_set<tree> blocks;
>    if (DECL_INITIAL (fn->decl))
>      {
> -      pointer_set_insert (blocks, DECL_INITIAL (fn->decl));
> -      collect_subblocks (blocks, DECL_INITIAL (fn->decl));
> +      blocks.add (DECL_INITIAL (fn->decl));
> +      collect_subblocks (&blocks, DECL_INITIAL (fn->decl));
>      }
>
>    FOR_EACH_BB_FN (bb, fn)
> @@ -4857,7 +4856,7 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
>           bool err2 = false;
>           unsigned i;
>
> -         pointer_set_insert (visited_stmts, phi);
> +         visited_stmts.add (phi);
>
>           if (gimple_bb (phi) != bb)
>             {
> @@ -4878,7 +4877,7 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
>             {
>               tree arg = gimple_phi_arg_def (phi, i);
>               tree addr = walk_tree (&arg, verify_node_sharing_1,
> -                                    visited, NULL);
> +                                    &visited, NULL);
>               if (addr)
>                 {
>                   error ("incorrect sharing of tree nodes");
> @@ -4892,13 +4891,13 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
>                   error ("virtual PHI with argument locations");
>                   err2 = true;
>                 }
> -             addr = walk_tree (&arg, verify_expr_location_1, blocks, NULL);
> +             addr = walk_tree (&arg, verify_expr_location_1, &blocks, NULL);
>               if (addr)
>                 {
>                   debug_generic_expr (addr);
>                   err2 = true;
>                 }
> -             err2 |= verify_location (blocks, loc);
> +             err2 |= verify_location (&blocks, loc);
>             }
>
>           if (err2)
> @@ -4914,7 +4913,7 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
>           tree addr;
>           int lp_nr;
>
> -         pointer_set_insert (visited_stmts, stmt);
> +         visited_stmts.add (stmt);
>
>           if (gimple_bb (stmt) != bb)
>             {
> @@ -4923,10 +4922,10 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
>             }
>
>           err2 |= verify_gimple_stmt (stmt);
> -         err2 |= verify_location (blocks, gimple_location (stmt));
> +         err2 |= verify_location (&blocks, gimple_location (stmt));
>
>           memset (&wi, 0, sizeof (wi));
> -         wi.info = (void *) visited;
> +         wi.info = (void *) &visited;
>           addr = walk_gimple_op (stmt, verify_node_sharing, &wi);
>           if (addr)
>             {
> @@ -4936,7 +4935,7 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
>             }
>
>           memset (&wi, 0, sizeof (wi));
> -         wi.info = (void *) blocks;
> +         wi.info = (void *) &blocks;
>           addr = walk_gimple_op (stmt, verify_expr_location, &wi);
>           if (addr)
>             {
> @@ -4992,14 +4991,11 @@ verify_gimple_in_cfg (struct function *fn, bool verify_nothrow)
>    if (get_eh_throw_stmt_table (cfun))
>      htab_traverse (get_eh_throw_stmt_table (cfun),
>                    verify_eh_throw_stmt_node,
> -                  visited_stmts);
> +                  &visited_stmts);
>
>    if (err || eh_error_found)
>      internal_error ("verify_gimple failed");
>
> -  pointer_set_destroy (visited);
> -  pointer_set_destroy (visited_stmts);
> -  pointer_set_destroy (blocks);
>    verify_histograms ();
>    timevar_pop (TV_TREE_STMT_VERIFY);
>  }
> diff --git a/gcc/tree-core.h b/gcc/tree-core.h
> index 34c48fa..9d462d1 100644
> --- a/gcc/tree-core.h
> +++ b/gcc/tree-core.h
> @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
>  #define GCC_TREE_CORE_H
>
>  #include "hashtab.h"
> +#include "hash-set.h"
>  #include "machmode.h"
>  #include "input.h"
>  #include "statistics.h"
> @@ -45,7 +46,6 @@ struct fixed_value;
>  struct ptr_info_def;
>  struct range_info_def;
>  struct die_struct;
> -struct pointer_set_t;
>
>
>  /*---------------------------------------------------------------------------
> @@ -692,7 +692,7 @@ typedef tree (*walk_tree_fn) (tree *, int *, void *);
>
>  /* The type of a callback function that represents a custom walk_tree.  */
>  typedef tree (*walk_tree_lh) (tree *, int *, tree (*) (tree *, int *, void *),
> -                             void *, struct pointer_set_t*);
> +                             void *, hash_set<tree> *);
>
>
>  /*---------------------------------------------------------------------------
> diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
> index df9a6fc..38842e8 100644
> --- a/gcc/tree-eh.c
> +++ b/gcc/tree-eh.c
> @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "flags.h"
>  #include "function.h"
>  #include "except.h"
> +#include "hash-set.h"
>  #include "pointer-set.h"
>  #include "basic-block.h"
>  #include "tree-ssa-alias.h"
> @@ -3578,7 +3579,7 @@ lower_eh_dispatch (basic_block src, gimple stmt)
>         eh_catch c;
>         edge_iterator ei;
>         edge e;
> -       struct pointer_set_t *seen_values = pointer_set_create ();
> +       hash_set<tree> seen_values;
>
>         /* Collect the labels for a switch.  Zero the post_landing_pad
>            field becase we'll no longer have anything keeping these labels
> @@ -3605,12 +3606,12 @@ lower_eh_dispatch (basic_block src, gimple stmt)
>                    attached to the handler anymore, we remove
>                    the corresponding edge and then we delete unreachable
>                    blocks at the end of this pass.  */
> -               if (! pointer_set_contains (seen_values, TREE_VALUE (flt_node)))
> +               if (! seen_values.contains (TREE_VALUE (flt_node)))
>                   {
>                     tree t = build_case_label (TREE_VALUE (flt_node),
>                                                NULL, lab);
>                     labels.safe_push (t);
> -                   pointer_set_insert (seen_values, TREE_VALUE (flt_node));
> +                   seen_values.add (TREE_VALUE (flt_node));
>                     have_label = true;
>                   }
>
> @@ -3662,7 +3663,6 @@ lower_eh_dispatch (basic_block src, gimple stmt)
>             x = gimple_build_switch (filter, default_label, labels);
>             gsi_insert_before (&gsi, x, GSI_SAME_STMT);
>           }
> -       pointer_set_destroy (seen_values);
>        }
>        break;
>
> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
> index 33705b7..6af4912 100644
> --- a/gcc/tree-inline.c
> +++ b/gcc/tree-inline.c
> @@ -1788,7 +1788,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
>              expensive, copy_body can be told to watch for nontrivial
>              changes.  */
>           if (id->statements_to_fold)
> -           pointer_set_insert (id->statements_to_fold, stmt);
> +           id->statements_to_fold->add (stmt);
>
>           /* We're duplicating a CALL_EXPR.  Find any corresponding
>              callgraph edges and update or duplicate them.  */
> @@ -3507,7 +3507,6 @@ inline_forbidden_p (tree fndecl)
>  {
>    struct function *fun = DECL_STRUCT_FUNCTION (fndecl);
>    struct walk_stmt_info wi;
> -  struct pointer_set_t *visited_nodes;
>    basic_block bb;
>    bool forbidden_p = false;
>
> @@ -3518,10 +3517,10 @@ inline_forbidden_p (tree fndecl)
>
>    /* Next, walk the statements of the function looking for
>       constraucts we can't handle, or are non-optimal for inlining.  */
> -  visited_nodes = pointer_set_create ();
> +  hash_set<tree> visited_nodes;
>    memset (&wi, 0, sizeof (wi));
>    wi.info = (void *) fndecl;
> -  wi.pset = visited_nodes;
> +  wi.pset = &visited_nodes;
>
>    FOR_EACH_BB_FN (bb, fun)
>      {
> @@ -3533,7 +3532,6 @@ inline_forbidden_p (tree fndecl)
>         break;
>      }
>
> -  pointer_set_destroy (visited_nodes);
>    return forbidden_p;
>  }
>
> @@ -4531,7 +4529,7 @@ gimple_expand_calls_inline (basic_block bb, copy_body_data *id)
>     in the STATEMENTS pointer set.  */
>
>  static void
> -fold_marked_statements (int first, struct pointer_set_t *statements)
> +fold_marked_statements (int first, hash_set<gimple> *statements)
>  {
>    for (; first < n_basic_blocks_for_fn (cfun); first++)
>      if (BASIC_BLOCK_FOR_FN (cfun, first))
> @@ -4541,7 +4539,7 @@ fold_marked_statements (int first, struct pointer_set_t *statements)
>         for (gsi = gsi_start_bb (BASIC_BLOCK_FOR_FN (cfun, first));
>              !gsi_end_p (gsi);
>              gsi_next (&gsi))
> -         if (pointer_set_contains (statements, gsi_stmt (gsi)))
> +         if (statements->contains (gsi_stmt (gsi)))
>             {
>               gimple old_stmt = gsi_stmt (gsi);
>               tree old_decl = is_gimple_call (old_stmt) ? gimple_call_fndecl (old_stmt) : 0;
> @@ -4642,7 +4640,7 @@ optimize_inline_calls (tree fn)
>    id.transform_return_to_modify = true;
>    id.transform_parameter = true;
>    id.transform_lang_insert_block = NULL;
> -  id.statements_to_fold = pointer_set_create ();
> +  id.statements_to_fold = new hash_set<gimple>;
>
>    push_gimplify_context ();
>
> @@ -4678,7 +4676,7 @@ optimize_inline_calls (tree fn)
>
>    /* Fold queued statements.  */
>    fold_marked_statements (last, id.statements_to_fold);
> -  pointer_set_destroy (id.statements_to_fold);
> +  delete id.statements_to_fold;
>
>    gcc_assert (!id.debug_stmts.exists ());
>
> @@ -4920,7 +4918,6 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
>  {
>    copy_body_data id;
>    struct walk_stmt_info wi;
> -  struct pointer_set_t *visited;
>    gimple_seq copy;
>
>    /* There's nothing to do for NULL_TREE.  */
> @@ -4943,11 +4940,10 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
>
>    /* Walk the tree once to find local labels.  */
>    memset (&wi, 0, sizeof (wi));
> -  visited = pointer_set_create ();
> +  hash_set<tree> visited;
>    wi.info = &id;
> -  wi.pset = visited;
> +  wi.pset = &visited;
>    walk_gimple_seq (seq, mark_local_labels_stmt, NULL, &wi);
> -  pointer_set_destroy (visited);
>
>    copy = gimple_seq_copy (seq);
>
> @@ -5370,7 +5366,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
>    memset (&id, 0, sizeof (id));
>
>    /* Generate a new name for the new version. */
> -  id.statements_to_fold = pointer_set_create ();
> +  id.statements_to_fold = new hash_set<gimple>;
>
>    id.decl_map = pointer_map_create ();
>    id.debug_map = NULL;
> @@ -5541,7 +5537,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
>    free_dominance_info (CDI_POST_DOMINATORS);
>
>    fold_marked_statements (0, id.statements_to_fold);
> -  pointer_set_destroy (id.statements_to_fold);
> +  delete id.statements_to_fold;
>    fold_cond_expr_cond ();
>    delete_unreachable_blocks_update_callgraph (&id);
>    if (id.dst_node->definition)
> diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
> index 2a5daaf..c13e6c7 100644
> --- a/gcc/tree-inline.h
> +++ b/gcc/tree-inline.h
> @@ -21,6 +21,8 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_TREE_INLINE_H
>  #define GCC_TREE_INLINE_H
>
> +#include "hash-set.h"
> +
>  struct cgraph_edge;
>
>  /* Indicate the desired behavior wrt call graph edges.  We can either
> @@ -114,7 +116,7 @@ struct copy_body_data
>    void (*transform_lang_insert_block) (tree);
>
>    /* Statements that might be possibly folded.  */
> -  struct pointer_set_t *statements_to_fold;
> +  hash_set<gimple> *statements_to_fold;
>
>    /* Entry basic block to currently copied body.  */
>    basic_block entry_bb;
> diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
> index 185d87c..45c5cf7 100644
> --- a/gcc/tree-nested.c
> +++ b/gcc/tree-nested.c
> @@ -95,7 +95,7 @@ struct nesting_info
>
>    struct pointer_map_t *field_map;
>    struct pointer_map_t *var_map;
> -  struct pointer_set_t *mem_refs;
> +  hash_set<tree *> *mem_refs;
>    bitmap suppress_expansion;
>
>    tree context;
> @@ -732,7 +732,7 @@ create_nesting_tree (struct cgraph_node *cgn)
>    struct nesting_info *info = XCNEW (struct nesting_info);
>    info->field_map = pointer_map_create ();
>    info->var_map = pointer_map_create ();
> -  info->mem_refs = pointer_set_create ();
> +  info->mem_refs = new hash_set<tree *>;
>    info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
>    info->context = cgn->decl;
>
> @@ -1651,7 +1651,7 @@ convert_local_reference_op (tree *tp, int *walk_subtrees, void *data)
>          fold here, as the chain record type is not yet finalized.  */
>        if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
>           && !DECL_P (TREE_OPERAND (TREE_OPERAND (t, 0), 0)))
> -       pointer_set_insert (info->mem_refs, tp);
> +       info->mem_refs->add (tp);
>        wi->val_only = save_val_only;
>        break;
>
> @@ -2655,8 +2655,8 @@ remap_vla_decls (tree block, struct nesting_info *root)
>  }
>
>  /* Fold the MEM_REF *E.  */
> -static bool
> -fold_mem_refs (const void *e, void *data ATTRIBUTE_UNUSED)
> +bool
> +fold_mem_refs (tree *const &e, void *data ATTRIBUTE_UNUSED)
>  {
>    tree *ref_p = CONST_CAST2 (tree *, const tree *, (const tree *)e);
>    *ref_p = fold (*ref_p);
> @@ -2878,7 +2878,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
>      }
>
>    /* Fold the rewritten MEM_REF trees.  */
> -  pointer_set_traverse (root->mem_refs, fold_mem_refs, NULL);
> +  root->mem_refs->traverse<void *, fold_mem_refs> (NULL);
>
>    /* Dump the translated tree function.  */
>    if (dump_file)
> @@ -2933,7 +2933,7 @@ free_nesting_tree (struct nesting_info *root)
>        next = iter_nestinfo_next (node);
>        pointer_map_destroy (node->var_map);
>        pointer_map_destroy (node->field_map);
> -      pointer_set_destroy (node->mem_refs);
> +      delete node->mem_refs;
>        free (node);
>        node = next;
>      }
> diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
> index ca6e014..aee0331 100644
> --- a/gcc/tree-pretty-print.c
> +++ b/gcc/tree-pretty-print.c
> @@ -27,7 +27,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "expr.h"
>  #include "tree-pretty-print.h"
>  #include "hashtab.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "gimple-expr.h"
>  #include "cgraph.h"
>  #include "langhooks.h"
> @@ -103,14 +103,14 @@ debug_generic_stmt (tree t)
>  DEBUG_FUNCTION void
>  debug_tree_chain (tree t)
>  {
> -  struct pointer_set_t *seen = pointer_set_create ();
> +  hash_set<tree> seen;
>
>    while (t)
>      {
>        print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID);
>        fprintf (stderr, " ");
>        t = TREE_CHAIN (t);
> -      if (pointer_set_insert (seen, t))
> +      if (seen.add (t))
>         {
>           fprintf (stderr, "... [cycled back to ");
>           print_generic_expr (stderr, t, TDF_VOPS|TDF_MEMSYMS|TDF_UID);
> @@ -119,8 +119,6 @@ debug_tree_chain (tree t)
>         }
>      }
>    fprintf (stderr, "\n");
> -
> -  pointer_set_destroy (seen);
>  }
>
>  /* Prints declaration DECL to the FILE with details specified by FLAGS.  */
> diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
> index 36d68a8..83c1b19 100644
> --- a/gcc/tree-ssa-loop-niter.c
> +++ b/gcc/tree-ssa-loop-niter.c
> @@ -28,6 +28,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "basic-block.h"
>  #include "gimple-pretty-print.h"
>  #include "intl.h"
> +#include "hash-set.h"
>  #include "pointer-set.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
> @@ -3281,7 +3282,7 @@ discover_iteration_bound_by_body_walk (struct loop *loop)
>  static void
>  maybe_lower_iteration_bound (struct loop *loop)
>  {
> -  pointer_set_t *not_executed_last_iteration = NULL;
> +  hash_set<gimple> *not_executed_last_iteration = NULL;
>    struct nb_iter_bound *elt;
>    bool found_exit = false;
>    vec<basic_block> queue = vNULL;
> @@ -3300,8 +3301,8 @@ maybe_lower_iteration_bound (struct loop *loop)
>           && wi::ltu_p (elt->bound, loop->nb_iterations_upper_bound))
>         {
>           if (!not_executed_last_iteration)
> -           not_executed_last_iteration = pointer_set_create ();
> -         pointer_set_insert (not_executed_last_iteration, elt->stmt);
> +           not_executed_last_iteration = new hash_set<gimple>;
> +         not_executed_last_iteration->add (elt->stmt);
>         }
>      }
>    if (!not_executed_last_iteration)
> @@ -3327,7 +3328,7 @@ maybe_lower_iteration_bound (struct loop *loop)
>        for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>         {
>           gimple stmt = gsi_stmt (gsi);
> -         if (pointer_set_contains (not_executed_last_iteration, stmt))
> +         if (not_executed_last_iteration->contains (stmt))
>             {
>               stmt_found = true;
>               break;
> @@ -3376,7 +3377,7 @@ maybe_lower_iteration_bound (struct loop *loop)
>      }
>    BITMAP_FREE (visited);
>    queue.release ();
> -  pointer_set_destroy (not_executed_last_iteration);
> +  delete not_executed_last_iteration;
>  }
>
>  /* Records estimates on numbers of iterations of LOOP.  If USE_UNDEFINED_P
> diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
> index 052d760..3185d9a 100644
> --- a/gcc/tree-ssa-phiopt.c
> +++ b/gcc/tree-ssa-phiopt.c
> @@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "flags.h"
>  #include "tm_p.h"
>  #include "basic-block.h"
> +#include "hash-set.h"
>  #include "pointer-set.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
> @@ -72,9 +73,9 @@ static bool abs_replacement (basic_block, basic_block,
>  static bool neg_replacement (basic_block, basic_block,
>                              edge, edge, gimple, tree, tree);
>  static bool cond_store_replacement (basic_block, basic_block, edge, edge,
> -                                   struct pointer_set_t *);
> +                                   hash_set<tree> *);
>  static bool cond_if_else_store_replacement (basic_block, basic_block, basic_block);
> -static struct pointer_set_t * get_non_trapping (void);
> +static hash_set<tree> * get_non_trapping ();
>  static void replace_phi_edge_with_variable (basic_block, edge, gimple, tree);
>  static void hoist_adjacent_loads (basic_block, basic_block,
>                                   basic_block, basic_block);
> @@ -176,7 +177,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads)
>    basic_block *bb_order;
>    unsigned n, i;
>    bool cfgchanged = false;
> -  struct pointer_set_t *nontrap = 0;
> +  hash_set<tree> *nontrap = 0;
>
>    if (do_store_elim)
>      /* Calculate the set of non-trapping memory accesses.  */
> @@ -363,7 +364,7 @@ tree_ssa_phiopt_worker (bool do_store_elim, bool do_hoist_loads)
>    free (bb_order);
>
>    if (do_store_elim)
> -    pointer_set_destroy (nontrap);
> +    delete nontrap;
>    /* If the CFG has changed, we should cleanup the CFG.  */
>    if (cfgchanged && do_store_elim)
>      {
> @@ -1469,7 +1470,7 @@ ssa_names_hasher::equal (const value_type *n1, const compare_type *n2)
>  class nontrapping_dom_walker : public dom_walker
>  {
>  public:
> -  nontrapping_dom_walker (cdi_direction direction, pointer_set_t *ps)
> +  nontrapping_dom_walker (cdi_direction direction, hash_set<tree> *ps)
>      : dom_walker (direction), m_nontrapping (ps), m_seen_ssa_names (128) {}
>
>    virtual void before_dom_children (basic_block);
> @@ -1484,7 +1485,7 @@ private:
>       the RHS.  */
>    void add_or_mark_expr (basic_block, tree, bool);
>
> -  pointer_set_t *m_nontrapping;
> +  hash_set<tree> *m_nontrapping;
>
>    /* The hash table for remembering what we've seen.  */
>    hash_table<ssa_names_hasher> m_seen_ssa_names;
> @@ -1572,7 +1573,7 @@ nontrapping_dom_walker::add_or_mark_expr (basic_block bb, tree exp, bool store)
>          then we can't trap.  */
>        if (found_bb && (((size_t)found_bb->aux) & 1) == 1)
>         {
> -         pointer_set_insert (m_nontrapping, exp);
> +         m_nontrapping->add (exp);
>         }
>        else
>          {
> @@ -1601,11 +1602,11 @@ nontrapping_dom_walker::add_or_mark_expr (basic_block bb, tree exp, bool store)
>     It will do a dominator walk over the whole function, and it will
>     make use of the bb->aux pointers.  It returns a set of trees
>     (the MEM_REFs itself) which can't trap.  */
> -static struct pointer_set_t *
> +static hash_set<tree> *
>  get_non_trapping (void)
>  {
>    nt_call_phase = 0;
> -  pointer_set_t *nontrap = pointer_set_create ();
> +  hash_set<tree> *nontrap = new hash_set<tree>;
>    /* We're going to do a dominator walk, so ensure that we have
>       dominance information.  */
>    calculate_dominance_info (CDI_DOMINATORS);
> @@ -1634,7 +1635,7 @@ get_non_trapping (void)
>
>  static bool
>  cond_store_replacement (basic_block middle_bb, basic_block join_bb,
> -                       edge e0, edge e1, struct pointer_set_t *nontrap)
> +                       edge e0, edge e1, hash_set<tree> *nontrap)
>  {
>    gimple assign = last_and_only_stmt (middle_bb);
>    tree lhs, rhs, name, name2;
> @@ -1659,7 +1660,7 @@ cond_store_replacement (basic_block middle_bb, basic_block join_bb,
>    /* Prove that we can move the store down.  We could also check
>       TREE_THIS_NOTRAP here, but in that case we also could move stores,
>       whose value is not available readily, which we want to avoid.  */
> -  if (!pointer_set_contains (nontrap, lhs))
> +  if (!nontrap->contains (lhs))
>      return false;
>
>    /* Now we've checked the constraints, so do the transformation:
> diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
> index 9807b42..3dee5ba 100644
> --- a/gcc/tree-ssa-threadedge.c
> +++ b/gcc/tree-ssa-threadedge.c
> @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "function.h"
>  #include "timevar.h"
>  #include "dumpfile.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
>  #include "gimple-expr.h"
> @@ -693,13 +693,13 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
>      }
>
>    auto_vec<tree, alloc_count> fewvars;
> -  pointer_set_t *vars = NULL;
> +  hash_set<tree> *vars = NULL;
>
>    /* If we're already starting with 3/4 of alloc_count, go for a
> -     pointer_set, otherwise start with an unordered stack-allocated
> +     hash_set, otherwise start with an unordered stack-allocated
>       VEC.  */
>    if (i * 4 > alloc_count * 3)
> -    vars = pointer_set_create ();
> +    vars = new hash_set<tree>;
>
>    /* Now go through the initial debug stmts in DEST again, this time
>       actually inserting in VARS or FEWVARS.  Don't bother checking for
> @@ -720,7 +720,7 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
>         gcc_unreachable ();
>
>        if (vars)
> -       pointer_set_insert (vars, var);
> +       vars->add (var);
>        else
>         fewvars.quick_push (var);
>      }
> @@ -754,7 +754,7 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
>              or somesuch.  Adding `&& bb == src' to the condition
>              below will preserve all potentially relevant debug
>              notes.  */
> -         if (vars && pointer_set_insert (vars, var))
> +         if (vars && vars->add (var))
>             continue;
>           else if (!vars)
>             {
> @@ -769,11 +769,11 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
>                 fewvars.quick_push (var);
>               else
>                 {
> -                 vars = pointer_set_create ();
> +                 vars = new hash_set<tree>;
>                   for (i = 0; i < alloc_count; i++)
> -                   pointer_set_insert (vars, fewvars[i]);
> +                   vars->add (fewvars[i]);
>                   fewvars.release ();
> -                 pointer_set_insert (vars, var);
> +                 vars->add (var);
>                 }
>             }
>
> @@ -786,7 +786,7 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
>    while (bb != src && single_pred_p (bb));
>
>    if (vars)
> -    pointer_set_destroy (vars);
> +    delete vars;
>    else if (fewvars.exists ())
>      fewvars.release ();
>  }
> diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
> index 64259fb..f2578b7 100644
> --- a/gcc/tree-ssa-uninit.c
> +++ b/gcc/tree-ssa-uninit.c
> @@ -29,6 +29,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "function.h"
>  #include "gimple-pretty-print.h"
>  #include "bitmap.h"
> +#include "hash-set.h"
>  #include "pointer-set.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
> @@ -60,7 +61,7 @@ along with GCC; see the file COPYING3.  If not see
>  /* Pointer set of potentially undefined ssa names, i.e.,
>     ssa names that are defined by phi with operands that
>     are not defined or potentially undefined.  */
> -static pointer_set_t *possibly_undefined_names = 0;
> +static hash_set<tree> *possibly_undefined_names = 0;
>
>  /* Bit mask handling macros.  */
>  #define MASK_SET_BIT(mask, pos) mask |= (1 << pos)
> @@ -89,7 +90,7 @@ has_undefined_value_p (tree t)
>  {
>    return (ssa_undefined_value_p (t)
>            || (possibly_undefined_names
> -              && pointer_set_contains (possibly_undefined_names, t)));
> +              && possibly_undefined_names->contains (t)));
>  }
>
>
> @@ -648,13 +649,13 @@ find_predicates (pred_chain_union *preds,
>  static void
>  collect_phi_def_edges (gimple phi, basic_block cd_root,
>                         vec<edge> *edges,
> -                       pointer_set_t *visited_phis)
> +                       hash_set<gimple> *visited_phis)
>  {
>    size_t i, n;
>    edge opnd_edge;
>    tree opnd;
>
> -  if (pointer_set_insert (visited_phis, phi))
> +  if (visited_phis->add (phi))
>      return;
>
>    n = gimple_phi_num_args (phi);
> @@ -707,7 +708,6 @@ find_def_preds (pred_chain_union *preds, gimple phi)
>    vec<edge> def_edges = vNULL;
>    bool has_valid_pred = false;
>    basic_block phi_bb, cd_root = 0;
> -  pointer_set_t *visited_phis;
>
>    phi_bb = gimple_bb (phi);
>    /* First find the closest dominating bb to be
> @@ -716,9 +716,8 @@ find_def_preds (pred_chain_union *preds, gimple phi)
>    if (!cd_root)
>      return false;
>
> -  visited_phis = pointer_set_create ();
> -  collect_phi_def_edges (phi, cd_root, &def_edges, visited_phis);
> -  pointer_set_destroy (visited_phis);
> +  hash_set<gimple> visited_phis;
> +  collect_phi_def_edges (phi, cd_root, &def_edges, &visited_phis);
>
>    n = def_edges.length ();
>    if (n == 0)
> @@ -941,7 +940,7 @@ is_use_properly_guarded (gimple use_stmt,
>                           basic_block use_bb,
>                           gimple phi,
>                           unsigned uninit_opnds,
> -                         pointer_set_t *visited_phis);
> +                         hash_set<gimple> *visited_phis);
>
>  /* Returns true if all uninitialized opnds are pruned. Returns false
>     otherwise. PHI is the phi node with uninitialized operands,
> @@ -983,7 +982,7 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gimple phi,
>                                               gimple flag_def,
>                                               tree boundary_cst,
>                                               enum tree_code cmp_code,
> -                                             pointer_set_t *visited_phis,
> +                                             hash_set<gimple> *visited_phis,
>                                               bitmap *visited_flag_phis)
>  {
>    unsigned i;
> @@ -1153,7 +1152,7 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gimple phi,
>  static bool
>  use_pred_not_overlap_with_undef_path_pred (pred_chain_union preds,
>                                            gimple phi, unsigned uninit_opnds,
> -                                          pointer_set_t *visited_phis)
> +                                          hash_set<gimple> *visited_phis)
>  {
>    unsigned int i, n;
>    gimple flag_def = 0;
> @@ -1818,11 +1817,11 @@ push_pred (pred_chain_union *norm_preds, pred_info pred)
>
>  inline static void
>  push_to_worklist (tree op, vec<pred_info, va_heap, vl_ptr> *work_list,
> -                  pointer_set_t *mark_set)
> +                  hash_set<tree> *mark_set)
>  {
> -  if (pointer_set_contains (mark_set, op))
> +  if (mark_set->contains (op))
>      return;
> -  pointer_set_insert (mark_set, op);
> +  mark_set->add (op);
>
>    pred_info arg_pred;
>    arg_pred.pred_lhs = op;
> @@ -1907,7 +1906,7 @@ normalize_one_pred_1 (pred_chain_union *norm_preds,
>                        pred_info pred,
>                        enum tree_code and_or_code,
>                        vec<pred_info, va_heap, vl_ptr> *work_list,
> -                     pointer_set_t *mark_set)
> +                     hash_set<tree> *mark_set)
>  {
>    if (!is_neq_zero_form_p (pred))
>      {
> @@ -1987,7 +1986,6 @@ normalize_one_pred (pred_chain_union *norm_preds,
>                      pred_info pred)
>  {
>    vec<pred_info, va_heap, vl_ptr> work_list = vNULL;
> -  pointer_set_t *mark_set = NULL;
>    enum tree_code and_or_code = ERROR_MARK;
>    pred_chain norm_chain = vNULL;
>
> @@ -2015,19 +2013,18 @@ normalize_one_pred (pred_chain_union *norm_preds,
>      }
>
>    work_list.safe_push (pred);
> -  mark_set = pointer_set_create ();
> +  hash_set<tree> mark_set;
>
>    while (!work_list.is_empty ())
>      {
>        pred_info a_pred = work_list.pop ();
>        normalize_one_pred_1 (norm_preds, &norm_chain, a_pred,
> -                            and_or_code, &work_list, mark_set);
> +                            and_or_code, &work_list, &mark_set);
>      }
>    if (and_or_code == BIT_AND_EXPR)
>      norm_preds->safe_push (norm_chain);
>
>    work_list.release ();
> -  pointer_set_destroy (mark_set);
>  }
>
>  static void
> @@ -2035,26 +2032,25 @@ normalize_one_pred_chain (pred_chain_union *norm_preds,
>                            pred_chain one_chain)
>  {
>    vec<pred_info, va_heap, vl_ptr> work_list = vNULL;
> -  pointer_set_t *mark_set = pointer_set_create ();
> +  hash_set<tree> mark_set;
>    pred_chain norm_chain = vNULL;
>    size_t i;
>
>    for (i = 0; i < one_chain.length (); i++)
>      {
>        work_list.safe_push (one_chain[i]);
> -      pointer_set_insert (mark_set, one_chain[i].pred_lhs);
> +      mark_set.add (one_chain[i].pred_lhs);
>      }
>
>    while (!work_list.is_empty ())
>      {
>        pred_info a_pred = work_list.pop ();
>        normalize_one_pred_1 (0, &norm_chain, a_pred,
> -                            BIT_AND_EXPR, &work_list, mark_set);
> +                            BIT_AND_EXPR, &work_list, &mark_set);
>      }
>
>    norm_preds->safe_push (norm_chain);
>    work_list.release ();
> -  pointer_set_destroy (mark_set);
>  }
>
>  /* Normalize predicate chains PREDS and returns the normalized one.  */
> @@ -2112,7 +2108,7 @@ is_use_properly_guarded (gimple use_stmt,
>                           basic_block use_bb,
>                           gimple phi,
>                           unsigned uninit_opnds,
> -                         pointer_set_t *visited_phis)
> +                         hash_set<gimple> *visited_phis)
>  {
>    basic_block phi_bb;
>    pred_chain_union preds = vNULL;
> @@ -2120,7 +2116,7 @@ is_use_properly_guarded (gimple use_stmt,
>    bool has_valid_preds = false;
>    bool is_properly_guarded = false;
>
> -  if (pointer_set_insert (visited_phis, phi))
> +  if (visited_phis->add (phi))
>      return false;
>
>    phi_bb = gimple_bb (phi);
> @@ -2181,7 +2177,7 @@ is_use_properly_guarded (gimple use_stmt,
>  static gimple
>  find_uninit_use (gimple phi, unsigned uninit_opnds,
>                   vec<gimple> *worklist,
> -                pointer_set_t *added_to_worklist)
> +                hash_set<gimple> *added_to_worklist)
>  {
>    tree phi_result;
>    use_operand_p use_p;
> @@ -2192,28 +2188,22 @@ find_uninit_use (gimple phi, unsigned uninit_opnds,
>
>    FOR_EACH_IMM_USE_FAST (use_p, iter, phi_result)
>      {
> -      pointer_set_t *visited_phis;
>        basic_block use_bb;
>
>        use_stmt = USE_STMT (use_p);
>        if (is_gimple_debug (use_stmt))
>         continue;
>
> -      visited_phis = pointer_set_create ();
> -
>        if (gimple_code (use_stmt) == GIMPLE_PHI)
>         use_bb = gimple_phi_arg_edge (use_stmt,
>                                       PHI_ARG_INDEX_FROM_USE (use_p))->src;
>        else
>         use_bb = gimple_bb (use_stmt);
>
> +      hash_set<gimple> visited_phis;
>        if (is_use_properly_guarded (use_stmt, use_bb, phi, uninit_opnds,
> -                                   visited_phis))
> -        {
> -          pointer_set_destroy (visited_phis);
> -          continue;
> -        }
> -      pointer_set_destroy (visited_phis);
> +                                   &visited_phis))
> +       continue;
>
>        if (dump_file && (dump_flags & TDF_DETAILS))
>          {
> @@ -2226,7 +2216,7 @@ find_uninit_use (gimple phi, unsigned uninit_opnds,
>
>        /* Found a phi use that is not guarded,
>           add the phi to the worklist.  */
> -      if (!pointer_set_insert (added_to_worklist, use_stmt))
> +      if (!added_to_worklist->add (use_stmt))
>          {
>            if (dump_file && (dump_flags & TDF_DETAILS))
>              {
> @@ -2235,7 +2225,7 @@ find_uninit_use (gimple phi, unsigned uninit_opnds,
>              }
>
>            worklist->safe_push (use_stmt);
> -          pointer_set_insert (possibly_undefined_names, phi_result);
> +          possibly_undefined_names->add (phi_result);
>          }
>      }
>
> @@ -2252,7 +2242,7 @@ find_uninit_use (gimple phi, unsigned uninit_opnds,
>
>  static void
>  warn_uninitialized_phi (gimple phi, vec<gimple> *worklist,
> -                        pointer_set_t *added_to_worklist)
> +                        hash_set<gimple> *added_to_worklist)
>  {
>    unsigned uninit_opnds;
>    gimple uninit_use_stmt = 0;
> @@ -2339,7 +2329,6 @@ pass_late_warn_uninitialized::execute (function *fun)
>    basic_block bb;
>    gimple_stmt_iterator gsi;
>    vec<gimple> worklist = vNULL;
> -  pointer_set_t *added_to_worklist;
>
>    calculate_dominance_info (CDI_DOMINATORS);
>    calculate_dominance_info (CDI_POST_DOMINATORS);
> @@ -2350,8 +2339,8 @@ pass_late_warn_uninitialized::execute (function *fun)
>
>    timevar_push (TV_TREE_UNINIT);
>
> -  possibly_undefined_names = pointer_set_create ();
> -  added_to_worklist = pointer_set_create ();
> +  possibly_undefined_names = new hash_set<tree>;
> +  hash_set<gimple> added_to_worklist;
>
>    /* Initialize worklist  */
>    FOR_EACH_BB_FN (bb, fun)
> @@ -2373,7 +2362,7 @@ pass_late_warn_uninitialized::execute (function *fun)
>                 && uninit_undefined_value_p (op))
>               {
>                 worklist.safe_push (phi);
> -               pointer_set_insert (added_to_worklist, phi);
> +               added_to_worklist.add (phi);
>                 if (dump_file && (dump_flags & TDF_DETAILS))
>                   {
>                     fprintf (dump_file, "[WORKLIST]: add to initial list: ");
> @@ -2388,12 +2377,11 @@ pass_late_warn_uninitialized::execute (function *fun)
>      {
>        gimple cur_phi = 0;
>        cur_phi = worklist.pop ();
> -      warn_uninitialized_phi (cur_phi, &worklist, added_to_worklist);
> +      warn_uninitialized_phi (cur_phi, &worklist, &added_to_worklist);
>      }
>
>    worklist.release ();
> -  pointer_set_destroy (added_to_worklist);
> -  pointer_set_destroy (possibly_undefined_names);
> +  delete possibly_undefined_names;
>    possibly_undefined_names = NULL;
>    free_dominance_info (CDI_POST_DOMINATORS);
>    timevar_pop (TV_TREE_UNINIT);
> diff --git a/gcc/tree.c b/gcc/tree.c
> index 6669a84..de1c9b6 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -5143,7 +5143,7 @@ struct free_lang_data_d
>    vec<tree> worklist;
>
>    /* Set of traversed objects.  Used to avoid duplicate visits.  */
> -  struct pointer_set_t *pset;
> +  hash_set<tree> *pset;
>
>    /* Array of symbols to process with free_lang_data_in_decl.  */
>    vec<tree> decls;
> @@ -5208,7 +5208,7 @@ add_tree_to_fld_list (tree t, struct free_lang_data_d *fld)
>  static inline void
>  fld_worklist_push (tree t, struct free_lang_data_d *fld)
>  {
> -  if (t && !is_lang_specific (t) && !pointer_set_contains (fld->pset, t))
> +  if (t && !is_lang_specific (t) && !fld->pset->contains (t))
>      fld->worklist.safe_push ((t));
>  }
>
> @@ -5374,7 +5374,7 @@ find_decls_types (tree t, struct free_lang_data_d *fld)
>  {
>    while (1)
>      {
> -      if (!pointer_set_contains (fld->pset, t))
> +      if (!fld->pset->contains (t))
>         walk_tree (&t, find_decls_types_r, fld, fld->pset);
>        if (fld->worklist.is_empty ())
>         break;
> @@ -5584,7 +5584,7 @@ free_lang_data_in_cgraph (void)
>    alias_pair *p;
>
>    /* Initialize sets and arrays to store referenced decls and types.  */
> -  fld.pset = pointer_set_create ();
> +  fld.pset = new hash_set<tree>;
>    fld.worklist.create (0);
>    fld.decls.create (100);
>    fld.types.create (100);
> @@ -5614,7 +5614,7 @@ free_lang_data_in_cgraph (void)
>    FOR_EACH_VEC_ELT (fld.types, i, t)
>      free_lang_data_in_type (t);
>
> -  pointer_set_destroy (fld.pset);
> +  delete fld.pset;
>    fld.worklist.release ();
>    fld.decls.release ();
>    fld.types.release ();
> @@ -10819,7 +10819,7 @@ num_ending_zeros (const_tree x)
>
>  static tree
>  walk_type_fields (tree type, walk_tree_fn func, void *data,
> -                 struct pointer_set_t *pset, walk_tree_lh lh)
> +                 hash_set<tree> *pset, walk_tree_lh lh)
>  {
>    tree result = NULL_TREE;
>
> @@ -10901,7 +10901,7 @@ walk_type_fields (tree type, walk_tree_fn func, void *data,
>
>  tree
>  walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
> -            struct pointer_set_t *pset, walk_tree_lh lh)
> +            hash_set<tree> *pset, walk_tree_lh lh)
>  {
>    enum tree_code code;
>    int walk_subtrees;
> @@ -10922,7 +10922,7 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
>
>    /* Don't walk the same tree twice, if the user has requested
>       that we avoid doing so.  */
> -  if (pset && pointer_set_insert (pset, *tp))
> +  if (pset && pset->add (*tp))
>      return NULL_TREE;
>
>    /* Call the function.  */
> @@ -11237,11 +11237,9 @@ walk_tree_without_duplicates_1 (tree *tp, walk_tree_fn func, void *data,
>                                 walk_tree_lh lh)
>  {
>    tree result;
> -  struct pointer_set_t *pset;
>
> -  pset = pointer_set_create ();
> -  result = walk_tree_1 (tp, func, data, pset, lh);
> -  pointer_set_destroy (pset);
> +  hash_set<tree> pset;
> +  result = walk_tree_1 (tp, func, data, &pset, lh);
>    return result;
>  }
>
> diff --git a/gcc/tree.h b/gcc/tree.h
> index 2bb6d1f..c9f978a 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
>  #define GCC_TREE_H
>
>  #include "tree-core.h"
> +#include "hash-set.h"
>  #include "wide-int.h"
>  #include "inchash.h"
>
> @@ -4328,7 +4329,7 @@ extern void using_eh_for_cleanups (void);
>  extern bool using_eh_for_cleanups_p (void);
>  extern const char *get_tree_code_name (enum tree_code);
>  extern void set_call_expr_flags (tree, int);
> -extern tree walk_tree_1 (tree*, walk_tree_fn, void*, struct pointer_set_t*,
> +extern tree walk_tree_1 (tree*, walk_tree_fn, void*, hash_set<tree>*,
>                          walk_tree_lh);
>  extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*,
>                                             walk_tree_lh);
> diff --git a/gcc/value-prof.c b/gcc/value-prof.c
> index 3e51539..ffdee65 100644
> --- a/gcc/value-prof.c
> +++ b/gcc/value-prof.c
> @@ -59,6 +59,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "data-streamer.h"
>  #include "builtins.h"
>  #include "tree-nested.h"
> +#include "hash-set.h"
>
>  /* In this file value profile based optimizations are placed.  Currently the
>     following optimizations are implemented (for more detailed descriptions
> @@ -515,10 +516,10 @@ static bool error_found = false;
>  static int
>  visit_hist (void **slot, void *data)
>  {
> -  struct pointer_set_t *visited = (struct pointer_set_t *) data;
> +  hash_set<histogram_value> *visited = (hash_set<histogram_value> *) data;
>    histogram_value hist = *(histogram_value *) slot;
>
> -  if (!pointer_set_contains (visited, hist)
> +  if (!visited->contains (hist)
>        && hist->type != HIST_TYPE_TIME_PROFILE)
>      {
>        error ("dead histogram");
> @@ -538,10 +539,9 @@ verify_histograms (void)
>    basic_block bb;
>    gimple_stmt_iterator gsi;
>    histogram_value hist;
> -  struct pointer_set_t *visited_hists;
>
>    error_found = false;
> -  visited_hists = pointer_set_create ();
> +  hash_set<histogram_value> visited_hists;
>    FOR_EACH_BB_FN (bb, cfun)
>      for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
>        {
> @@ -558,12 +558,11 @@ verify_histograms (void)
>                 dump_histogram_value (stderr, hist);
>                 error_found = true;
>               }
> -            pointer_set_insert (visited_hists, hist);
> +            visited_hists.add (hist);
>           }
>        }
>    if (VALUE_HISTOGRAMS (cfun))
> -    htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, visited_hists);
> -  pointer_set_destroy (visited_hists);
> +    htab_traverse (VALUE_HISTOGRAMS (cfun), visit_hist, &visited_hists);
>    if (error_found)
>      internal_error ("verify_histograms failed");
>  }
> diff --git a/gcc/varasm.c b/gcc/varasm.c
> index 819ec26..9d8602b 100644
> --- a/gcc/varasm.c
> +++ b/gcc/varasm.c
> @@ -51,7 +51,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "common/common-target.h"
>  #include "targhooks.h"
>  #include "cgraph.h"
> -#include "pointer-set.h"
> +#include "hash-set.h"
>  #include "asan.h"
>  #include "basic-block.h"
>
> @@ -2249,7 +2249,7 @@ static bool pending_assemble_externals_processed;
>
>  /* Avoid O(external_decls**2) lookups in the pending_assemble_externals
>     TREE_LIST in assemble_external.  */
> -static struct pointer_set_t *pending_assemble_externals_set;
> +static hash_set<tree> *pending_assemble_externals_set;
>
>  /* True if DECL is a function decl for which no out-of-line copy exists.
>     It is assumed that DECL's assembler name has been set.  */
> @@ -2303,7 +2303,7 @@ process_pending_assemble_externals (void)
>
>    pending_assemble_externals = 0;
>    pending_assemble_externals_processed = true;
> -  pointer_set_destroy (pending_assemble_externals_set);
> +  delete pending_assemble_externals_set;
>  #endif
>  }
>
> @@ -2361,7 +2361,7 @@ assemble_external (tree decl ATTRIBUTE_UNUSED)
>        return;
>      }
>
> -  if (! pointer_set_insert (pending_assemble_externals_set, decl))
> +  if (! pending_assemble_externals_set->add (decl))
>      pending_assemble_externals = tree_cons (NULL, decl,
>                                             pending_assemble_externals);
>  #endif
> @@ -5991,7 +5991,7 @@ init_varasm_once (void)
>      readonly_data_section = text_section;
>
>  #ifdef ASM_OUTPUT_EXTERNAL
> -  pending_assemble_externals_set = pointer_set_create ();
> +  pending_assemble_externals_set = new hash_set<tree>;
>  #endif
>  }
>
> diff --git a/gcc/varpool.c b/gcc/varpool.c
> index 74117e2..558767f 100644
> --- a/gcc/varpool.c
> +++ b/gcc/varpool.c
> @@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree-ssa-alias.h"
>  #include "gimple.h"
>  #include "lto-streamer.h"
> +#include "hash-set.h"
>
>  const char * const tls_model_names[]={"none", "tls-emulated", "tls-real",
>                                       "tls-global-dynamic", "tls-local-dynamic",
> @@ -576,7 +577,7 @@ varpool_remove_unreferenced_decls (void)
>    varpool_node *first = (varpool_node *)(void *)1;
>    int i;
>    struct ipa_ref *ref = NULL;
> -  struct pointer_set_t *referenced = pointer_set_create ();
> +  hash_set<varpool_node *> referenced;
>
>    if (seen_error ())
>      return;
> @@ -623,7 +624,7 @@ varpool_remove_unreferenced_decls (void)
>               && vnode->analyzed)
>             enqueue_node (vnode, &first);
>           else
> -           pointer_set_insert (referenced, node);
> +           referenced.add (node);
>         }
>      }
>    if (cgraph_dump_file)
> @@ -635,13 +636,13 @@ varpool_remove_unreferenced_decls (void)
>         {
>            if (cgraph_dump_file)
>             fprintf (cgraph_dump_file, " %s", node->asm_name ());
> -         if (pointer_set_contains (referenced, node))
> +         if (referenced.contains (node))
>             node->remove_initializer ();
>           else
>             node->remove ();
>         }
>      }
> -  pointer_set_destroy (referenced);
> +
>    if (cgraph_dump_file)
>      fprintf (cgraph_dump_file, "\n");
>  }
> --
> 2.0.1
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]