diff mbox

convert many pointer_map to hash_map

Message ID 1406889295-22653-1-git-send-email-tsaunders@mozilla.com
State New
Headers show

Commit Message

Trevor Saunders Aug. 1, 2014, 10:34 a.m. UTC
From: Trevor Saunders <tsaunders@mozilla.com>

Hi,

This patch replaces a bunch of usage of pointer_map with hash_map.  It also
adds an overload to hash_map::traverse that allows modifying the value, and a
remove method.

bootstrapped + regtested on x86_64-unknown-linux-gnu, ok?

Trev

c-family/

	* cilk.c: Use hash_map instead of pointer_map.

c/

	* c-typeck.c: Use hash_map instead of pointer_map.

cp/

	* optimize.c, semantics.c: Use hash_map instead of pointer_map.

gcc/

	* hash-map.h (default_hashmap_traits::mark_key_deleted):
	Fix cast.
	(hash_map::remove): New method.
(hash_map::traverse): New method.
	* cgraph.h, except.c, except.h, gimple-ssa-strength-reduction.c,
	ipa-utils.c, lto-cgraph.c, lto-streamer.h, omp-low.c, predict.c,
	tree-cfg.c, tree-cfgcleanup.c, tree-eh.c, tree-eh.h, tree-inline.c,
	tree-inline.h, tree-nested.c, tree-sra.c, tree-ssa-loop-im.c,
	tree-ssa-loop-ivopts.c, tree-ssa-reassoc.c, tree-ssa-structalias.c,
	tree-ssa.c, tree-ssa.h, var-tracking.c: Use hash_map instead of
 pointer_map.

Comments

Richard Biener Aug. 1, 2014, 10:52 a.m. UTC | #1
On Fri, Aug 1, 2014 at 12:34 PM,  <tsaunders@mozilla.com> wrote:
> From: Trevor Saunders <tsaunders@mozilla.com>
>
> Hi,
>
> This patch replaces a bunch of usage of pointer_map with hash_map.  It also
> adds an overload to hash_map::traverse that allows modifying the value, and a
> remove method.
>
> bootstrapped + regtested on x86_64-unknown-linux-gnu, ok?

Ok.

Thanks,
Richard.

> Trev
>
> c-family/
>
>         * cilk.c: Use hash_map instead of pointer_map.
>
> c/
>
>         * c-typeck.c: Use hash_map instead of pointer_map.
>
> cp/
>
>         * optimize.c, semantics.c: Use hash_map instead of pointer_map.
>
> gcc/
>
>         * hash-map.h (default_hashmap_traits::mark_key_deleted):
>         Fix cast.
>         (hash_map::remove): New method.
> (hash_map::traverse): New method.
>         * cgraph.h, except.c, except.h, gimple-ssa-strength-reduction.c,
>         ipa-utils.c, lto-cgraph.c, lto-streamer.h, omp-low.c, predict.c,
>         tree-cfg.c, tree-cfgcleanup.c, tree-eh.c, tree-eh.h, tree-inline.c,
>         tree-inline.h, tree-nested.c, tree-sra.c, tree-ssa-loop-im.c,
>         tree-ssa-loop-ivopts.c, tree-ssa-reassoc.c, tree-ssa-structalias.c,
>         tree-ssa.c, tree-ssa.h, var-tracking.c: Use hash_map instead of
>  pointer_map.
> diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
> index b864bb1..e0d1141 100644
> --- a/gcc/c-family/cilk.c
> +++ b/gcc/c-family/cilk.c
> @@ -64,7 +64,7 @@ struct wrapper_data
>    /* Containing function.  */
>    tree context;
>    /* Disposition of all variables in the inner statement.  */
> -  struct pointer_map_t *decl_map;
> +  hash_map<tree, tree> *decl_map;
>    /* True if this function needs a static chain.  */
>    bool nested;
>    /* Arguments to be passed to wrapper function, currently a list.  */
> @@ -335,12 +335,11 @@ create_cilk_helper_decl (struct wrapper_data *wd)
>
>  /* A function used by walk tree to find wrapper parms.  */
>
> -static bool
> -wrapper_parm_cb (const void *key0, void **val0, void *data)
> +bool
> +wrapper_parm_cb (tree const &key0, tree *val0, wrapper_data *wd)
>  {
> -  struct wrapper_data *wd = (struct wrapper_data *) data;
> -  tree arg = * (tree *)&key0;
> -  tree val = (tree)*val0;
> +  tree arg = key0;
> +  tree val = *val0;
>    tree parm;
>
>    if (val == error_mark_node || val == arg)
> @@ -387,7 +386,7 @@ build_wrapper_type (struct wrapper_data *wd)
>    wd->parms = NULL_TREE;
>    wd->argtypes = void_list_node;
>
> -  pointer_map_traverse (wd->decl_map, wrapper_parm_cb, wd);
> +  wd->decl_map->traverse<wrapper_data *, wrapper_parm_cb> (wd);
>    gcc_assert (wd->type != CILK_BLOCK_FOR);
>
>    /* Now build a function.
> @@ -452,25 +451,22 @@ copy_decl_for_cilk (tree decl, copy_body_data *id)
>
>  /* Copy all local variables.  */
>
> -static bool
> -for_local_cb (const void *k_v, void **vp, void *p)
> +bool
> +for_local_cb (tree const &k, tree *vp, copy_body_data *id)
>  {
> -  tree k = *(tree *) &k_v;
> -  tree v = (tree) *vp;
> +  tree v = *vp;
>
>    if (v == error_mark_node)
> -    *vp = copy_decl_no_change (k, (copy_body_data *) p);
> +    *vp = copy_decl_no_change (k, id);
>    return true;
>  }
>
>  /* Copy all local declarations from a _Cilk_spawned function's body.  */
>
> -static bool
> -wrapper_local_cb (const void *k_v, void **vp, void *data)
> +bool
> +wrapper_local_cb (tree const &key, tree *vp, copy_body_data *id)
>  {
> -  copy_body_data *id = (copy_body_data *) data;
> -  tree key = *(tree *) &k_v;
> -  tree val = (tree) *vp;
> +  tree val = *vp;
>
>    if (val == error_mark_node)
>      *vp = copy_decl_for_cilk (key, id);
> @@ -514,8 +510,11 @@ cilk_outline (tree inner_fn, tree *stmt_p, void *w)
>    insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn));
>
>    /* We don't want the private variables any more.  */
> -  pointer_map_traverse (wd->decl_map, nested ? for_local_cb : wrapper_local_cb,
> -                       &id);
> +  if (nested)
> +    wd->decl_map->traverse<copy_body_data *, for_local_cb> (&id);
> +  else
> +    wd->decl_map->traverse<copy_body_data *, wrapper_local_cb> (&id);
> +
>    walk_tree (stmt_p, copy_tree_body_r, (void *) &id, NULL);
>
>    /* See if this function can throw or calls something that should
> @@ -576,7 +575,7 @@ init_wd (struct wrapper_data *wd, enum cilk_block_type type)
>    wd->type = type;
>    wd->fntype = NULL_TREE;
>    wd->context = current_function_decl;
> -  wd->decl_map = pointer_map_create ();
> +  wd->decl_map = new hash_map<tree, tree>;
>    /* _Cilk_for bodies are always nested.  Others start off as
>       normal functions.  */
>    wd->nested = (type == CILK_BLOCK_FOR);
> @@ -590,7 +589,7 @@ init_wd (struct wrapper_data *wd, enum cilk_block_type type)
>  static void
>  free_wd (struct wrapper_data *wd)
>  {
> -  pointer_map_destroy (wd->decl_map);
> +  delete wd->decl_map;
>    wd->nested = false;
>    wd->arglist = NULL_TREE;
>    wd->argtypes = NULL_TREE;
> @@ -618,12 +617,11 @@ free_wd (struct wrapper_data *wd)
>     (var, ???) -- Pure output argument, handled similarly to above.
>  */
>
> -static bool
> -declare_one_free_variable (const void *var0, void **map0,
> -                          void *data ATTRIBUTE_UNUSED)
> +bool
> +declare_one_free_variable (tree const &var0, tree *map0, wrapper_data &)
>  {
> -  const_tree var = (const_tree) var0;
> -  tree map = (tree)*map0;
> +  const_tree var = var0;
> +  tree map = *map0;
>    tree var_type = TREE_TYPE (var), arg_type;
>    bool by_reference;
>    tree parm;
> @@ -713,7 +711,7 @@ create_cilk_wrapper (tree exp, tree *args_out)
>      }
>    else
>      extract_free_variables (exp, &wd, ADD_READ);
> -  pointer_map_traverse (wd.decl_map, declare_one_free_variable, &wd);
> +  wd.decl_map->traverse<wrapper_data &, declare_one_free_variable> (wd);
>    wd.block = TREE_BLOCK (exp);
>    if (!wd.block)
>      wd.block = DECL_INITIAL (current_function_decl);
> @@ -884,9 +882,7 @@ cilk_install_body_pedigree_operations (tree frame_ptr)
>  static void
>  add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
>  {
> -  void **valp;
> -
> -  valp = pointer_map_contains (wd->decl_map, (void *) var);
> +  tree *valp = wd->decl_map->get (var);
>    if (valp)
>      {
>        tree val = (tree) *valp;
> @@ -907,7 +903,7 @@ add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
>        if (how != ADD_WRITE)
>         return;
>        /* This variable might have been entered as read but is now written.  */
> -      *valp = (void *) var;
> +      *valp = var;
>        wd->nested = true;
>        return;
>      }
> @@ -971,7 +967,7 @@ add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
>               break;
>             }
>         }
> -      *pointer_map_insert (wd->decl_map, (void *) var) = val;
> +      wd->decl_map->put (var, val);
>      }
>  }
>
> diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> index 06fd565..bedb63e 100644
> --- a/gcc/c/c-typeck.c
> +++ b/gcc/c/c-typeck.c
> @@ -11783,15 +11783,15 @@ c_clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
>                  tree decl, tree placeholder)
>  {
>    copy_body_data id;
> -  struct pointer_map_t *decl_map = pointer_map_create ();
> +  hash_map<tree, tree> decl_map;
>
> -  *pointer_map_insert (decl_map, omp_decl1) = placeholder;
> -  *pointer_map_insert (decl_map, omp_decl2) = decl;
> +  decl_map.put (omp_decl1, placeholder);
> +  decl_map.put (omp_decl2, decl);
>    memset (&id, 0, sizeof (id));
>    id.src_fn = DECL_CONTEXT (omp_decl1);
>    id.dst_fn = current_function_decl;
>    id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
> -  id.decl_map = decl_map;
> +  id.decl_map = &decl_map;
>
>    id.copy_decl = copy_decl_no_change;
>    id.transform_call_graph_edges = CB_CGE_DUPLICATE;
> @@ -11800,7 +11800,6 @@ c_clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
>    id.transform_lang_insert_block = NULL;
>    id.eh_lp_nr = 0;
>    walk_tree (&stmt, copy_tree_body_r, &id, NULL);
> -  pointer_map_destroy (decl_map);
>    return stmt;
>  }
>
> diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> index f8f76c4..0fa8635 100644
> --- a/gcc/cgraph.h
> +++ b/gcc/cgraph.h
> @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_CGRAPH_H
>  #define GCC_CGRAPH_H
>
> +#include "hash-map.h"
>  #include "is-a.h"
>  #include "plugin-api.h"
>  #include "vec.h"
> @@ -1204,7 +1205,7 @@ public:
>     can appear in multiple sets.  */
>  struct cgraph_node_set_def
>  {
> -  struct pointer_map_t *map;
> +  hash_map<cgraph_node *, size_t> *map;
>    vec<cgraph_node *> nodes;
>  };
>
> @@ -1217,7 +1218,7 @@ class varpool_node;
>     can appear in multiple sets.  */
>  struct varpool_node_set_def
>  {
> -  struct pointer_map_t * map;
> +  hash_map<varpool_node *, size_t> * map;
>    vec<varpool_node *> nodes;
>  };
>
> diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
> index 3cd8047..6eeca4d 100644
> --- a/gcc/cp/optimize.c
> +++ b/gcc/cp/optimize.c
> @@ -86,7 +86,7 @@ clone_body (tree clone, tree fn, void *arg_map)
>    id.src_fn = fn;
>    id.dst_fn = clone;
>    id.src_cfun = DECL_STRUCT_FUNCTION (fn);
> -  id.decl_map = (struct pointer_map_t *) arg_map;
> +  id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
>
>    id.copy_decl = copy_decl_no_change;
>    id.transform_call_graph_edges = CB_CGE_DUPLICATE;
> @@ -527,7 +527,7 @@ maybe_clone_body (tree fn)
>        tree parm;
>        tree clone_parm;
>        int parmno;
> -      struct pointer_map_t *decl_map;
> +      hash_map<tree, tree> *decl_map;
>        bool alias = false;
>
>        clone = fns[idx];
> @@ -587,7 +587,7 @@ maybe_clone_body (tree fn)
>             }
>
>            /* Remap the parameters.  */
> -          decl_map = pointer_map_create ();
> +          decl_map = new hash_map<tree, tree>;
>            for (parmno = 0,
>                  parm = DECL_ARGUMENTS (fn),
>                  clone_parm = DECL_ARGUMENTS (clone);
> @@ -600,7 +600,7 @@ maybe_clone_body (tree fn)
>                  {
>                    tree in_charge;
>                    in_charge = in_charge_arg_for_name (DECL_NAME (clone));
> -                  *pointer_map_insert (decl_map, parm) = in_charge;
> +                  decl_map->put (parm, in_charge);
>                  }
>                else if (DECL_ARTIFICIAL (parm)
>                         && DECL_NAME (parm) == vtt_parm_identifier)
> @@ -611,19 +611,22 @@ maybe_clone_body (tree fn)
>                    if (DECL_HAS_VTT_PARM_P (clone))
>                      {
>                        DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
> -                      *pointer_map_insert (decl_map, parm) = clone_parm;
> +                      decl_map->put (parm, clone_parm);
>                        clone_parm = DECL_CHAIN (clone_parm);
>                      }
>                    /* Otherwise, map the VTT parameter to `NULL'.  */
>                    else
> -                    *pointer_map_insert (decl_map, parm)
> -                       = fold_convert (TREE_TYPE (parm), null_pointer_node);
> +                   {
> +                     tree t
> +                       = fold_convert (TREE_TYPE (parm), null_pointer_node);
> +                     decl_map->put (parm, t);
> +                   }
>                  }
>                /* Map other parameters to their equivalents in the cloned
>                   function.  */
>                else
>                  {
> -                  *pointer_map_insert (decl_map, parm) = clone_parm;
> +                  decl_map->put (parm, clone_parm);
>                    clone_parm = DECL_CHAIN (clone_parm);
>                  }
>              }
> @@ -632,14 +635,14 @@ maybe_clone_body (tree fn)
>              {
>                parm = DECL_RESULT (fn);
>                clone_parm = DECL_RESULT (clone);
> -              *pointer_map_insert (decl_map, parm) = clone_parm;
> +              decl_map->put (parm, clone_parm);
>              }
>
>            /* Clone the body.  */
>            clone_body (clone, fn, decl_map);
>
>            /* Clean up.  */
> -          pointer_map_destroy (decl_map);
> +          delete decl_map;
>          }
>
>        /* The clone can throw iff the original function can throw.  */
> diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
> index 735284e..4868d69 100644
> --- a/gcc/cp/semantics.c
> +++ b/gcc/cp/semantics.c
> @@ -4977,15 +4977,15 @@ clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
>                tree decl, tree placeholder)
>  {
>    copy_body_data id;
> -  struct pointer_map_t *decl_map = pointer_map_create ();
> +  hash_map<tree, tree> decl_map;
>
> -  *pointer_map_insert (decl_map, omp_decl1) = placeholder;
> -  *pointer_map_insert (decl_map, omp_decl2) = decl;
> +  decl_map.put (omp_decl1, placeholder);
> +  decl_map.put (omp_decl2, decl);
>    memset (&id, 0, sizeof (id));
>    id.src_fn = DECL_CONTEXT (omp_decl1);
>    id.dst_fn = current_function_decl;
>    id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
> -  id.decl_map = decl_map;
> +  id.decl_map = &decl_map;
>
>    id.copy_decl = copy_decl_no_change;
>    id.transform_call_graph_edges = CB_CGE_DUPLICATE;
> @@ -4994,7 +4994,6 @@ clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
>    id.transform_lang_insert_block = NULL;
>    id.eh_lp_nr = 0;
>    walk_tree (&stmt, copy_tree_body_r, &id, NULL);
> -  pointer_map_destroy (decl_map);
>    return stmt;
>  }
>
> diff --git a/gcc/except.c b/gcc/except.c
> index c8dbc50..ec08e91 100644
> --- a/gcc/except.c
> +++ b/gcc/except.c
> @@ -527,7 +527,7 @@ struct duplicate_eh_regions_data
>  {
>    duplicate_eh_regions_map label_map;
>    void *label_map_data;
> -  struct pointer_map_t *eh_map;
> +  hash_map<void *, void *> *eh_map;
>  };
>
>  static void
> @@ -536,12 +536,9 @@ duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
>  {
>    eh_landing_pad old_lp, new_lp;
>    eh_region new_r;
> -  void **slot;
>
>    new_r = gen_eh_region (old_r->type, outer);
> -  slot = pointer_map_insert (data->eh_map, (void *)old_r);
> -  gcc_assert (*slot == NULL);
> -  *slot = (void *)new_r;
> +  gcc_assert (!data->eh_map->put (old_r, new_r));
>
>    switch (old_r->type)
>      {
> @@ -586,9 +583,7 @@ duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
>         continue;
>
>        new_lp = gen_eh_landing_pad (new_r);
> -      slot = pointer_map_insert (data->eh_map, (void *)old_lp);
> -      gcc_assert (*slot == NULL);
> -      *slot = (void *)new_lp;
> +      gcc_assert (!data->eh_map->put (old_lp, new_lp));
>
>        new_lp->post_landing_pad
>         = data->label_map (old_lp->post_landing_pad, data->label_map_data);
> @@ -609,7 +604,7 @@ duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
>     that allows the caller to remap uses of both EH regions and
>     EH landing pads.  */
>
> -struct pointer_map_t *
> +hash_map<void *, void *> *
>  duplicate_eh_regions (struct function *ifun,
>                       eh_region copy_region, int outer_lp,
>                       duplicate_eh_regions_map map, void *map_data)
> @@ -623,7 +618,7 @@ duplicate_eh_regions (struct function *ifun,
>
>    data.label_map = map;
>    data.label_map_data = map_data;
> -  data.eh_map = pointer_map_create ();
> +  data.eh_map = new hash_map<void *, void *>;
>
>    outer_region = get_eh_region_from_lp_number (outer_lp);
>
> diff --git a/gcc/except.h b/gcc/except.h
> index bab13e1..5c2aa3d 100644
> --- a/gcc/except.h
> +++ b/gcc/except.h
> @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
>  #  define GCC_EXCEPT_H
>  #endif
>
> +#include "hash-map.h"
>  #include "hashtab.h"
>
>  struct function;
> @@ -249,7 +250,7 @@ extern rtx expand_builtin_extend_pointer (tree);
>  extern void expand_dw2_landing_pad_for_region (eh_region);
>
>  typedef tree (*duplicate_eh_regions_map) (tree, void *);
> -extern struct pointer_map_t *duplicate_eh_regions
> +extern hash_map<void *, void *> *duplicate_eh_regions
>    (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
>
>  extern void sjlj_emit_function_exit_after (rtx);
> diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
> index d7c5db5..b13b7f7 100644
> --- a/gcc/gimple-ssa-strength-reduction.c
> +++ b/gcc/gimple-ssa-strength-reduction.c
> @@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "coretypes.h"
>  #include "tree.h"
>  #include "pointer-set.h"
> +#include "hash-map.h"
>  #include "hash-table.h"
>  #include "basic-block.h"
>  #include "tree-ssa-alias.h"
> @@ -373,7 +374,7 @@ enum count_phis_status
>  };
>
>  /* Pointer map embodying a mapping from statements to candidates.  */
> -static struct pointer_map_t *stmt_cand_map;
> +static hash_map<gimple, slsr_cand_t> *stmt_cand_map;
>
>  /* Obstack for candidates.  */
>  static struct obstack cand_obstack;
> @@ -435,7 +436,7 @@ static hash_table<cand_chain_hasher> *base_cand_map;
>  /* Pointer map used by tree_to_aff_combination_expand.  */
>  static struct pointer_map_t *name_expansions;
>  /* Pointer map embodying a mapping from bases to alternative bases.  */
> -static struct pointer_map_t *alt_base_map;
> +static hash_map<tree, tree> *alt_base_map;
>
>  /* Given BASE, use the tree affine combiniation facilities to
>     find the underlying tree expression for BASE, with any
> @@ -447,7 +448,7 @@ static struct pointer_map_t *alt_base_map;
>  static tree
>  get_alternative_base (tree base)
>  {
> -  tree *result = (tree *) pointer_map_contains (alt_base_map, base);
> +  tree *result = alt_base_map->get (base);
>
>    if (result == NULL)
>      {
> @@ -459,13 +460,9 @@ get_alternative_base (tree base)
>        aff.offset = 0;
>        expr = aff_combination_to_tree (&aff);
>
> -      result = (tree *) pointer_map_insert (alt_base_map, base);
> -      gcc_assert (!*result);
> +      gcc_assert (!alt_base_map->put (base, base == expr ? NULL : expr));
>
> -      if (expr == base)
> -       *result = NULL;
> -      else
> -       *result = expr;
> +      return expr == base ? NULL : expr;
>      }
>
>    return *result;
> @@ -724,7 +721,7 @@ base_cand_from_table (tree base_in)
>    if (!def)
>      return (slsr_cand_t) NULL;
>
> -  result = (slsr_cand_t *) pointer_map_contains (stmt_cand_map, def);
> +  result = stmt_cand_map->get (def);
>
>    if (result && (*result)->kind != CAND_REF)
>      return *result;
> @@ -737,9 +734,7 @@ base_cand_from_table (tree base_in)
>  static void
>  add_cand_for_stmt (gimple gs, slsr_cand_t c)
>  {
> -  void **slot = pointer_map_insert (stmt_cand_map, gs);
> -  gcc_assert (!*slot);
> -  *slot = c;
> +  gcc_assert (!stmt_cand_map->put (gs, c));
>  }
>
>  /* Given PHI which contains a phi statement, determine whether it
> @@ -3628,7 +3623,7 @@ pass_strength_reduction::execute (function *fun)
>    cand_vec.create (128);
>
>    /* Allocate the mapping from statements to candidate indices.  */
> -  stmt_cand_map = pointer_map_create ();
> +  stmt_cand_map = new hash_map<gimple, slsr_cand_t>;
>
>    /* Create the obstack where candidate chains will reside.  */
>    gcc_obstack_init (&chain_obstack);
> @@ -3637,7 +3632,7 @@ pass_strength_reduction::execute (function *fun)
>    base_cand_map = new hash_table<cand_chain_hasher> (500);
>
>    /* Allocate the mapping from bases to alternative bases.  */
> -  alt_base_map = pointer_map_create ();
> +  alt_base_map = new hash_map<tree, tree>;
>
>    /* Initialize the loop optimizer.  We need to detect flow across
>       back edges, and this gives us dominator information as well.  */
> @@ -3654,7 +3649,7 @@ pass_strength_reduction::execute (function *fun)
>        dump_cand_chains ();
>      }
>
> -  pointer_map_destroy (alt_base_map);
> +  delete alt_base_map;
>    free_affine_expand_cache (&name_expansions);
>
>    /* Analyze costs and make appropriate replacements.  */
> @@ -3664,7 +3659,7 @@ pass_strength_reduction::execute (function *fun)
>    delete base_cand_map;
>    base_cand_map = NULL;
>    obstack_free (&chain_obstack, NULL);
> -  pointer_map_destroy (stmt_cand_map);
> +  delete stmt_cand_map;
>    cand_vec.release ();
>    obstack_free (&cand_obstack, NULL);
>
> diff --git a/gcc/hash-map.h b/gcc/hash-map.h
> index 0b50f72..ec48844 100644
> --- a/gcc/hash-map.h
> +++ b/gcc/hash-map.h
> @@ -93,7 +93,7 @@ private:
>    static void
>    mark_key_deleted (T *&k)
>      {
> -      k = static_cast<T *> (1);
> +      k = reinterpret_cast<T *> (1);
>      }
>
>    template<typename T>
> @@ -185,6 +185,11 @@ public:
>        return e->m_value;
>      }
>
> +  void remove (const Key &k)
> +    {
> +      m_table.remove_elt_with_hash (k, Traits::hash (k));
> +    }
> +
>    /* Call the call back on each pair of key and value with the passed in
>       arg.  */
>
> @@ -196,6 +201,15 @@ public:
>         f ((*iter).m_key, (*iter).m_value, a);
>      }
>
> +  template<typename Arg, bool (*f)(const Key &, Value *, Arg)>
> +  void traverse (Arg a) const
> +    {
> +      for (typename hash_table<hash_entry>::iterator iter = m_table.begin ();
> +          iter != m_table.end (); ++iter)
> +       if (!f ((*iter).m_key, &(*iter).m_value, a))
> +         break;
> +    }
> +
>  private:
>    hash_table<hash_entry> m_table;
>  };
> diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
> index 7810e55..a391b5d 100644
> --- a/gcc/ipa-utils.c
> +++ b/gcc/ipa-utils.c
> @@ -389,7 +389,7 @@ cgraph_node_set_new (void)
>    cgraph_node_set new_node_set;
>
>    new_node_set = XCNEW (struct cgraph_node_set_def);
> -  new_node_set->map = pointer_map_create ();
> +  new_node_set->map = new hash_map<cgraph_node *, size_t>;
>    new_node_set->nodes.create (0);
>    return new_node_set;
>  }
> @@ -400,19 +400,17 @@ cgraph_node_set_new (void)
>  void
>  cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
>  {
> -  void **slot;
> +  bool existed_p;
> +  size_t &index = set->map->get_or_insert (node, &existed_p);
>
> -  slot = pointer_map_insert (set->map, node);
> -
> -  if (*slot)
> +  if (existed_p)
>      {
> -      int index = (size_t) *slot - 1;
>        gcc_checking_assert ((set->nodes[index]
>                            == node));
>        return;
>      }
>
> -  *slot = (void *)(size_t) (set->nodes.length () + 1);
> +  index = set->nodes.length () + 1;
>
>    /* Insert into node vector.  */
>    set->nodes.safe_push (node);
> @@ -424,15 +422,14 @@ cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
>  void
>  cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
>  {
> -  void **slot, **last_slot;
>    int index;
>    struct cgraph_node *last_node;
>
> -  slot = pointer_map_contains (set->map, node);
> +  size_t *slot = set->map->get (node);
>    if (slot == NULL || !*slot)
>      return;
>
> -  index = (size_t) *slot - 1;
> +  index = *slot - 1;
>    gcc_checking_assert (set->nodes[index]
>                        == node);
>
> @@ -441,16 +438,16 @@ cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
>    last_node = set->nodes.pop ();
>    if (last_node != node)
>      {
> -      last_slot = pointer_map_contains (set->map, last_node);
> +      size_t *last_slot = set->map->get (last_node);
>        gcc_checking_assert (last_slot && *last_slot);
> -      *last_slot = (void *)(size_t) (index + 1);
> +      *last_slot = index + 1;
>
>        /* Move the last element to the original spot of NODE.  */
>        set->nodes[index] = last_node;
>      }
>
>    /* Remove element from hash table.  */
> -  *slot = NULL;
> +  set->map->remove (node);
>  }
>
>
> @@ -460,14 +457,14 @@ cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
>  cgraph_node_set_iterator
>  cgraph_node_set_find (cgraph_node_set set, struct cgraph_node *node)
>  {
> -  void **slot;
> +  size_t *slot;
>    cgraph_node_set_iterator csi;
>
> -  slot = pointer_map_contains (set->map, node);
> +  slot = set->map->get (node);
>    if (slot == NULL || !*slot)
>      csi.index = (unsigned) ~0;
>    else
> -    csi.index = (size_t)*slot - 1;
> +    csi.index = *slot - 1;
>    csi.set = set;
>
>    return csi;
> @@ -505,7 +502,7 @@ void
>  free_cgraph_node_set (cgraph_node_set set)
>  {
>    set->nodes.release ();
> -  pointer_map_destroy (set->map);
> +  delete set->map;
>    free (set);
>  }
>
> @@ -518,7 +515,7 @@ varpool_node_set_new (void)
>    varpool_node_set new_node_set;
>
>    new_node_set = XCNEW (struct varpool_node_set_def);
> -  new_node_set->map = pointer_map_create ();
> +  new_node_set->map = new hash_map<varpool_node *, size_t>;
>    new_node_set->nodes.create (0);
>    return new_node_set;
>  }
> @@ -529,19 +526,18 @@ varpool_node_set_new (void)
>  void
>  varpool_node_set_add (varpool_node_set set, varpool_node *node)
>  {
> -  void **slot;
> -
> -  slot = pointer_map_insert (set->map, node);
> +  bool existed;
> +  size_t &slot = set->map->get_or_insert (node, &existed);
>
> -  if (*slot)
> +  if (existed)
>      {
> -      int index = (size_t) *slot - 1;
> +      int index = slot - 1;
>        gcc_checking_assert ((set->nodes[index]
>                            == node));
>        return;
>      }
>
> -  *slot = (void *)(size_t) (set->nodes.length () + 1);
> +  slot = set->nodes.length () + 1;
>
>    /* Insert into node vector.  */
>    set->nodes.safe_push (node);
> @@ -553,15 +549,14 @@ varpool_node_set_add (varpool_node_set set, varpool_node *node)
>  void
>  varpool_node_set_remove (varpool_node_set set, varpool_node *node)
>  {
> -  void **slot, **last_slot;
>    int index;
>    varpool_node *last_node;
>
> -  slot = pointer_map_contains (set->map, node);
> +  size_t *slot = set->map->get (node);
>    if (slot == NULL || !*slot)
>      return;
>
> -  index = (size_t) *slot - 1;
> +  index = *slot - 1;
>    gcc_checking_assert (set->nodes[index]
>                        == node);
>
> @@ -570,16 +565,16 @@ varpool_node_set_remove (varpool_node_set set, varpool_node *node)
>    last_node = set->nodes.pop ();
>    if (last_node != node)
>      {
> -      last_slot = pointer_map_contains (set->map, last_node);
> +      size_t *last_slot = set->map->get (last_node);
>        gcc_checking_assert (last_slot && *last_slot);
> -      *last_slot = (void *)(size_t) (index + 1);
> +      *last_slot = index + 1;
>
>        /* Move the last element to the original spot of NODE.  */
>        set->nodes[index] = last_node;
>      }
>
>    /* Remove element from hash table.  */
> -  *slot = NULL;
> +  set->map->remove (node);
>  }
>
>
> @@ -589,14 +584,13 @@ varpool_node_set_remove (varpool_node_set set, varpool_node *node)
>  varpool_node_set_iterator
>  varpool_node_set_find (varpool_node_set set, varpool_node *node)
>  {
> -  void **slot;
>    varpool_node_set_iterator vsi;
>
> -  slot = pointer_map_contains (set->map, node);
> +  size_t *slot = set->map->get (node);
>    if (slot == NULL || !*slot)
>      vsi.index = (unsigned) ~0;
>    else
> -    vsi.index = (size_t)*slot - 1;
> +    vsi.index = *slot - 1;
>    vsi.set = set;
>
>    return vsi;
> @@ -625,7 +619,7 @@ void
>  free_varpool_node_set (varpool_node_set set)
>  {
>    set->nodes.release ();
> -  pointer_map_destroy (set->map);
> +  delete set->map;
>    free (set);
>  }
>
> diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
> index 42b0790..28a30ad 100644
> --- a/gcc/lto-cgraph.c
> +++ b/gcc/lto-cgraph.c
> @@ -93,7 +93,7 @@ lto_symtab_encoder_new (bool for_input)
>    lto_symtab_encoder_t encoder = XCNEW (struct lto_symtab_encoder_d);
>
>    if (!for_input)
> -    encoder->map = pointer_map_create ();
> +    encoder->map = new hash_map<symtab_node *, size_t>;
>    encoder->nodes.create (0);
>    return encoder;
>  }
> @@ -106,7 +106,7 @@ lto_symtab_encoder_delete (lto_symtab_encoder_t encoder)
>  {
>     encoder->nodes.release ();
>     if (encoder->map)
> -     pointer_map_destroy (encoder->map);
> +     delete encoder->map;
>     free (encoder);
>  }
>
> @@ -120,7 +120,6 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
>                            symtab_node *node)
>  {
>    int ref;
> -  void **slot;
>
>    if (!encoder->map)
>      {
> @@ -131,18 +130,17 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
>        return ref;
>      }
>
> -  slot = pointer_map_contains (encoder->map, node);
> +  size_t *slot = encoder->map->get (node);
>    if (!slot || !*slot)
>      {
>        lto_encoder_entry entry = {node, false, false, false};
>        ref = encoder->nodes.length ();
>        if (!slot)
> -        slot = pointer_map_insert (encoder->map, node);
> -      *slot = (void *) (intptr_t) (ref + 1);
> +        encoder->map->put (node, ref + 1);
>        encoder->nodes.safe_push (entry);
>      }
>    else
> -    ref = (size_t) *slot - 1;
> +    ref = *slot - 1;
>
>    return ref;
>  }
> @@ -153,15 +151,14 @@ bool
>  lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
>                                 symtab_node *node)
>  {
> -  void **slot, **last_slot;
>    int index;
>    lto_encoder_entry last_node;
>
> -  slot = pointer_map_contains (encoder->map, node);
> +  size_t *slot = encoder->map->get (node);
>    if (slot == NULL || !*slot)
>      return false;
>
> -  index = (size_t) *slot - 1;
> +  index = *slot - 1;
>    gcc_checking_assert (encoder->nodes[index].node == node);
>
>    /* Remove from vector. We do this by swapping node with the last element
> @@ -169,16 +166,14 @@ lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
>    last_node = encoder->nodes.pop ();
>    if (last_node.node != node)
>      {
> -      last_slot = pointer_map_contains (encoder->map, last_node.node);
> -      gcc_checking_assert (last_slot && *last_slot);
> -      *last_slot = (void *)(size_t) (index + 1);
> +      gcc_assert (encoder->map->put (last_node.node, index + 1));
>
>        /* Move the last element to the original spot of NODE.  */
>        encoder->nodes[index] = last_node;
>      }
>
>    /* Remove element from hash table.  */
> -  *slot = NULL;
> +  encoder->map->remove (node);
>    return true;
>  }
>
> diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
> index d350ad9..b2486dd 100644
> --- a/gcc/lto-streamer.h
> +++ b/gcc/lto-streamer.h
> @@ -443,7 +443,7 @@ struct lto_encoder_entry
>  struct lto_symtab_encoder_d
>  {
>    vec<lto_encoder_entry> nodes;
> -  pointer_map_t *map;
> +  hash_map<symtab_node *, size_t> *map;
>  };
>
>  typedef struct lto_symtab_encoder_d *lto_symtab_encoder_t;
> @@ -1046,8 +1046,8 @@ static inline int
>  lto_symtab_encoder_lookup (lto_symtab_encoder_t encoder,
>                            symtab_node *node)
>  {
> -  void **slot = pointer_map_contains (encoder->map, node);
> -  return (slot && *slot ? (size_t) *(slot) - 1 : LCC_NOT_FOUND);
> +  size_t *slot = encoder->map->get (node);
> +  return (slot && *slot ? *(slot) - 1 : LCC_NOT_FOUND);
>  }
>
>  /* Return true if iterator LSE points to nothing.  */
> diff --git a/gcc/omp-low.c b/gcc/omp-low.c
> index b46693b..0fe2a40 100644
> --- a/gcc/omp-low.c
> +++ b/gcc/omp-low.c
> @@ -812,16 +812,14 @@ is_reference (tree decl)
>  static inline tree
>  lookup_decl (tree var, omp_context *ctx)
>  {
> -  tree *n;
> -  n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
> +  tree *n = ctx->cb.decl_map->get (var);
>    return *n;
>  }
>
>  static inline tree
>  maybe_lookup_decl (const_tree var, omp_context *ctx)
>  {
> -  tree *n;
> -  n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
> +  tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
>    return n ? *n : NULL_TREE;
>  }
>
> @@ -1359,7 +1357,7 @@ new_omp_context (gimple stmt, omp_context *outer_ctx)
>        ctx->depth = 1;
>      }
>
> -  ctx->cb.decl_map = pointer_map_create ();
> +  ctx->cb.decl_map = new hash_map<tree, tree>;
>
>    return ctx;
>  }
> @@ -1408,7 +1406,7 @@ delete_omp_context (splay_tree_value value)
>  {
>    omp_context *ctx = (omp_context *) value;
>
> -  pointer_map_destroy (ctx->cb.decl_map);
> +  delete ctx->cb.decl_map;
>
>    if (ctx->field_map)
>      splay_tree_delete (ctx->field_map);
> @@ -6541,7 +6539,6 @@ expand_omp_for_static_chunk (struct omp_region *region,
>        gimple_stmt_iterator psi;
>        gimple phi;
>        edge re, ene;
> -      edge_var_map_vector *head;
>        edge_var_map *vm;
>        size_t i;
>
> @@ -6552,7 +6549,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
>          appropriate phi nodes in iter_part_bb instead.  */
>        se = single_pred_edge (fin_bb);
>        re = single_succ_edge (trip_update_bb);
> -      head = redirect_edge_var_map_vector (re);
> +      vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
>        ene = single_succ_edge (entry_bb);
>
>        psi = gsi_start_phis (fin_bb);
> @@ -9219,7 +9216,7 @@ task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
>        walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
>                  &tcctx->cb, NULL);
>        new_fields = new_f;
> -      *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
> +      tcctx->cb.decl_map->put (f, new_f);
>      }
>    TYPE_FIELDS (type) = nreverse (new_fields);
>    layout_type (type);
> @@ -9286,7 +9283,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>        tcctx.cb.copy_decl = task_copyfn_copy_decl;
>        tcctx.cb.eh_lp_nr = 0;
>        tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
> -      tcctx.cb.decl_map = pointer_map_create ();
> +      tcctx.cb.decl_map = new hash_map<tree, tree>;
>        tcctx.ctx = ctx;
>
>        if (record_needs_remap)
> @@ -9311,12 +9308,12 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>           tree *p;
>
>           decl = OMP_CLAUSE_DECL (c);
> -         p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
> +         p = tcctx.cb.decl_map->get (decl);
>           if (p == NULL)
>             continue;
>           n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
>           sf = (tree) n->value;
> -         sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> +         sf = *tcctx.cb.decl_map->get (sf);
>           src = build_simple_mem_ref_loc (loc, sarg);
>           src = omp_build_component_ref (src, sf);
>           t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
> @@ -9335,11 +9332,11 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>           break;
>         f = (tree) n->value;
>         if (tcctx.cb.decl_map)
> -         f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
> +         f = *tcctx.cb.decl_map->get (f);
>         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
>         sf = (tree) n->value;
>         if (tcctx.cb.decl_map)
> -         sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> +         sf = *tcctx.cb.decl_map->get (sf);
>         src = build_simple_mem_ref_loc (loc, sarg);
>         src = omp_build_component_ref (src, sf);
>         dst = build_simple_mem_ref_loc (loc, arg);
> @@ -9356,13 +9353,13 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>           break;
>         f = (tree) n->value;
>         if (tcctx.cb.decl_map)
> -         f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
> +         f = *tcctx.cb.decl_map->get (f);
>         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
>         if (n != NULL)
>           {
>             sf = (tree) n->value;
>             if (tcctx.cb.decl_map)
> -             sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> +             sf = *tcctx.cb.decl_map->get (sf);
>             src = build_simple_mem_ref_loc (loc, sarg);
>             src = omp_build_component_ref (src, sf);
>             if (use_pointer_for_field (decl, NULL) || is_reference (decl))
> @@ -9382,13 +9379,13 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
>         f = (tree) n->value;
>         if (tcctx.cb.decl_map)
> -         f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
> +         f = *tcctx.cb.decl_map->get (f);
>         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
>         if (n != NULL)
>           {
>             sf = (tree) n->value;
>             if (tcctx.cb.decl_map)
> -             sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> +             sf = *tcctx.cb.decl_map->get (sf);
>             src = build_simple_mem_ref_loc (loc, sarg);
>             src = omp_build_component_ref (src, sf);
>             if (use_pointer_for_field (decl, NULL))
> @@ -9419,7 +9416,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>           if (n == NULL)
>             continue;
>           f = (tree) n->value;
> -         f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
> +         f = *tcctx.cb.decl_map->get (f);
>           gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
>           ind = DECL_VALUE_EXPR (decl);
>           gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
> @@ -9427,7 +9424,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>           n = splay_tree_lookup (ctx->sfield_map,
>                                  (splay_tree_key) TREE_OPERAND (ind, 0));
>           sf = (tree) n->value;
> -         sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> +         sf = *tcctx.cb.decl_map->get (sf);
>           src = build_simple_mem_ref_loc (loc, sarg);
>           src = omp_build_component_ref (src, sf);
>           src = build_simple_mem_ref_loc (loc, src);
> @@ -9438,7 +9435,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>           n = splay_tree_lookup (ctx->field_map,
>                                  (splay_tree_key) TREE_OPERAND (ind, 0));
>           df = (tree) n->value;
> -         df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
> +         df = *tcctx.cb.decl_map->get (df);
>           ptr = build_simple_mem_ref_loc (loc, arg);
>           ptr = omp_build_component_ref (ptr, df);
>           t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
> @@ -9450,7 +9447,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
>    append_to_statement_list (t, &list);
>
>    if (tcctx.cb.decl_map)
> -    pointer_map_destroy (tcctx.cb.decl_map);
> +    delete tcctx.cb.decl_map;
>    pop_gimplify_context (NULL);
>    BIND_EXPR_BODY (bind) = list;
>    pop_cfun ();
> diff --git a/gcc/predict.c b/gcc/predict.c
> index 72a3b53..34ebdc3 100644
> --- a/gcc/predict.c
> +++ b/gcc/predict.c
> @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "target.h"
>  #include "cfgloop.h"
>  #include "pointer-set.h"
> +#include "hash-map.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
>  #include "gimple-expr.h"
> @@ -490,11 +491,6 @@ rtl_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
>    return false;
>  }
>
> -/* This map contains for a basic block the list of predictions for the
> -   outgoing edges.  */
> -
> -static struct pointer_map_t *bb_predictions;
> -
>  /*  Structure representing predictions in tree level. */
>
>  struct edge_prediction {
> @@ -504,6 +500,11 @@ struct edge_prediction {
>      int ep_probability;
>  };
>
> +/* This map contains for a basic block the list of predictions for the
> +   outgoing edges.  */
> +
> +static hash_map<const_basic_block, edge_prediction *> *bb_predictions;
> +
>  /* Return true if the one of outgoing edges is already predicted by
>     PREDICTOR.  */
>
> @@ -511,12 +512,12 @@ bool
>  gimple_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
>  {
>    struct edge_prediction *i;
> -  void **preds = pointer_map_contains (bb_predictions, bb);
> +  edge_prediction **preds = bb_predictions->get (bb);
>
>    if (!preds)
>      return false;
>
> -  for (i = (struct edge_prediction *) *preds; i; i = i->ep_next)
> +  for (i = *preds; i; i = i->ep_next)
>      if (i->ep_predictor == predictor)
>        return true;
>    return false;
> @@ -618,10 +619,10 @@ gimple_predict_edge (edge e, enum br_predictor predictor, int probability)
>        && flag_guess_branch_prob && optimize)
>      {
>        struct edge_prediction *i = XNEW (struct edge_prediction);
> -      void **preds = pointer_map_insert (bb_predictions, e->src);
> +      edge_prediction *&preds = bb_predictions->get_or_insert (e->src);
>
> -      i->ep_next = (struct edge_prediction *) *preds;
> -      *preds = i;
> +      i->ep_next = preds;
> +      preds = i;
>        i->ep_probability = probability;
>        i->ep_predictor = predictor;
>        i->ep_edge = e;
> @@ -633,16 +634,14 @@ gimple_predict_edge (edge e, enum br_predictor predictor, int probability)
>  void
>  remove_predictions_associated_with_edge (edge e)
>  {
> -  void **preds;
> -
>    if (!bb_predictions)
>      return;
>
> -  preds = pointer_map_contains (bb_predictions, e->src);
> +  edge_prediction **preds = bb_predictions->get (e->src);
>
>    if (preds)
>      {
> -      struct edge_prediction **prediction = (struct edge_prediction **) preds;
> +      struct edge_prediction **prediction = preds;
>        struct edge_prediction *next;
>
>        while (*prediction)
> @@ -664,13 +663,13 @@ remove_predictions_associated_with_edge (edge e)
>  static void
>  clear_bb_predictions (basic_block bb)
>  {
> -  void **preds = pointer_map_contains (bb_predictions, bb);
> +  edge_prediction **preds = bb_predictions->get (bb);
>    struct edge_prediction *pred, *next;
>
>    if (!preds)
>      return;
>
> -  for (pred = (struct edge_prediction *) *preds; pred; pred = next)
> +  for (pred = *preds; pred; pred = next)
>      {
>        next = pred->ep_next;
>        free (pred);
> @@ -903,7 +902,6 @@ combine_predictions_for_bb (basic_block bb)
>    int nedges = 0;
>    edge e, first = NULL, second = NULL;
>    edge_iterator ei;
> -  void **preds;
>
>    FOR_EACH_EDGE (e, ei, bb->succs)
>      if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
> @@ -935,12 +933,12 @@ combine_predictions_for_bb (basic_block bb)
>    if (dump_file)
>      fprintf (dump_file, "Predictions for bb %i\n", bb->index);
>
> -  preds = pointer_map_contains (bb_predictions, bb);
> +  edge_prediction **preds = bb_predictions->get (bb);
>    if (preds)
>      {
>        /* We implement "first match" heuristics and use probability guessed
>          by predictor with smallest index.  */
> -      for (pred = (struct edge_prediction *) *preds; pred; pred = pred->ep_next)
> +      for (pred = *preds; pred; pred = pred->ep_next)
>         {
>           enum br_predictor predictor = pred->ep_predictor;
>           int probability = pred->ep_probability;
> @@ -2243,14 +2241,14 @@ tree_bb_level_predictions (void)
>
>  #ifdef ENABLE_CHECKING
>
> -/* Callback for pointer_map_traverse, asserts that the pointer map is
> +/* Callback for hash_map::traverse, asserts that the pointer map is
>     empty.  */
>
> -static bool
> -assert_is_empty (const void *key ATTRIBUTE_UNUSED, void **value,
> -                void *data ATTRIBUTE_UNUSED)
> +bool
> +assert_is_empty (const_basic_block const &, edge_prediction *const &value,
> +                void *)
>  {
> -  gcc_assert (!*value);
> +  gcc_assert (!value);
>    return false;
>  }
>  #endif
> @@ -2375,7 +2373,7 @@ tree_estimate_probability (void)
>    create_preheaders (CP_SIMPLE_PREHEADERS);
>    calculate_dominance_info (CDI_POST_DOMINATORS);
>
> -  bb_predictions = pointer_map_create ();
> +  bb_predictions = new hash_map<const_basic_block, edge_prediction *>;
>    tree_bb_level_predictions ();
>    record_loop_exits ();
>
> @@ -2389,9 +2387,9 @@ tree_estimate_probability (void)
>      combine_predictions_for_bb (bb);
>
>  #ifdef ENABLE_CHECKING
> -  pointer_map_traverse (bb_predictions, assert_is_empty, NULL);
> +  bb_predictions->traverse<void *, assert_is_empty> (NULL);
>  #endif
> -  pointer_map_destroy (bb_predictions);
> +  delete bb_predictions;
>    bb_predictions = NULL;
>
>    estimate_bb_frequencies (false);
> diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> index e034762..cfa6527 100644
> --- a/gcc/tree-cfg.c
> +++ b/gcc/tree-cfg.c
> @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "system.h"
>  #include "coretypes.h"
>  #include "hash-table.h"
> +#include "hash-map.h"
>  #include "tm.h"
>  #include "tree.h"
>  #include "trans-mem.h"
> @@ -92,7 +93,7 @@ static const int initial_cfg_capacity = 20;
>     more persistent.  The key is getting notification of changes to
>     the CFG (particularly edge removal, creation and redirection).  */
>
> -static struct pointer_map_t *edge_to_cases;
> +static hash_map<edge, tree> *edge_to_cases;
>
>  /* If we record edge_to_cases, this bitmap will hold indexes
>     of basic blocks that end in a GIMPLE_SWITCH which we touched
> @@ -1048,19 +1049,17 @@ make_cond_expr_edges (basic_block bb)
>     SWITCH_EXPRs and structure sharing rules, then free the hash table
>     element.  */
>
> -static bool
> -edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value,
> -                      void *data ATTRIBUTE_UNUSED)
> +bool
> +edge_to_cases_cleanup (edge const &, tree const &value, void *)
>  {
>    tree t, next;
>
> -  for (t = (tree) *value; t; t = next)
> +  for (t = value; t; t = next)
>      {
>        next = CASE_CHAIN (t);
>        CASE_CHAIN (t) = NULL;
>      }
>
> -  *value = NULL;
>    return true;
>  }
>
> @@ -1070,7 +1069,7 @@ void
>  start_recording_case_labels (void)
>  {
>    gcc_assert (edge_to_cases == NULL);
> -  edge_to_cases = pointer_map_create ();
> +  edge_to_cases = new hash_map<edge, tree>;
>    touched_switch_bbs = BITMAP_ALLOC (NULL);
>  }
>
> @@ -1089,8 +1088,8 @@ end_recording_case_labels (void)
>  {
>    bitmap_iterator bi;
>    unsigned i;
> -  pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL);
> -  pointer_map_destroy (edge_to_cases);
> +  edge_to_cases->traverse<void *, edge_to_cases_cleanup> (NULL);
> +  delete edge_to_cases;
>    edge_to_cases = NULL;
>    EXECUTE_IF_SET_IN_BITMAP (touched_switch_bbs, 0, i, bi)
>      {
> @@ -1113,7 +1112,7 @@ end_recording_case_labels (void)
>  static tree
>  get_cases_for_edge (edge e, gimple t)
>  {
> -  void **slot;
> +  tree *slot;
>    size_t i, n;
>
>    /* If we are not recording cases, then we do not have CASE_LABEL_EXPR
> @@ -1121,9 +1120,9 @@ get_cases_for_edge (edge e, gimple t)
>    if (!recording_case_labels_p ())
>      return NULL;
>
> -  slot = pointer_map_contains (edge_to_cases, e);
> +  slot = edge_to_cases->get (e);
>    if (slot)
> -    return (tree) *slot;
> +    return *slot;
>
>    /* If we did not find E in the hash table, then this must be the first
>       time we have been queried for information about E & T.  Add all the
> @@ -1139,12 +1138,12 @@ get_cases_for_edge (edge e, gimple t)
>
>        /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
>          a new chain.  */
> -      slot = pointer_map_insert (edge_to_cases, this_edge);
> -      CASE_CHAIN (elt) = (tree) *slot;
> -      *slot = elt;
> +      tree &s = edge_to_cases->get_or_insert (this_edge);
> +      CASE_CHAIN (elt) = s;
> +      s = elt;
>      }
>
> -  return (tree) *pointer_map_contains (edge_to_cases, e);
> +  return *edge_to_cases->get (e);
>  }
>
>  /* Create the edges for a GIMPLE_SWITCH starting at block BB.  */
> @@ -2577,12 +2576,11 @@ last_and_only_stmt (basic_block bb)
>  static void
>  reinstall_phi_args (edge new_edge, edge old_edge)
>  {
> -  edge_var_map_vector *v;
>    edge_var_map *vm;
>    int i;
>    gimple_stmt_iterator phis;
>
> -  v = redirect_edge_var_map_vector (old_edge);
> +  vec<edge_var_map> *v = redirect_edge_var_map_vector (old_edge);
>    if (!v)
>      return;
>
> @@ -6268,22 +6266,20 @@ gather_blocks_in_sese_region (basic_block entry, basic_block exit,
>     The duplicates are recorded in VARS_MAP.  */
>
>  static void
> -replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
> +replace_by_duplicate_decl (tree *tp, hash_map<tree, tree> *vars_map,
>                            tree to_context)
>  {
>    tree t = *tp, new_t;
>    struct function *f = DECL_STRUCT_FUNCTION (to_context);
> -  void **loc;
>
>    if (DECL_CONTEXT (t) == to_context)
>      return;
>
> -  loc = pointer_map_contains (vars_map, t);
> +  bool existed;
> +  tree &loc = vars_map->get_or_insert (t, &existed);
>
> -  if (!loc)
> +  if (!existed)
>      {
> -      loc = pointer_map_insert (vars_map, t);
> -
>        if (SSA_VAR_P (t))
>         {
>           new_t = copy_var_decl (t, DECL_NAME (t), TREE_TYPE (t));
> @@ -6296,10 +6292,10 @@ replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
>         }
>        DECL_CONTEXT (new_t) = to_context;
>
> -      *loc = new_t;
> +      loc = new_t;
>      }
>    else
> -    new_t = (tree) *loc;
> +    new_t = loc;
>
>    *tp = new_t;
>  }
> @@ -6309,15 +6305,14 @@ replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
>     VARS_MAP maps old ssa names and var_decls to the new ones.  */
>
>  static tree
> -replace_ssa_name (tree name, struct pointer_map_t *vars_map,
> +replace_ssa_name (tree name, hash_map<tree, tree> *vars_map,
>                   tree to_context)
>  {
> -  void **loc;
>    tree new_name;
>
>    gcc_assert (!virtual_operand_p (name));
>
> -  loc = pointer_map_contains (vars_map, name);
> +  tree *loc = vars_map->get (name);
>
>    if (!loc)
>      {
> @@ -6335,11 +6330,10 @@ replace_ssa_name (tree name, struct pointer_map_t *vars_map,
>         new_name = copy_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context),
>                                      name, SSA_NAME_DEF_STMT (name));
>
> -      loc = pointer_map_insert (vars_map, name);
> -      *loc = new_name;
> +      vars_map->put (name, new_name);
>      }
>    else
> -    new_name = (tree) *loc;
> +    new_name = *loc;
>
>    return new_name;
>  }
> @@ -6350,9 +6344,9 @@ struct move_stmt_d
>    tree new_block;
>    tree from_context;
>    tree to_context;
> -  struct pointer_map_t *vars_map;
> +  hash_map<tree, tree> *vars_map;
>    htab_t new_label_map;
> -  struct pointer_map_t *eh_map;
> +  hash_map<void *, void *> *eh_map;
>    bool remap_decls_p;
>  };
>
> @@ -6429,11 +6423,9 @@ static int
>  move_stmt_eh_region_nr (int old_nr, struct move_stmt_d *p)
>  {
>    eh_region old_r, new_r;
> -  void **slot;
>
>    old_r = get_eh_region_from_number (old_nr);
> -  slot = pointer_map_contains (p->eh_map, old_r);
> -  new_r = (eh_region) *slot;
> +  new_r = static_cast<eh_region> (*p->eh_map->get (old_r));
>
>    return new_r->index;
>  }
> @@ -6767,7 +6759,7 @@ new_label_mapper (tree decl, void *data)
>     subblocks.  */
>
>  static void
> -replace_block_vars_by_duplicates (tree block, struct pointer_map_t *vars_map,
> +replace_block_vars_by_duplicates (tree block, hash_map<tree, tree> *vars_map,
>                                   tree to_context)
>  {
>    tree *tp, t;
> @@ -6845,7 +6837,7 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
>    edge e;
>    edge_iterator ei;
>    htab_t new_label_map;
> -  struct pointer_map_t *vars_map, *eh_map;
> +  hash_map<void *, void *> *eh_map;
>    struct loop *loop = entry_bb->loop_father;
>    struct loop *loop0 = get_loop (saved_cfun, 0);
>    struct move_stmt_d d;
> @@ -6989,14 +6981,14 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
>    /* Move blocks from BBS into DEST_CFUN.  */
>    gcc_assert (bbs.length () >= 2);
>    after = dest_cfun->cfg->x_entry_block_ptr;
> -  vars_map = pointer_map_create ();
> +  hash_map<tree, tree> vars_map;
>
>    memset (&d, 0, sizeof (d));
>    d.orig_block = orig_block;
>    d.new_block = DECL_INITIAL (dest_cfun->decl);
>    d.from_context = cfun->decl;
>    d.to_context = dest_cfun->decl;
> -  d.vars_map = vars_map;
> +  d.vars_map = &vars_map;
>    d.new_label_map = new_label_map;
>    d.eh_map = eh_map;
>    d.remap_decls_p = true;
> @@ -7051,13 +7043,12 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
>      }
>
>    replace_block_vars_by_duplicates (DECL_INITIAL (dest_cfun->decl),
> -                                   vars_map, dest_cfun->decl);
> +                                   &vars_map, dest_cfun->decl);
>
>    if (new_label_map)
>      htab_delete (new_label_map);
>    if (eh_map)
> -    pointer_map_destroy (eh_map);
> -  pointer_map_destroy (vars_map);
> +    delete eh_map;
>
>    /* Rewire the entry and exit blocks.  The successor to the entry
>       block turns into the successor of DEST_FN's ENTRY_BLOCK_PTR in
> diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
> index bc4d83e..2b6927e 100644
> --- a/gcc/tree-cfgcleanup.c
> +++ b/gcc/tree-cfgcleanup.c
> @@ -865,16 +865,14 @@ remove_forwarder_block_with_phi (basic_block bb)
>
>           if (TREE_CODE (def) == SSA_NAME)
>             {
> -             edge_var_map_vector *head;
> -             edge_var_map *vm;
> -             size_t i;
> -
>               /* If DEF is one of the results of PHI nodes removed during
>                  redirection, replace it with the PHI argument that used
>                  to be on E.  */
> -             head = redirect_edge_var_map_vector (e);
> -             FOR_EACH_VEC_SAFE_ELT (head, i, vm)
> +             vec<edge_var_map> *head = redirect_edge_var_map_vector (e);
> +             size_t length = head ? head->length () : 0;
> +             for (size_t i = 0; i < length; i++)
>                 {
> +                 edge_var_map *vm = &(*head)[i];
>                   tree old_arg = redirect_edge_var_map_result (vm);
>                   tree new_arg = redirect_edge_var_map_def (vm);
>
> diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
> index 38842e8..db28184 100644
> --- a/gcc/tree-eh.c
> +++ b/gcc/tree-eh.c
> @@ -406,7 +406,7 @@ struct leh_tf_state
>    size_t goto_queue_active;
>
>    /* Pointer map to help in searching goto_queue when it is large.  */
> -  struct pointer_map_t *goto_queue_map;
> +  hash_map<gimple, goto_queue_node *> *goto_queue_map;
>
>    /* The set of unique labels seen as entries in the goto queue.  */
>    vec<tree> dest_array;
> @@ -441,7 +441,6 @@ static gimple_seq
>  find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
>  {
>    unsigned int i;
> -  void **slot;
>
>    if (tf->goto_queue_active < LARGE_GOTO_QUEUE)
>      {
> @@ -456,19 +455,18 @@ find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
>
>    if (!tf->goto_queue_map)
>      {
> -      tf->goto_queue_map = pointer_map_create ();
> +      tf->goto_queue_map = new hash_map<gimple, goto_queue_node *>;
>        for (i = 0; i < tf->goto_queue_active; i++)
>         {
> -         slot = pointer_map_insert (tf->goto_queue_map,
> -                                     tf->goto_queue[i].stmt.g);
> -          gcc_assert (*slot == NULL);
> -         *slot = &tf->goto_queue[i];
> +         bool existed = tf->goto_queue_map->put (tf->goto_queue[i].stmt.g,
> +                                                 &tf->goto_queue[i]);
> +         gcc_assert (!existed);
>         }
>      }
>
> -  slot = pointer_map_contains (tf->goto_queue_map, stmt.g);
> +  goto_queue_node **slot = tf->goto_queue_map->get (stmt.g);
>    if (slot != NULL)
> -    return (((struct goto_queue_node *) *slot)->repl_stmt);
> +    return ((*slot)->repl_stmt);
>
>    return NULL;
>  }
> @@ -1372,7 +1370,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
>    tree tmp;
>    gimple switch_stmt;
>    gimple_seq finally;
> -  struct pointer_map_t *cont_map = NULL;
> +  hash_map<tree, gimple> *cont_map = NULL;
>    /* The location of the TRY_FINALLY stmt.  */
>    location_t tf_loc = gimple_location (tf->try_finally_expr);
>    /* The location of the finally block.  */
> @@ -1511,32 +1509,27 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
>        if (case_label_vec.length () <= case_index || !case_label_vec[case_index])
>          {
>            tree case_lab;
> -          void **slot;
>           tmp = build_int_cst (integer_type_node, switch_id);
>            case_lab = build_case_label (tmp, NULL,
>                                        create_artificial_label (tf_loc));
>            /* We store the cont_stmt in the pointer map, so that we can recover
>               it in the loop below.  */
>            if (!cont_map)
> -            cont_map = pointer_map_create ();
> -          slot = pointer_map_insert (cont_map, case_lab);
> -          *slot = q->cont_stmt;
> +            cont_map = new hash_map<tree, gimple>;
> +          cont_map->put (case_lab, q->cont_stmt);
>            case_label_vec.quick_push (case_lab);
>          }
>      }
>    for (j = last_case_index; j < last_case_index + nlabels; j++)
>      {
>        gimple cont_stmt;
> -      void **slot;
>
>        last_case = case_label_vec[j];
>
>        gcc_assert (last_case);
>        gcc_assert (cont_map);
>
> -      slot = pointer_map_contains (cont_map, last_case);
> -      gcc_assert (slot);
> -      cont_stmt = *(gimple *) slot;
> +      cont_stmt = *cont_map->get (last_case);
>
>        x = gimple_build_label (CASE_LABEL (last_case));
>        gimple_seq_add_stmt (&switch_body, x);
> @@ -1544,7 +1537,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
>        maybe_record_in_goto_queue (state, cont_stmt);
>      }
>    if (cont_map)
> -    pointer_map_destroy (cont_map);
> +    delete cont_map;
>
>    replace_goto_queue (tf);
>
> @@ -1734,7 +1727,7 @@ lower_try_finally (struct leh_state *state, gimple tp)
>    this_tf.dest_array.release ();
>    free (this_tf.goto_queue);
>    if (this_tf.goto_queue_map)
> -    pointer_map_destroy (this_tf.goto_queue_map);
> +    delete this_tf.goto_queue_map;
>
>    /* If there was an old (aka outer) eh_seq, append the current eh_seq.
>       If there was no old eh_seq, then the append is trivially already done.  */
> @@ -2921,10 +2914,10 @@ maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
>  bool
>  maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
>                             struct function *old_fun, gimple old_stmt,
> -                           struct pointer_map_t *map, int default_lp_nr)
> +                           hash_map<void *, void *> *map,
> +                           int default_lp_nr)
>  {
>    int old_lp_nr, new_lp_nr;
> -  void **slot;
>
>    if (!stmt_could_throw_p (new_stmt))
>      return false;
> @@ -2941,8 +2934,7 @@ maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
>        eh_landing_pad old_lp, new_lp;
>
>        old_lp = (*old_fun->eh->lp_array)[old_lp_nr];
> -      slot = pointer_map_contains (map, old_lp);
> -      new_lp = (eh_landing_pad) *slot;
> +      new_lp = static_cast<eh_landing_pad> (*map->get (old_lp));
>        new_lp_nr = new_lp->index;
>      }
>    else
> @@ -2950,8 +2942,7 @@ maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
>        eh_region old_r, new_r;
>
>        old_r = (*old_fun->eh->region_array)[-old_lp_nr];
> -      slot = pointer_map_contains (map, old_r);
> -      new_r = (eh_region) *slot;
> +      new_r = static_cast<eh_region> (*map->get (old_r));
>        new_lp_nr = -new_r->index;
>      }
>
> @@ -3154,7 +3145,7 @@ make_pass_refactor_eh (gcc::context *ctxt)
>  /* At the end of gimple optimization, we can lower RESX.  */
>
>  static bool
> -lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
> +lower_resx (basic_block bb, gimple stmt, hash_map<eh_region, tree> *mnt_map)
>  {
>    int lp_nr;
>    eh_region src_r, dst_r;
> @@ -3199,14 +3190,13 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
>        if (lp_nr < 0)
>         {
>           basic_block new_bb;
> -         void **slot;
>           tree lab;
>
>           /* We are resuming into a MUST_NOT_CALL region.  Expand a call to
>              the failure decl into a new block, if needed.  */
>           gcc_assert (dst_r->type == ERT_MUST_NOT_THROW);
>
> -         slot = pointer_map_contains (mnt_map, dst_r);
> +         tree *slot = mnt_map->get (dst_r);
>           if (slot == NULL)
>             {
>               gimple_stmt_iterator gsi2;
> @@ -3221,12 +3211,11 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
>               gimple_set_location (x, dst_r->u.must_not_throw.failure_loc);
>               gsi_insert_after (&gsi2, x, GSI_CONTINUE_LINKING);
>
> -             slot = pointer_map_insert (mnt_map, dst_r);
> -             *slot = lab;
> +             mnt_map->put (dst_r, lab);
>             }
>           else
>             {
> -             lab = (tree) *slot;
> +             lab = *slot;
>               new_bb = label_to_block (lab);
>             }
>
> @@ -3334,24 +3323,21 @@ unsigned
>  pass_lower_resx::execute (function *fun)
>  {
>    basic_block bb;
> -  struct pointer_map_t *mnt_map;
>    bool dominance_invalidated = false;
>    bool any_rewritten = false;
>
> -  mnt_map = pointer_map_create ();
> +  hash_map<eh_region, tree> mnt_map;
>
>    FOR_EACH_BB_FN (bb, fun)
>      {
>        gimple last = last_stmt (bb);
>        if (last && is_gimple_resx (last))
>         {
> -         dominance_invalidated |= lower_resx (bb, last, mnt_map);
> +         dominance_invalidated |= lower_resx (bb, last, &mnt_map);
>           any_rewritten = true;
>         }
>      }
>
> -  pointer_map_destroy (mnt_map);
> -
>    if (dominance_invalidated)
>      {
>        free_dominance_info (CDI_DOMINATORS);
> diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h
> index cd9b40d..51c2adc 100644
> --- a/gcc/tree-eh.h
> +++ b/gcc/tree-eh.h
> @@ -20,6 +20,10 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_TREE_EH_H
>  #define GCC_TREE_EH_H
>
> +#include "hash-map.h"
> +
> +typedef struct eh_region_d *eh_region;
> +
>  extern void using_eh_for_cleanups (void);
>  extern void add_stmt_to_eh_lp (gimple, int);
>  extern bool remove_stmt_from_eh_lp_fn (struct function *, gimple);
> @@ -43,7 +47,7 @@ extern bool maybe_clean_eh_stmt (gimple);
>  extern bool maybe_clean_or_replace_eh_stmt (gimple, gimple);
>  extern bool maybe_duplicate_eh_stmt_fn (struct function *, gimple,
>                                         struct function *, gimple,
> -                                       struct pointer_map_t *, int);
> +                                       hash_map<void *, void *> *, int);
>  extern bool maybe_duplicate_eh_stmt (gimple, gimple);
>  extern void maybe_remove_unreachable_handlers (void);
>  extern bool verify_eh_edges (gimple);
> diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
> index 6af4912..e2b7990 100644
> --- a/gcc/tree-inline.c
> +++ b/gcc/tree-inline.c
> @@ -135,7 +135,7 @@ static tree declare_return_variable (copy_body_data *, tree, tree, basic_block);
>  static void remap_block (tree *, copy_body_data *);
>  static void copy_bind_expr (tree *, int *, copy_body_data *);
>  static void declare_inline_vars (tree, tree);
> -static void remap_save_expr (tree *, void *, int *);
> +static void remap_save_expr (tree *, hash_map<tree, tree> *, int *);
>  static void prepend_lexical_block (tree current_block, tree new_block);
>  static tree copy_decl_to_var (tree, copy_body_data *);
>  static tree copy_result_decl_to_var (tree, copy_body_data *);
> @@ -149,12 +149,12 @@ static bool delete_unreachable_blocks_update_callgraph (copy_body_data *id);
>  void
>  insert_decl_map (copy_body_data *id, tree key, tree value)
>  {
> -  *pointer_map_insert (id->decl_map, key) = value;
> +  id->decl_map->put (key, value);
>
>    /* Always insert an identity map as well.  If we see this same new
>       node again, we won't want to duplicate it a second time.  */
>    if (key != value)
> -    *pointer_map_insert (id->decl_map, value) = value;
> +    id->decl_map->put (value, value);
>  }
>
>  /* Insert a tree->tree mapping for ID.  This is only used for
> @@ -176,9 +176,9 @@ insert_debug_decl_map (copy_body_data *id, tree key, tree value)
>    gcc_assert (TREE_CODE (value) == VAR_DECL);
>
>    if (!id->debug_map)
> -    id->debug_map = pointer_map_create ();
> +    id->debug_map = new hash_map<tree, tree>;
>
> -  *pointer_map_insert (id->debug_map, key) = value;
> +  id->debug_map->put (key, value);
>  }
>
>  /* If nonzero, we're remapping the contents of inlined debug
> @@ -197,7 +197,7 @@ remap_ssa_name (tree name, copy_body_data *id)
>
>    gcc_assert (TREE_CODE (name) == SSA_NAME);
>
> -  n = (tree *) pointer_map_contains (id->decl_map, name);
> +  n = id->decl_map->get (name);
>    if (n)
>      return unshare_expr (*n);
>
> @@ -213,7 +213,7 @@ remap_ssa_name (tree name, copy_body_data *id)
>           gimple_stmt_iterator gsi;
>           tree val = SSA_NAME_VAR (name);
>
> -         n = (tree *) pointer_map_contains (id->decl_map, val);
> +         n = id->decl_map->get (val);
>           if (n != NULL)
>             val = *n;
>           if (TREE_CODE (val) != PARM_DECL)
> @@ -342,7 +342,7 @@ remap_decl (tree decl, copy_body_data *id)
>
>    /* See if we have remapped this declaration.  */
>
> -  n = (tree *) pointer_map_contains (id->decl_map, decl);
> +  n = id->decl_map->get (decl);
>
>    if (!n && processing_debug_stmt)
>      {
> @@ -562,7 +562,7 @@ remap_type (tree type, copy_body_data *id)
>      return type;
>
>    /* See if we have remapped this type.  */
> -  node = (tree *) pointer_map_contains (id->decl_map, type);
> +  node = id->decl_map->get (type);
>    if (node)
>      return *node;
>
> @@ -887,7 +887,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
>      {
>        /* If the enclosing record type is variably_modified_type_p, the field
>          has already been remapped.  Otherwise, it need not be.  */
> -      tree *n = (tree *) pointer_map_contains (id->decl_map, *tp);
> +      tree *n = id->decl_map->get (*tp);
>        if (n)
>         *tp = *n;
>        *walk_subtrees = 0;
> @@ -981,8 +981,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
>        if (old_block)
>         {
>           tree *n;
> -         n = (tree *) pointer_map_contains (id->decl_map,
> -                                            TREE_BLOCK (*tp));
> +         n = id->decl_map->get (TREE_BLOCK (*tp));
>           if (n)
>             new_block = *n;
>         }
> @@ -1108,7 +1107,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
>           tree decl = TREE_OPERAND (*tp, 0), value;
>           tree *n;
>
> -         n = (tree *) pointer_map_contains (id->decl_map, decl);
> +         n = id->decl_map->get (decl);
>           if (n)
>             {
>               value = *n;
> @@ -1125,7 +1124,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
>           /* Get rid of *& from inline substitutions that can happen when a
>              pointer argument is an ADDR_EXPR.  */
>           tree decl = TREE_OPERAND (*tp, 0);
> -         tree *n = (tree *) pointer_map_contains (id->decl_map, decl);
> +         tree *n = id->decl_map->get (decl);
>           if (n)
>             {
>               /* If we happen to get an ADDR_EXPR in n->value, strip
> @@ -1206,8 +1205,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
>           if (TREE_BLOCK (*tp))
>             {
>               tree *n;
> -             n = (tree *) pointer_map_contains (id->decl_map,
> -                                                TREE_BLOCK (*tp));
> +             n = id->decl_map->get (TREE_BLOCK (*tp));
>               if (n)
>                 new_block = *n;
>             }
> @@ -1261,11 +1259,9 @@ static int
>  remap_eh_region_nr (int old_nr, copy_body_data *id)
>  {
>    eh_region old_r, new_r;
> -  void **slot;
>
>    old_r = get_eh_region_from_number_fn (id->src_cfun, old_nr);
> -  slot = pointer_map_contains (id->eh_map, old_r);
> -  new_r = (eh_region) *slot;
> +  new_r = static_cast<eh_region> (*id->eh_map->get (old_r));
>
>    return new_r->index;
>  }
> @@ -1483,7 +1479,7 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
>           tree decl = gimple_assign_lhs (stmt), value;
>           tree *n;
>
> -         n = (tree *) pointer_map_contains (id->decl_map, decl);
> +         n = id->decl_map->get (decl);
>           if (n)
>             {
>               value = *n;
> @@ -1597,7 +1593,7 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
>    if (gimple_block (copy))
>      {
>        tree *n;
> -      n = (tree *) pointer_map_contains (id->decl_map, gimple_block (copy));
> +      n = id->decl_map->get (gimple_block (copy));
>        gcc_assert (n);
>        gimple_set_block (copy, *n);
>      }
> @@ -2191,8 +2187,7 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
>               if (LOCATION_BLOCK (locus))
>                 {
>                   tree *n;
> -                 n = (tree *) pointer_map_contains (id->decl_map,
> -                       LOCATION_BLOCK (locus));
> +                 n = id->decl_map->get (LOCATION_BLOCK (locus));
>                   gcc_assert (n);
>                   if (*n)
>                     locus = COMBINE_LOCATION_DATA (line_table, locus, *n);
> @@ -2638,7 +2633,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
>
>    if (id->eh_map)
>      {
> -      pointer_map_destroy (id->eh_map);
> +      delete id->eh_map;
>        id->eh_map = NULL;
>      }
>
> @@ -2659,7 +2654,7 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
>
>    if (gimple_block (stmt))
>      {
> -      n = (tree *) pointer_map_contains (id->decl_map, gimple_block (stmt));
> +      n = id->decl_map->get (gimple_block (stmt));
>        gimple_set_block (stmt, n ? *n : id->block);
>      }
>
> @@ -2675,14 +2670,14 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
>      t = gimple_debug_bind_get_var (stmt);
>
>    if (TREE_CODE (t) == PARM_DECL && id->debug_map
> -      && (n = (tree *) pointer_map_contains (id->debug_map, t)))
> +      && (n = id->debug_map->get (t)))
>      {
>        gcc_assert (TREE_CODE (*n) == VAR_DECL);
>        t = *n;
>      }
>    else if (TREE_CODE (t) == VAR_DECL
>            && !is_global_var (t)
> -          && !pointer_map_contains (id->decl_map, t))
> +          && !id->decl_map->get (t))
>      /* T is a non-localized variable.  */;
>    else
>      walk_tree (&t, remap_gimple_op_r, &wi, NULL);
> @@ -3076,7 +3071,7 @@ initialize_inlined_parameters (copy_body_data *id, gimple stmt,
>       parameter following the array.  */
>    for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
>      {
> -      tree *varp = (tree *) pointer_map_contains (id->decl_map, p);
> +      tree *varp = id->decl_map->get (p);
>        if (varp
>           && TREE_CODE (*varp) == VAR_DECL)
>         {
> @@ -3089,7 +3084,7 @@ initialize_inlined_parameters (copy_body_data *id, gimple stmt,
>              by the parameter setup.  */
>           if (def)
>             {
> -             tree *defp = (tree *) pointer_map_contains (id->decl_map, def);
> +             tree *defp = id->decl_map->get (def);
>               if (defp
>                   && TREE_CODE (*defp) == SSA_NAME
>                   && SSA_NAME_VAR (*defp) == var)
> @@ -4135,7 +4130,8 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
>  {
>    tree use_retvar;
>    tree fn;
> -  struct pointer_map_t *st, *dst;
> +  hash_map<tree, tree> *dst;
> +  hash_map<tree, tree> *st = NULL;
>    tree return_slot;
>    tree modify_dest;
>    location_t saved_location;
> @@ -4291,7 +4287,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
>    /* Local declarations will be replaced by their equivalents in this
>       map.  */
>    st = id->decl_map;
> -  id->decl_map = pointer_map_create ();
> +  id->decl_map = new hash_map<tree, tree>;
>    dst = id->debug_map;
>    id->debug_map = NULL;
>
> @@ -4415,10 +4411,10 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
>    /* Clean up.  */
>    if (id->debug_map)
>      {
> -      pointer_map_destroy (id->debug_map);
> +      delete id->debug_map;
>        id->debug_map = dst;
>      }
> -  pointer_map_destroy (id->decl_map);
> +  delete id->decl_map;
>    id->decl_map = st;
>
>    /* Unlink the calls virtual operands before replacing it.  */
> @@ -4772,14 +4768,13 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
>     the function into which the copy will be placed.  */
>
>  static void
> -remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
> +remap_save_expr (tree *tp, hash_map<tree, tree> *st, int *walk_subtrees)
>  {
> -  struct pointer_map_t *st = (struct pointer_map_t *) st_;
>    tree *n;
>    tree t;
>
>    /* See if we already encountered this SAVE_EXPR.  */
> -  n = (tree *) pointer_map_contains (st, *tp);
> +  n = st->get (*tp);
>
>    /* If we didn't already remap this SAVE_EXPR, do so now.  */
>    if (!n)
> @@ -4787,9 +4782,9 @@ remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
>        t = copy_node (*tp);
>
>        /* Remember this SAVE_EXPR.  */
> -      *pointer_map_insert (st, *tp) = t;
> +      st->put (*tp, t);
>        /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
> -      *pointer_map_insert (st, t) = t;
> +      st->put (t, t);
>      }
>    else
>      {
> @@ -4836,7 +4831,7 @@ replace_locals_op (tree *tp, int *walk_subtrees, void *data)
>  {
>    struct walk_stmt_info *wi = (struct walk_stmt_info*) data;
>    copy_body_data *id = (copy_body_data *) wi->info;
> -  struct pointer_map_t *st = id->decl_map;
> +  hash_map<tree, tree> *st = id->decl_map;
>    tree *n;
>    tree expr = *tp;
>
> @@ -4846,7 +4841,7 @@ replace_locals_op (tree *tp, int *walk_subtrees, void *data)
>        || TREE_CODE (expr) == LABEL_DECL)
>      {
>        /* Lookup the declaration.  */
> -      n = (tree *) pointer_map_contains (st, expr);
> +      n = st->get (expr);
>
>        /* If it's there, remap it.  */
>        if (n)
> @@ -4928,7 +4923,7 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
>    memset (&id, 0, sizeof (id));
>    id.src_fn = current_function_decl;
>    id.dst_fn = current_function_decl;
> -  id.decl_map = pointer_map_create ();
> +  id.decl_map = new hash_map<tree, tree>;
>    id.debug_map = NULL;
>
>    id.copy_decl = copy_decl_no_change;
> @@ -4953,9 +4948,9 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
>    walk_gimple_seq (copy, replace_locals_stmt, replace_locals_op, &wi);
>
>    /* Clean up.  */
> -  pointer_map_destroy (id.decl_map);
> +  delete id.decl_map;
>    if (id.debug_map)
> -    pointer_map_destroy (id.debug_map);
> +    delete id.debug_map;
>
>    return copy;
>  }
> @@ -5145,7 +5140,7 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
>          *parg = new_tree;
>         parg = &DECL_CHAIN (new_tree);
>        }
> -    else if (!pointer_map_contains (id->decl_map, arg))
> +    else if (!id->decl_map->get (arg))
>        {
>         /* Make an equivalent VAR_DECL.  If the argument was used
>            as temporary variable later in function, the uses will be
> @@ -5368,7 +5363,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
>    /* Generate a new name for the new version. */
>    id.statements_to_fold = new hash_set<gimple>;
>
> -  id.decl_map = pointer_map_create ();
> +  id.decl_map = new hash_map<tree, tree>;
>    id.debug_map = NULL;
>    id.src_fn = old_decl;
>    id.dst_fn = new_decl;
> @@ -5530,9 +5525,9 @@ tree_function_versioning (tree old_decl, tree new_decl,
>      }
>
>    /* Clean up.  */
> -  pointer_map_destroy (id.decl_map);
> +  delete id.decl_map;
>    if (id.debug_map)
> -    pointer_map_destroy (id.debug_map);
> +    delete id.debug_map;
>    free_dominance_info (CDI_DOMINATORS);
>    free_dominance_info (CDI_POST_DOMINATORS);
>
> @@ -5587,22 +5582,22 @@ maybe_inline_call_in_expr (tree exp)
>    /* We can only try to inline "const" functions.  */
>    if (fn && TREE_READONLY (fn) && DECL_SAVED_TREE (fn))
>      {
> -      struct pointer_map_t *decl_map = pointer_map_create ();
>        call_expr_arg_iterator iter;
>        copy_body_data id;
>        tree param, arg, t;
> +      hash_map<tree, tree> decl_map;
>
>        /* Remap the parameters.  */
>        for (param = DECL_ARGUMENTS (fn), arg = first_call_expr_arg (exp, &iter);
>            param;
>            param = DECL_CHAIN (param), arg = next_call_expr_arg (&iter))
> -       *pointer_map_insert (decl_map, param) = arg;
> +       decl_map.put (param, arg);
>
>        memset (&id, 0, sizeof (id));
>        id.src_fn = fn;
>        id.dst_fn = current_function_decl;
>        id.src_cfun = DECL_STRUCT_FUNCTION (fn);
> -      id.decl_map = decl_map;
> +      id.decl_map = &decl_map;
>
>        id.copy_decl = copy_decl_no_change;
>        id.transform_call_graph_edges = CB_CGE_DUPLICATE;
> @@ -5620,7 +5615,6 @@ maybe_inline_call_in_expr (tree exp)
>        id.eh_lp_nr = 0;
>
>        t = copy_tree_body (&id);
> -      pointer_map_destroy (decl_map);
>
>        /* We can only return something suitable for use in a GENERIC
>          expression tree.  */
> @@ -5642,15 +5636,15 @@ build_duplicate_type (tree type)
>    id.src_fn = current_function_decl;
>    id.dst_fn = current_function_decl;
>    id.src_cfun = cfun;
> -  id.decl_map = pointer_map_create ();
> +  id.decl_map = new hash_map<tree, tree>;
>    id.debug_map = NULL;
>    id.copy_decl = copy_decl_no_change;
>
>    type = remap_type_1 (type, &id);
>
> -  pointer_map_destroy (id.decl_map);
> +  delete id.decl_map;
>    if (id.debug_map)
> -    pointer_map_destroy (id.debug_map);
> +    delete id.debug_map;
>
>    TYPE_CANONICAL (type) = type;
>
> diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
> index c13e6c7..53059da 100644
> --- a/gcc/tree-inline.h
> +++ b/gcc/tree-inline.h
> @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
>  #ifndef GCC_TREE_INLINE_H
>  #define GCC_TREE_INLINE_H
>
> +#include "hash-map.h"
>  #include "hash-set.h"
>
>  struct cgraph_edge;
> @@ -64,7 +65,7 @@ struct copy_body_data
>
>    /* The map from local declarations in the inlined function to
>       equivalents in the function into which it is being inlined.  */
> -  struct pointer_map_t *decl_map;
> +  hash_map<tree, tree> *decl_map;
>
>    /* Create a new decl to replace DECL in the destination function.  */
>    tree (*copy_decl) (tree, struct copy_body_data *);
> @@ -81,7 +82,7 @@ struct copy_body_data
>
>    /* Maps region and landing pad structures from the function being copied
>       to duplicates created within the function we inline into.  */
> -  struct pointer_map_t *eh_map;
> +  hash_map<void *, void *> *eh_map;
>
>    /* We use the same mechanism do all sorts of different things.  Rather
>       than enumerating the different cases, we categorize the behavior
> @@ -132,7 +133,7 @@ struct copy_body_data
>       equivalents in the function into which it is being inlined, where
>       the originals have been mapped to a value rather than to a
>       variable.  */
> -  struct pointer_map_t *debug_map;
> +  hash_map<tree, tree> *debug_map;
>
>    /* Cilk keywords currently need to replace some variables that
>       ordinary nested functions do not.  */
> diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
> index 45c5cf7..7d5c039 100644
> --- a/gcc/tree-nested.c
> +++ b/gcc/tree-nested.c
> @@ -93,8 +93,8 @@ struct nesting_info
>    struct nesting_info *inner;
>    struct nesting_info *next;
>
> -  struct pointer_map_t *field_map;
> -  struct pointer_map_t *var_map;
> +  hash_map<tree, tree> *field_map;
> +  hash_map<tree, tree> *var_map;
>    hash_set<tree *> *mem_refs;
>    bitmap suppress_expansion;
>
> @@ -286,15 +286,13 @@ static tree
>  lookup_field_for_decl (struct nesting_info *info, tree decl,
>                        enum insert_option insert)
>  {
> -  void **slot;
> -
>    if (insert == NO_INSERT)
>      {
> -      slot = pointer_map_contains (info->field_map, decl);
> -      return slot ? (tree) *slot : NULL_TREE;
> +      tree *slot = info->field_map->get (decl);
> +      return slot ? *slot : NULL_TREE;
>      }
>
> -  slot = pointer_map_insert (info->field_map, decl);
> +  tree *slot = &info->field_map->get_or_insert (decl);
>    if (!*slot)
>      {
>        tree field = make_node (FIELD_DECL);
> @@ -324,7 +322,7 @@ lookup_field_for_decl (struct nesting_info *info, tree decl,
>         info->any_parm_remapped = true;
>      }
>
> -  return (tree) *slot;
> +  return *slot;
>  }
>
>  /* Build or return the variable that holds the static chain within
> @@ -521,15 +519,13 @@ static tree
>  lookup_tramp_for_decl (struct nesting_info *info, tree decl,
>                        enum insert_option insert)
>  {
> -  void **slot;
> -
>    if (insert == NO_INSERT)
>      {
> -      slot = pointer_map_contains (info->var_map, decl);
> -      return slot ? (tree) *slot : NULL_TREE;
> +      tree *slot = info->var_map->get (decl);
> +      return slot ? *slot : NULL_TREE;
>      }
>
> -  slot = pointer_map_insert (info->var_map, decl);
> +  tree *slot = &info->var_map->get_or_insert (decl);
>    if (!*slot)
>      {
>        tree field = make_node (FIELD_DECL);
> @@ -543,7 +539,7 @@ lookup_tramp_for_decl (struct nesting_info *info, tree decl,
>        info->any_tramp_created = true;
>      }
>
> -  return (tree) *slot;
> +  return *slot;
>  }
>
>  /* Build or return the field within the non-local frame state that holds
> @@ -730,8 +726,8 @@ static struct nesting_info *
>  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->field_map = new hash_map<tree, tree>;
> +  info->var_map = new hash_map<tree, tree>;
>    info->mem_refs = new hash_set<tree *>;
>    info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
>    info->context = cgn->decl;
> @@ -834,12 +830,11 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
>    tree target_context;
>    struct nesting_info *i;
>    tree x, field, new_decl;
> -  void **slot;
>
> -  slot = pointer_map_insert (info->var_map, decl);
> +  tree *slot = &info->var_map->get_or_insert (decl);
>
>    if (*slot)
> -    return (tree) *slot;
> +    return *slot;
>
>    target_context = decl_function_context (decl);
>
> @@ -1483,11 +1478,10 @@ static tree
>  get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
>  {
>    tree x, new_decl;
> -  void **slot;
>
> -  slot = pointer_map_insert (info->var_map, decl);
> +  tree *slot = &info->var_map->get_or_insert (decl);
>    if (*slot)
> -    return (tree) *slot;
> +    return *slot;
>
>    /* Make sure frame_decl gets created.  */
>    (void) get_frame_type (info);
> @@ -2064,7 +2058,6 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
>  {
>    struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
>    tree label, new_label, target_context, x, field;
> -  void **slot;
>    gimple call;
>    gimple stmt = gsi_stmt (*gsi);
>
> @@ -2098,7 +2091,7 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
>       (hairy target-specific) non-local goto receiver code to be generated
>       when we expand rtl.  Enter this association into var_map so that we
>       can insert the new label into the IL during a second pass.  */
> -  slot = pointer_map_insert (i->var_map, label);
> +  tree *slot = &i->var_map->get_or_insert (label);
>    if (*slot == NULL)
>      {
>        new_label = create_artificial_label (UNKNOWN_LOCATION);
> @@ -2106,7 +2099,7 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
>        *slot = new_label;
>      }
>    else
> -    new_label = (tree) *slot;
> +    new_label = *slot;
>
>    /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field).  */
>    field = get_nl_goto_field (i);
> @@ -2136,7 +2129,6 @@ convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
>    struct nesting_info *const info = (struct nesting_info *) wi->info;
>    tree label, new_label;
>    gimple_stmt_iterator tmp_gsi;
> -  void **slot;
>    gimple stmt = gsi_stmt (*gsi);
>
>    if (gimple_code (stmt) != GIMPLE_LABEL)
> @@ -2147,7 +2139,7 @@ convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
>
>    label = gimple_label_label (stmt);
>
> -  slot = pointer_map_contains (info->var_map, label);
> +  tree *slot = info->var_map->get (label);
>    if (!slot)
>      {
>        *handled_ops_p = false;
> @@ -2513,7 +2505,7 @@ static tree
>  nesting_copy_decl (tree decl, copy_body_data *id)
>  {
>    struct nesting_copy_body_data *nid = (struct nesting_copy_body_data *) id;
> -  void **slot = pointer_map_contains (nid->root->var_map, decl);
> +  tree *slot = nid->root->var_map->get (decl);
>
>    if (slot)
>      return (tree) *slot;
> @@ -2542,15 +2534,14 @@ contains_remapped_vars (tree *tp, int *walk_subtrees, void *data)
>  {
>    struct nesting_info *root = (struct nesting_info *) data;
>    tree t = *tp;
> -  void **slot;
>
>    if (DECL_P (t))
>      {
>        *walk_subtrees = 0;
> -      slot = pointer_map_contains (root->var_map, t);
> +      tree *slot = root->var_map->get (t);
>
>        if (slot)
> -       return (tree) *slot;
> +       return *slot;
>      }
>    return NULL;
>  }
> @@ -2580,7 +2571,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
>               && variably_modified_type_p (type, NULL)))
>           continue;
>
> -       if (pointer_map_contains (root->var_map, TREE_OPERAND (val, 0))
> +       if (root->var_map->get (TREE_OPERAND (val, 0))
>             || walk_tree (&type, contains_remapped_vars, root, NULL))
>           break;
>        }
> @@ -2590,7 +2581,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
>
>    memset (&id, 0, sizeof (id));
>    id.cb.copy_decl = nesting_copy_decl;
> -  id.cb.decl_map = pointer_map_create ();
> +  id.cb.decl_map = new hash_map<tree, tree>;
>    id.root = root;
>
>    for (; var; var = DECL_CHAIN (var))
> @@ -2598,7 +2589,6 @@ remap_vla_decls (tree block, struct nesting_info *root)
>        {
>         struct nesting_info *i;
>         tree newt, context;
> -       void **slot;
>
>         val = DECL_VALUE_EXPR (var);
>         type = TREE_TYPE (var);
> @@ -2608,7 +2598,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
>               && variably_modified_type_p (type, NULL)))
>           continue;
>
> -       slot = pointer_map_contains (root->var_map, TREE_OPERAND (val, 0));
> +       tree *slot = root->var_map->get (TREE_OPERAND (val, 0));
>         if (!slot && !walk_tree (&type, contains_remapped_vars, root, NULL))
>           continue;
>
> @@ -2651,7 +2641,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
>           SET_DECL_VALUE_EXPR (var, val);
>        }
>
> -  pointer_map_destroy (id.cb.decl_map);
> +  delete id.cb.decl_map;
>  }
>
>  /* Fold the MEM_REF *E.  */
> @@ -2830,7 +2820,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
>
>           memset (&id, 0, sizeof (id));
>           id.cb.copy_decl = nesting_copy_decl;
> -         id.cb.decl_map = pointer_map_create ();
> +         id.cb.decl_map = new hash_map<tree, tree>;
>           id.root = root;
>
>           for (; debug_var; debug_var = DECL_CHAIN (debug_var))
> @@ -2865,7 +2855,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
>                   TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
>               }
>
> -         pointer_map_destroy (id.cb.decl_map);
> +         delete id.cb.decl_map;
>         }
>
>        scope = gimple_seq_first_stmt (gimple_body (root->context));
> @@ -2931,8 +2921,8 @@ free_nesting_tree (struct nesting_info *root)
>    do
>      {
>        next = iter_nestinfo_next (node);
> -      pointer_map_destroy (node->var_map);
> -      pointer_map_destroy (node->field_map);
> +      delete node->var_map;
> +      delete node->field_map;
>        delete node->mem_refs;
>        free (node);
>        node = next;
> diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> index f9d39ac..2231314 100644
> --- a/gcc/tree-sra.c
> +++ b/gcc/tree-sra.c
> @@ -74,11 +74,11 @@ along with GCC; see the file COPYING3.  If not see
>  #include "config.h"
>  #include "system.h"
>  #include "coretypes.h"
> +#include "hash-map.h"
>  #include "hash-table.h"
>  #include "alloc-pool.h"
>  #include "tm.h"
>  #include "tree.h"
> -#include "pointer-set.h"
>  #include "basic-block.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
> @@ -290,7 +290,7 @@ struct assign_link
>  static alloc_pool link_pool;
>
>  /* Base (tree) -> Vector (vec<access_p> *) map.  */
> -static struct pointer_map_t *base_access_vec;
> +static hash_map<tree, auto_vec<access_p> > *base_access_vec;
>
>  /* Candidate hash table helpers.  */
>
> @@ -518,13 +518,7 @@ access_has_replacements_p (struct access *acc)
>  static vec<access_p> *
>  get_base_access_vector (tree base)
>  {
> -  void **slot;
> -
> -  slot = pointer_map_contains (base_access_vec, base);
> -  if (!slot)
> -    return NULL;
> -  else
> -    return *(vec<access_p> **) slot;
> +  return base_access_vec->get (base);
>  }
>
>  /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
> @@ -667,24 +661,13 @@ sra_initialize (void)
>    gcc_obstack_init (&name_obstack);
>    access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
>    link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
> -  base_access_vec = pointer_map_create ();
> +  base_access_vec = new hash_map<tree, auto_vec<access_p> >;
>    memset (&sra_stats, 0, sizeof (sra_stats));
>    encountered_apply_args = false;
>    encountered_recursive_call = false;
>    encountered_unchangable_recursive_call = false;
>  }
>
> -/* Hook fed to pointer_map_traverse, deallocate stored vectors.  */
> -
> -static bool
> -delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
> -                    void *data ATTRIBUTE_UNUSED)
> -{
> -  vec<access_p> *access_vec = (vec<access_p> *) *value;
> -  vec_free (access_vec);
> -  return true;
> -}
> -
>  /* Deallocate all general structures.  */
>
>  static void
> @@ -699,8 +682,7 @@ sra_deinitialize (void)
>    free_alloc_pool (link_pool);
>    obstack_free (&name_obstack, NULL);
>
> -  pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
> -  pointer_map_destroy (base_access_vec);
> +  delete base_access_vec;
>  }
>
>  /* Remove DECL from candidates for SRA and write REASON to the dump file if
> @@ -849,9 +831,7 @@ mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
>  static struct access *
>  create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
>  {
> -  vec<access_p> *v;
>    struct access *access;
> -  void **slot;
>
>    access = (struct access *) pool_alloc (access_pool);
>    memset (access, 0, sizeof (struct access));
> @@ -859,16 +839,7 @@ create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
>    access->offset = offset;
>    access->size = size;
>
> -  slot = pointer_map_contains (base_access_vec, base);
> -  if (slot)
> -    v = (vec<access_p> *) *slot;
> -  else
> -    vec_alloc (v, 32);
> -
> -  v->safe_push (access);
> -
> -  *((vec<access_p> **)
> -       pointer_map_insert (base_access_vec, base)) = v;
> +  base_access_vec->get_or_insert (base).safe_push (access);
>
>    return access;
>  }
> diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
> index c614978..0cbb3ae 100644
> --- a/gcc/tree-ssa-loop-im.c
> +++ b/gcc/tree-ssa-loop-im.c
> @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "basic-block.h"
>  #include "gimple-pretty-print.h"
>  #include "pointer-set.h"
> +#include "hash-map.h"
>  #include "hash-table.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
> @@ -103,7 +104,7 @@ struct lim_aux_data
>
>  /* Maps statements to their lim_aux_data.  */
>
> -static struct pointer_map_t *lim_aux_data_map;
> +static hash_map<gimple, lim_aux_data *> *lim_aux_data_map;
>
>  /* Description of a memory reference location.  */
>
> @@ -225,20 +226,20 @@ static bool ref_indep_loop_p (struct loop *, mem_ref_p);
>  static struct lim_aux_data *
>  init_lim_data (gimple stmt)
>  {
> -  void **p = pointer_map_insert (lim_aux_data_map, stmt);
> +  lim_aux_data *p = XCNEW (struct lim_aux_data);
> +  lim_aux_data_map->put (stmt, p);
>
> -  *p = XCNEW (struct lim_aux_data);
> -  return (struct lim_aux_data *) *p;
> +  return p;
>  }
>
>  static struct lim_aux_data *
>  get_lim_data (gimple stmt)
>  {
> -  void **p = pointer_map_contains (lim_aux_data_map, stmt);
> +  lim_aux_data **p = lim_aux_data_map->get (stmt);
>    if (!p)
>      return NULL;
>
> -  return (struct lim_aux_data *) *p;
> +  return *p;
>  }
>
>  /* Releases the memory occupied by DATA.  */
> @@ -253,11 +254,11 @@ free_lim_aux_data (struct lim_aux_data *data)
>  static void
>  clear_lim_data (gimple stmt)
>  {
> -  void **p = pointer_map_contains (lim_aux_data_map, stmt);
> +  lim_aux_data **p = lim_aux_data_map->get (stmt);
>    if (!p)
>      return;
>
> -  free_lim_aux_data ((struct lim_aux_data *) *p);
> +  free_lim_aux_data (*p);
>    *p = NULL;
>  }
>
> @@ -2429,7 +2430,7 @@ tree_ssa_lim_initialize (void)
>
>    bitmap_obstack_initialize (&lim_bitmap_obstack);
>    gcc_obstack_init (&mem_ref_obstack);
> -  lim_aux_data_map = pointer_map_create ();
> +  lim_aux_data_map = new hash_map<gimple, lim_aux_data *>;
>
>    if (flag_tm)
>      compute_transaction_bits ();
> @@ -2484,7 +2485,7 @@ tree_ssa_lim_finalize (void)
>      SET_ALWAYS_EXECUTED_IN (bb, NULL);
>
>    bitmap_obstack_release (&lim_bitmap_obstack);
> -  pointer_map_destroy (lim_aux_data_map);
> +  delete lim_aux_data_map;
>
>    delete memory_accesses.refs;
>    memory_accesses.refs = NULL;
> diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
> index 3b4a6cd..158a081 100644
> --- a/gcc/tree-ssa-loop-ivopts.c
> +++ b/gcc/tree-ssa-loop-ivopts.c
> @@ -70,7 +70,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tm_p.h"
>  #include "basic-block.h"
>  #include "gimple-pretty-print.h"
> -#include "pointer-set.h"
> +#include "hash-map.h"
>  #include "hash-table.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
> @@ -293,7 +293,7 @@ struct ivopts_data
>    struct loop *current_loop;
>
>    /* Numbers of iterations for all exits of the current loop.  */
> -  struct pointer_map_t *niters;
> +  hash_map<edge, tree_niter_desc *> *niters;
>
>    /* Number of registers used in it.  */
>    unsigned regs_used;
> @@ -814,15 +814,15 @@ static struct tree_niter_desc *
>  niter_for_exit (struct ivopts_data *data, edge exit)
>  {
>    struct tree_niter_desc *desc;
> -  void **slot;
> +  tree_niter_desc **slot;
>
>    if (!data->niters)
>      {
> -      data->niters = pointer_map_create ();
> +      data->niters = new hash_map<edge, tree_niter_desc *>;
>        slot = NULL;
>      }
>    else
> -    slot = pointer_map_contains (data->niters, exit);
> +    slot = data->niters->get (exit);
>
>    if (!slot)
>      {
> @@ -837,11 +837,10 @@ niter_for_exit (struct ivopts_data *data, edge exit)
>           XDELETE (desc);
>           desc = NULL;
>         }
> -      slot = pointer_map_insert (data->niters, exit);
> -      *slot = desc;
> +      data->niters->put (exit, desc);
>      }
>    else
> -    desc = (struct tree_niter_desc *) *slot;
> +    desc = *slot;
>
>    return desc;
>  }
> @@ -6704,15 +6703,12 @@ remove_unused_ivs (struct ivopts_data *data)
>  }
>
>  /* Frees memory occupied by struct tree_niter_desc in *VALUE. Callback
> -   for pointer_map_traverse.  */
> +   for hash_map::traverse.  */
>
> -static bool
> -free_tree_niter_desc (const void *key ATTRIBUTE_UNUSED, void **value,
> -                      void *data ATTRIBUTE_UNUSED)
> +bool
> +free_tree_niter_desc (edge const &, tree_niter_desc *const &value, void *)
>  {
> -  struct tree_niter_desc *const niter = (struct tree_niter_desc *) *value;
> -
> -  free (niter);
> +  free (value);
>    return true;
>  }
>
> @@ -6727,8 +6723,8 @@ free_loop_data (struct ivopts_data *data)
>
>    if (data->niters)
>      {
> -      pointer_map_traverse (data->niters, free_tree_niter_desc, NULL);
> -      pointer_map_destroy (data->niters);
> +      data->niters->traverse<void *, free_tree_niter_desc> (NULL);
> +      delete data->niters;
>        data->niters = NULL;
>      }
>
> diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
> index f9bd9a4..2e8337c 100644
> --- a/gcc/tree-ssa-reassoc.c
> +++ b/gcc/tree-ssa-reassoc.c
> @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "basic-block.h"
>  #include "gimple-pretty-print.h"
>  #include "tree-inline.h"
> -#include "pointer-set.h"
> +#include "hash-map.h"
>  #include "tree-ssa-alias.h"
>  #include "internal-fn.h"
>  #include "gimple-fold.h"
> @@ -216,7 +216,7 @@ static int next_operand_entry_id;
>  static long *bb_rank;
>
>  /* Operand->rank hashtable.  */
> -static struct pointer_map_t *operand_rank;
> +static hash_map<tree, long> *operand_rank;
>
>  /* Forward decls.  */
>  static long get_rank (tree);
> @@ -362,8 +362,8 @@ propagate_rank (long rank, tree op)
>  static inline long
>  find_operand_rank (tree e)
>  {
> -  void **slot = pointer_map_contains (operand_rank, e);
> -  return slot ? (long) (intptr_t) *slot : -1;
> +  long *slot = operand_rank->get (e);
> +  return slot ? *slot : -1;
>  }
>
>  /* Insert {E,RANK} into the operand rank hashtable.  */
> @@ -371,11 +371,8 @@ find_operand_rank (tree e)
>  static inline void
>  insert_operand_rank (tree e, long rank)
>  {
> -  void **slot;
>    gcc_assert (rank > 0);
> -  slot = pointer_map_insert (operand_rank, e);
> -  gcc_assert (!*slot);
> -  *slot = (void *) (intptr_t) rank;
> +  gcc_assert (!operand_rank->put (e, rank));
>  }
>
>  /* Given an expression E, return the rank of the expression.  */
> @@ -4635,7 +4632,7 @@ init_reassoc (void)
>       deeper loops come later.  */
>    pre_and_rev_post_order_compute (NULL, bbs, false);
>    bb_rank = XCNEWVEC (long, last_basic_block_for_fn (cfun));
> -  operand_rank = pointer_map_create ();
> +  operand_rank = new hash_map<tree, long>;
>
>    /* Give each default definition a distinct rank.  This includes
>       parameters and the static chain.  Walk backwards over all
> @@ -4676,7 +4673,7 @@ fini_reassoc (void)
>    statistics_counter_event (cfun, "Built-in powi calls created",
>                             reassociate_stats.pows_created);
>
> -  pointer_map_destroy (operand_rank);
> +  delete operand_rank;
>    free_alloc_pool (operand_entry_pool);
>    free (bb_rank);
>    plus_negates.release ();
> diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
> index 1879fc0..08e384b 100644
> --- a/gcc/tree-ssa-structalias.c
> +++ b/gcc/tree-ssa-structalias.c
> @@ -319,7 +319,7 @@ static inline bool type_can_have_subvars (const_tree);
>  static alloc_pool variable_info_pool;
>
>  /* Map varinfo to final pt_solution.  */
> -static pointer_map_t *final_solutions;
> +static hash_map<varinfo_t, pt_solution *> *final_solutions;
>  struct obstack final_solutions_obstack;
>
>  /* Table of variable info structures for constraint variables.
> @@ -393,19 +393,19 @@ new_var_info (tree t, const char *name)
>
>  /* A map mapping call statements to per-stmt variables for uses
>     and clobbers specific to the call.  */
> -static struct pointer_map_t *call_stmt_vars;
> +static hash_map<gimple, varinfo_t> *call_stmt_vars;
>
>  /* Lookup or create the variable for the call statement CALL.  */
>
>  static varinfo_t
>  get_call_vi (gimple call)
>  {
> -  void **slot_p;
>    varinfo_t vi, vi2;
>
> -  slot_p = pointer_map_insert (call_stmt_vars, call);
> -  if (*slot_p)
> -    return (varinfo_t) *slot_p;
> +  bool existed;
> +  varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
> +  if (existed)
> +    return *slot_p;
>
>    vi = new_var_info (NULL_TREE, "CALLUSED");
>    vi->offset = 0;
> @@ -421,7 +421,7 @@ get_call_vi (gimple call)
>
>    vi->next = vi2->id;
>
> -  *slot_p = (void *) vi;
> +  *slot_p = vi;
>    return vi;
>  }
>
> @@ -431,11 +431,9 @@ get_call_vi (gimple call)
>  static varinfo_t
>  lookup_call_use_vi (gimple call)
>  {
> -  void **slot_p;
> -
> -  slot_p = pointer_map_contains (call_stmt_vars, call);
> +  varinfo_t *slot_p = call_stmt_vars->get (call);
>    if (slot_p)
> -    return (varinfo_t) *slot_p;
> +    return *slot_p;
>
>    return NULL;
>  }
> @@ -2794,7 +2792,7 @@ solve_graph (constraint_graph_t graph)
>  }
>
>  /* Map from trees to variable infos.  */
> -static struct pointer_map_t *vi_for_tree;
> +static hash_map<tree, varinfo_t> *vi_for_tree;
>
>
>  /* Insert ID as the variable id for tree T in the vi_for_tree map.  */
> @@ -2802,10 +2800,8 @@ static struct pointer_map_t *vi_for_tree;
>  static void
>  insert_vi_for_tree (tree t, varinfo_t vi)
>  {
> -  void **slot = pointer_map_insert (vi_for_tree, t);
>    gcc_assert (vi);
> -  gcc_assert (*slot == NULL);
> -  *slot = vi;
> +  gcc_assert (!vi_for_tree->put (t, vi));
>  }
>
>  /* Find the variable info for tree T in VI_FOR_TREE.  If T does not
> @@ -2814,11 +2810,11 @@ insert_vi_for_tree (tree t, varinfo_t vi)
>  static varinfo_t
>  lookup_vi_for_tree (tree t)
>  {
> -  void **slot = pointer_map_contains (vi_for_tree, t);
> +  varinfo_t *slot = vi_for_tree->get (t);
>    if (slot == NULL)
>      return NULL;
>
> -  return (varinfo_t) *slot;
> +  return *slot;
>  }
>
>  /* Return a printable name for DECL  */
> @@ -2876,11 +2872,11 @@ alias_get_name (tree decl)
>  static varinfo_t
>  get_vi_for_tree (tree t)
>  {
> -  void **slot = pointer_map_contains (vi_for_tree, t);
> +  varinfo_t *slot = vi_for_tree->get (t);
>    if (slot == NULL)
>      return get_varinfo (create_variable_info_for (t, alias_get_name (t)));
>
> -  return (varinfo_t) *slot;
> +  return *slot;
>  }
>
>  /* Get a scalar constraint expression for a new temporary variable.  */
> @@ -6075,7 +6071,6 @@ find_what_var_points_to (varinfo_t orig_vi)
>    bitmap finished_solution;
>    bitmap result;
>    varinfo_t vi;
> -  void **slot;
>    struct pt_solution *pt;
>
>    /* This variable may have been collapsed, let's get the real
> @@ -6083,9 +6078,9 @@ find_what_var_points_to (varinfo_t orig_vi)
>    vi = get_varinfo (find (orig_vi->id));
>
>    /* See if we have already computed the solution and return it.  */
> -  slot = pointer_map_insert (final_solutions, vi);
> +  pt_solution **slot = &final_solutions->get_or_insert (vi);
>    if (*slot != NULL)
> -    return *(struct pt_solution *)*slot;
> +    return **slot;
>
>    *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution);
>    memset (pt, 0, sizeof (struct pt_solution));
> @@ -6685,8 +6680,8 @@ init_alias_vars (void)
>                                           sizeof (struct variable_info), 30);
>    constraints.create (8);
>    varmap.create (8);
> -  vi_for_tree = pointer_map_create ();
> -  call_stmt_vars = pointer_map_create ();
> +  vi_for_tree = new hash_map<tree, varinfo_t>;
> +  call_stmt_vars = new hash_map<gimple, varinfo_t>;
>
>    memset (&stats, 0, sizeof (stats));
>    shared_bitmap_table = new hash_table<shared_bitmap_hasher> (511);
> @@ -6694,7 +6689,7 @@ init_alias_vars (void)
>
>    gcc_obstack_init (&fake_var_decl_obstack);
>
> -  final_solutions = pointer_map_create ();
> +  final_solutions = new hash_map<varinfo_t, pt_solution *>;
>    gcc_obstack_init (&final_solutions_obstack);
>  }
>
> @@ -6943,8 +6938,8 @@ delete_points_to_sets (void)
>      fprintf (dump_file, "Points to sets created:%d\n",
>              stats.points_to_sets_created);
>
> -  pointer_map_destroy (vi_for_tree);
> -  pointer_map_destroy (call_stmt_vars);
> +  delete vi_for_tree;
> +  delete call_stmt_vars;
>    bitmap_obstack_release (&pta_obstack);
>    constraints.release ();
>
> @@ -6965,7 +6960,7 @@ delete_points_to_sets (void)
>
>    obstack_free (&fake_var_decl_obstack, NULL);
>
> -  pointer_map_destroy (final_solutions);
> +  delete final_solutions;
>    obstack_free (&final_solutions_obstack, NULL);
>  }
>
> diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
> index 73a4d1c..217b9fc 100644
> --- a/gcc/tree-ssa.c
> +++ b/gcc/tree-ssa.c
> @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "tree-into-ssa.h"
>  #include "tree-ssa.h"
>  #include "tree-inline.h"
> +#include "hash-map.h"
>  #include "hashtab.h"
>  #include "tree-pass.h"
>  #include "diagnostic-core.h"
> @@ -56,7 +57,7 @@ along with GCC; see the file COPYING3.  If not see
>  #include "cfgexpand.h"
>
>  /* Pointer map of variable mappings, keyed by edge.  */
> -static struct pointer_map_t *edge_var_maps;
> +static hash_map<edge, auto_vec<edge_var_map> > *edge_var_maps;
>
>
>  /* Add a mapping with PHI RESULT and PHI DEF associated with edge E.  */
> @@ -64,23 +65,17 @@ static struct pointer_map_t *edge_var_maps;
>  void
>  redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
>  {
> -  void **slot;
> -  edge_var_map_vector *head;
>    edge_var_map new_node;
>
>    if (edge_var_maps == NULL)
> -    edge_var_maps = pointer_map_create ();
> +    edge_var_maps = new hash_map<edge, auto_vec<edge_var_map> >;
>
> -  slot = pointer_map_insert (edge_var_maps, e);
> -  head = (edge_var_map_vector *) *slot;
> -  if (!head)
> -    vec_safe_reserve (head, 5);
> +  auto_vec<edge_var_map> &slot = edge_var_maps->get_or_insert (e);
>    new_node.def = def;
>    new_node.result = result;
>    new_node.locus = locus;
>
> -  vec_safe_push (head, new_node);
> -  *slot = head;
> +  slot.safe_push (new_node);
>  }
>
>
> @@ -89,82 +84,51 @@ redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
>  void
>  redirect_edge_var_map_clear (edge e)
>  {
> -  void **slot;
> -  edge_var_map_vector *head;
> -
>    if (!edge_var_maps)
>      return;
>
> -  slot = pointer_map_contains (edge_var_maps, e);
> +  auto_vec<edge_var_map> *head = edge_var_maps->get (e);
>
> -  if (slot)
> -    {
> -      head = (edge_var_map_vector *) *slot;
> -      vec_free (head);
> -      *slot = NULL;
> -    }
> +  if (head)
> +    head->release ();
>  }
>
>
>  /* Duplicate the redirected var mappings in OLDE in NEWE.
>
> -   Since we can't remove a mapping, let's just duplicate it.  This assumes a
> -   pointer_map can have multiple edges mapping to the same var_map (many to
> -   one mapping), since we don't remove the previous mappings.  */
> +   This assumes a hash_map can have multiple edges mapping to the same
> +   var_map (many to one mapping), since we don't remove the previous mappings.
> +   */
>
>  void
>  redirect_edge_var_map_dup (edge newe, edge olde)
>  {
> -  void **new_slot, **old_slot;
> -  edge_var_map_vector *head;
> -
>    if (!edge_var_maps)
>      return;
>
> -  new_slot = pointer_map_insert (edge_var_maps, newe);
> -  old_slot = pointer_map_contains (edge_var_maps, olde);
> -  if (!old_slot)
> +  auto_vec<edge_var_map> *head = edge_var_maps->get (olde);
> +  if (!head)
>      return;
> -  head = (edge_var_map_vector *) *old_slot;
>
> -  edge_var_map_vector *new_head = NULL;
> -  if (head)
> -    new_head = vec_safe_copy (head);
> -  else
> -    vec_safe_reserve (new_head, 5);
> -  *new_slot = new_head;
> +  edge_var_maps->get_or_insert (newe).safe_splice (*head);
>  }
>
>
>  /* Return the variable mappings for a given edge.  If there is none, return
>     NULL.  */
>
> -edge_var_map_vector *
> +vec<edge_var_map> *
>  redirect_edge_var_map_vector (edge e)
>  {
> -  void **slot;
> -
>    /* Hey, what kind of idiot would... you'd be surprised.  */
>    if (!edge_var_maps)
>      return NULL;
>
> -  slot = pointer_map_contains (edge_var_maps, e);
> +  auto_vec<edge_var_map> *slot = edge_var_maps->get (e);
>    if (!slot)
>      return NULL;
>
> -  return (edge_var_map_vector *) *slot;
> -}
> -
> -/* Used by redirect_edge_var_map_destroy to free all memory.  */
> -
> -static bool
> -free_var_map_entry (const void *key ATTRIBUTE_UNUSED,
> -                   void **value,
> -                   void *data ATTRIBUTE_UNUSED)
> -{
> -  edge_var_map_vector *head = (edge_var_map_vector *) *value;
> -  vec_free (head);
> -  return true;
> +  return slot;
>  }
>
>  /* Clear the edge variable mappings.  */
> @@ -172,12 +136,8 @@ free_var_map_entry (const void *key ATTRIBUTE_UNUSED,
>  void
>  redirect_edge_var_map_destroy (void)
>  {
> -  if (edge_var_maps)
> -    {
> -      pointer_map_traverse (edge_var_maps, free_var_map_entry, NULL);
> -      pointer_map_destroy (edge_var_maps);
> -      edge_var_maps = NULL;
> -    }
> +  delete edge_var_maps;
> +  edge_var_maps = NULL;
>  }
>
>
> @@ -223,12 +183,11 @@ void
>  flush_pending_stmts (edge e)
>  {
>    gimple phi;
> -  edge_var_map_vector *v;
>    edge_var_map *vm;
>    int i;
>    gimple_stmt_iterator gsi;
>
> -  v = redirect_edge_var_map_vector (e);
> +  vec<edge_var_map> *v = redirect_edge_var_map_vector (e);
>    if (!v)
>      return;
>
> diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h
> index c866206..835686c 100644
> --- a/gcc/tree-ssa.h
> +++ b/gcc/tree-ssa.h
> @@ -35,7 +35,7 @@ typedef vec<edge_var_map, va_heap, vl_embed> edge_var_map_vector;
>  extern void redirect_edge_var_map_add (edge, tree, tree, source_location);
>  extern void redirect_edge_var_map_clear (edge);
>  extern void redirect_edge_var_map_dup (edge, edge);
> -extern edge_var_map_vector *redirect_edge_var_map_vector (edge);
> +extern vec<edge_var_map> *redirect_edge_var_map_vector (edge);
>  extern void redirect_edge_var_map_destroy (void);
>  extern edge ssa_redirect_edge (edge, basic_block);
>  extern void flush_pending_stmts (edge);
> diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
> index 00810b9..3b72fce 100644
> --- a/gcc/var-tracking.c
> +++ b/gcc/var-tracking.c
> @@ -94,6 +94,7 @@
>  #include "varasm.h"
>  #include "stor-layout.h"
>  #include "pointer-set.h"
> +#include "hash-map.h"
>  #include "hash-table.h"
>  #include "basic-block.h"
>  #include "tm_p.h"
> @@ -2019,12 +2020,12 @@ vt_get_canonicalize_base (rtx loc)
>
>  /* This caches canonicalized addresses for VALUEs, computed using
>     information in the global cselib table.  */
> -static struct pointer_map_t *global_get_addr_cache;
> +static hash_map<rtx, rtx> *global_get_addr_cache;
>
>  /* This caches canonicalized addresses for VALUEs, computed using
>     information from the global cache and information pertaining to a
>     basic block being analyzed.  */
> -static struct pointer_map_t *local_get_addr_cache;
> +static hash_map<rtx, rtx> *local_get_addr_cache;
>
>  static rtx vt_canonicalize_addr (dataflow_set *, rtx);
>
> @@ -2036,13 +2037,13 @@ static rtx
>  get_addr_from_global_cache (rtx const loc)
>  {
>    rtx x;
> -  void **slot;
>
>    gcc_checking_assert (GET_CODE (loc) == VALUE);
>
> -  slot = pointer_map_insert (global_get_addr_cache, loc);
> -  if (*slot)
> -    return (rtx)*slot;
> +  bool existed;
> +  rtx *slot = &global_get_addr_cache->get_or_insert (loc, &existed);
> +  if (existed)
> +    return *slot;
>
>    x = canon_rtx (get_addr (loc));
>
> @@ -2056,8 +2057,7 @@ get_addr_from_global_cache (rtx const loc)
>         {
>           /* The table may have moved during recursion, recompute
>              SLOT.  */
> -         slot = pointer_map_contains (global_get_addr_cache, loc);
> -         *slot = x = nx;
> +         *global_get_addr_cache->get (loc) = x = nx;
>         }
>      }
>
> @@ -2072,16 +2072,16 @@ static rtx
>  get_addr_from_local_cache (dataflow_set *set, rtx const loc)
>  {
>    rtx x;
> -  void **slot;
>    decl_or_value dv;
>    variable var;
>    location_chain l;
>
>    gcc_checking_assert (GET_CODE (loc) == VALUE);
>
> -  slot = pointer_map_insert (local_get_addr_cache, loc);
> -  if (*slot)
> -    return (rtx)*slot;
> +  bool existed;
> +  rtx *slot = &local_get_addr_cache->get_or_insert (loc, &existed);
> +  if (existed)
> +    return *slot;
>
>    x = get_addr_from_global_cache (loc);
>
> @@ -2095,7 +2095,7 @@ get_addr_from_local_cache (dataflow_set *set, rtx const loc)
>        rtx nx = vt_canonicalize_addr (set, x);
>        if (nx != x)
>         {
> -         slot = pointer_map_contains (local_get_addr_cache, loc);
> +         slot = local_get_addr_cache->get (loc);
>           *slot = x = nx;
>         }
>        return x;
> @@ -2116,7 +2116,7 @@ get_addr_from_local_cache (dataflow_set *set, rtx const loc)
>           rtx nx = vt_canonicalize_addr (set, l->loc);
>           if (x != nx)
>             {
> -             slot = pointer_map_contains (local_get_addr_cache, loc);
> +             slot = local_get_addr_cache->get (loc);
>               *slot = x = nx;
>             }
>           break;
> @@ -2503,11 +2503,10 @@ val_store (dataflow_set *set, rtx val, rtx loc, rtx insn, bool modified)
>
>  /* Clear (canonical address) slots that reference X.  */
>
> -static bool
> -local_get_addr_clear_given_value (const void *v ATTRIBUTE_UNUSED,
> -                                 void **slot, void *x)
> +bool
> +local_get_addr_clear_given_value (rtx const &, rtx *slot, rtx x)
>  {
> -  if (vt_get_canonicalize_base ((rtx)*slot) == x)
> +  if (vt_get_canonicalize_base (*slot) == x)
>      *slot = NULL;
>    return true;
>  }
> @@ -2530,11 +2529,10 @@ val_reset (dataflow_set *set, decl_or_value dv)
>    if (var->onepart == ONEPART_VALUE)
>      {
>        rtx x = dv_as_value (dv);
> -      void **slot;
>
>        /* Relationships in the global cache don't change, so reset the
>          local cache entry only.  */
> -      slot = pointer_map_contains (local_get_addr_cache, x);
> +      rtx *slot = local_get_addr_cache->get (x);
>        if (slot)
>         {
>           /* If the value resolved back to itself, odds are that other
> @@ -2543,8 +2541,8 @@ val_reset (dataflow_set *set, decl_or_value dv)
>              old X but resolved to something else remain ok as long as
>              that something else isn't also reset.  */
>           if (*slot == x)
> -           pointer_map_traverse (local_get_addr_cache,
> -                                 local_get_addr_clear_given_value, x);
> +           local_get_addr_cache
> +             ->traverse<rtx, local_get_addr_clear_given_value> (x);
>           *slot = NULL;
>         }
>      }
> @@ -6660,7 +6658,7 @@ compute_bb_dataflow (basic_block bb)
>    dataflow_set_copy (out, in);
>
>    if (MAY_HAVE_DEBUG_INSNS)
> -    local_get_addr_cache = pointer_map_create ();
> +    local_get_addr_cache = new hash_map<rtx, rtx>;
>
>    FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
>      {
> @@ -6943,7 +6941,7 @@ compute_bb_dataflow (basic_block bb)
>
>    if (MAY_HAVE_DEBUG_INSNS)
>      {
> -      pointer_map_destroy (local_get_addr_cache);
> +      delete local_get_addr_cache;
>        local_get_addr_cache = NULL;
>
>        dataflow_set_equiv_regs (out);
> @@ -9477,13 +9475,13 @@ vt_emit_notes (void)
>        emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
>
>        if (MAY_HAVE_DEBUG_INSNS)
> -       local_get_addr_cache = pointer_map_create ();
> +       local_get_addr_cache = new hash_map<rtx, rtx>;
>
>        /* Emit the notes for the changes in the basic block itself.  */
>        emit_notes_in_bb (bb, &cur);
>
>        if (MAY_HAVE_DEBUG_INSNS)
> -       pointer_map_destroy (local_get_addr_cache);
> +       delete local_get_addr_cache;
>        local_get_addr_cache = NULL;
>
>        /* Free memory occupied by the in hash table, we won't need it
> @@ -9916,7 +9914,7 @@ vt_initialize (void)
>        valvar_pool = create_alloc_pool ("small variable_def pool",
>                                        sizeof (struct variable_def), 256);
>        preserved_values.create (256);
> -      global_get_addr_cache = pointer_map_create ();
> +      global_get_addr_cache = new hash_map<rtx, rtx>;
>      }
>    else
>      {
> @@ -10263,7 +10261,7 @@ vt_finalize (void)
>    if (MAY_HAVE_DEBUG_INSNS)
>      {
>        if (global_get_addr_cache)
> -       pointer_map_destroy (global_get_addr_cache);
> +       delete global_get_addr_cache;
>        global_get_addr_cache = NULL;
>        if (loc_exp_dep_pool)
>         free_alloc_pool (loc_exp_dep_pool);
> --
> 2.0.1
>
Trevor Saunders Aug. 2, 2014, 11:34 a.m. UTC | #2
On Fri, Aug 01, 2014 at 12:52:08PM +0200, Richard Biener wrote:
> On Fri, Aug 1, 2014 at 12:34 PM,  <tsaunders@mozilla.com> wrote:
> > From: Trevor Saunders <tsaunders@mozilla.com>
> >
> > Hi,
> >
> > This patch replaces a bunch of usage of pointer_map with hash_map.  It also
> > adds an overload to hash_map::traverse that allows modifying the value, and a
> > remove method.
> >
> > bootstrapped + regtested on x86_64-unknown-linux-gnu, ok?
> 
> Ok.

committed as r213517 thanks for the review.

Trev

> 
> Thanks,
> Richard.
> 
> > Trev
> >
> > c-family/
> >
> >         * cilk.c: Use hash_map instead of pointer_map.
> >
> > c/
> >
> >         * c-typeck.c: Use hash_map instead of pointer_map.
> >
> > cp/
> >
> >         * optimize.c, semantics.c: Use hash_map instead of pointer_map.
> >
> > gcc/
> >
> >         * hash-map.h (default_hashmap_traits::mark_key_deleted):
> >         Fix cast.
> >         (hash_map::remove): New method.
> > (hash_map::traverse): New method.
> >         * cgraph.h, except.c, except.h, gimple-ssa-strength-reduction.c,
> >         ipa-utils.c, lto-cgraph.c, lto-streamer.h, omp-low.c, predict.c,
> >         tree-cfg.c, tree-cfgcleanup.c, tree-eh.c, tree-eh.h, tree-inline.c,
> >         tree-inline.h, tree-nested.c, tree-sra.c, tree-ssa-loop-im.c,
> >         tree-ssa-loop-ivopts.c, tree-ssa-reassoc.c, tree-ssa-structalias.c,
> >         tree-ssa.c, tree-ssa.h, var-tracking.c: Use hash_map instead of
> >  pointer_map.
> > diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
> > index b864bb1..e0d1141 100644
> > --- a/gcc/c-family/cilk.c
> > +++ b/gcc/c-family/cilk.c
> > @@ -64,7 +64,7 @@ struct wrapper_data
> >    /* Containing function.  */
> >    tree context;
> >    /* Disposition of all variables in the inner statement.  */
> > -  struct pointer_map_t *decl_map;
> > +  hash_map<tree, tree> *decl_map;
> >    /* True if this function needs a static chain.  */
> >    bool nested;
> >    /* Arguments to be passed to wrapper function, currently a list.  */
> > @@ -335,12 +335,11 @@ create_cilk_helper_decl (struct wrapper_data *wd)
> >
> >  /* A function used by walk tree to find wrapper parms.  */
> >
> > -static bool
> > -wrapper_parm_cb (const void *key0, void **val0, void *data)
> > +bool
> > +wrapper_parm_cb (tree const &key0, tree *val0, wrapper_data *wd)
> >  {
> > -  struct wrapper_data *wd = (struct wrapper_data *) data;
> > -  tree arg = * (tree *)&key0;
> > -  tree val = (tree)*val0;
> > +  tree arg = key0;
> > +  tree val = *val0;
> >    tree parm;
> >
> >    if (val == error_mark_node || val == arg)
> > @@ -387,7 +386,7 @@ build_wrapper_type (struct wrapper_data *wd)
> >    wd->parms = NULL_TREE;
> >    wd->argtypes = void_list_node;
> >
> > -  pointer_map_traverse (wd->decl_map, wrapper_parm_cb, wd);
> > +  wd->decl_map->traverse<wrapper_data *, wrapper_parm_cb> (wd);
> >    gcc_assert (wd->type != CILK_BLOCK_FOR);
> >
> >    /* Now build a function.
> > @@ -452,25 +451,22 @@ copy_decl_for_cilk (tree decl, copy_body_data *id)
> >
> >  /* Copy all local variables.  */
> >
> > -static bool
> > -for_local_cb (const void *k_v, void **vp, void *p)
> > +bool
> > +for_local_cb (tree const &k, tree *vp, copy_body_data *id)
> >  {
> > -  tree k = *(tree *) &k_v;
> > -  tree v = (tree) *vp;
> > +  tree v = *vp;
> >
> >    if (v == error_mark_node)
> > -    *vp = copy_decl_no_change (k, (copy_body_data *) p);
> > +    *vp = copy_decl_no_change (k, id);
> >    return true;
> >  }
> >
> >  /* Copy all local declarations from a _Cilk_spawned function's body.  */
> >
> > -static bool
> > -wrapper_local_cb (const void *k_v, void **vp, void *data)
> > +bool
> > +wrapper_local_cb (tree const &key, tree *vp, copy_body_data *id)
> >  {
> > -  copy_body_data *id = (copy_body_data *) data;
> > -  tree key = *(tree *) &k_v;
> > -  tree val = (tree) *vp;
> > +  tree val = *vp;
> >
> >    if (val == error_mark_node)
> >      *vp = copy_decl_for_cilk (key, id);
> > @@ -514,8 +510,11 @@ cilk_outline (tree inner_fn, tree *stmt_p, void *w)
> >    insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn));
> >
> >    /* We don't want the private variables any more.  */
> > -  pointer_map_traverse (wd->decl_map, nested ? for_local_cb : wrapper_local_cb,
> > -                       &id);
> > +  if (nested)
> > +    wd->decl_map->traverse<copy_body_data *, for_local_cb> (&id);
> > +  else
> > +    wd->decl_map->traverse<copy_body_data *, wrapper_local_cb> (&id);
> > +
> >    walk_tree (stmt_p, copy_tree_body_r, (void *) &id, NULL);
> >
> >    /* See if this function can throw or calls something that should
> > @@ -576,7 +575,7 @@ init_wd (struct wrapper_data *wd, enum cilk_block_type type)
> >    wd->type = type;
> >    wd->fntype = NULL_TREE;
> >    wd->context = current_function_decl;
> > -  wd->decl_map = pointer_map_create ();
> > +  wd->decl_map = new hash_map<tree, tree>;
> >    /* _Cilk_for bodies are always nested.  Others start off as
> >       normal functions.  */
> >    wd->nested = (type == CILK_BLOCK_FOR);
> > @@ -590,7 +589,7 @@ init_wd (struct wrapper_data *wd, enum cilk_block_type type)
> >  static void
> >  free_wd (struct wrapper_data *wd)
> >  {
> > -  pointer_map_destroy (wd->decl_map);
> > +  delete wd->decl_map;
> >    wd->nested = false;
> >    wd->arglist = NULL_TREE;
> >    wd->argtypes = NULL_TREE;
> > @@ -618,12 +617,11 @@ free_wd (struct wrapper_data *wd)
> >     (var, ???) -- Pure output argument, handled similarly to above.
> >  */
> >
> > -static bool
> > -declare_one_free_variable (const void *var0, void **map0,
> > -                          void *data ATTRIBUTE_UNUSED)
> > +bool
> > +declare_one_free_variable (tree const &var0, tree *map0, wrapper_data &)
> >  {
> > -  const_tree var = (const_tree) var0;
> > -  tree map = (tree)*map0;
> > +  const_tree var = var0;
> > +  tree map = *map0;
> >    tree var_type = TREE_TYPE (var), arg_type;
> >    bool by_reference;
> >    tree parm;
> > @@ -713,7 +711,7 @@ create_cilk_wrapper (tree exp, tree *args_out)
> >      }
> >    else
> >      extract_free_variables (exp, &wd, ADD_READ);
> > -  pointer_map_traverse (wd.decl_map, declare_one_free_variable, &wd);
> > +  wd.decl_map->traverse<wrapper_data &, declare_one_free_variable> (wd);
> >    wd.block = TREE_BLOCK (exp);
> >    if (!wd.block)
> >      wd.block = DECL_INITIAL (current_function_decl);
> > @@ -884,9 +882,7 @@ cilk_install_body_pedigree_operations (tree frame_ptr)
> >  static void
> >  add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
> >  {
> > -  void **valp;
> > -
> > -  valp = pointer_map_contains (wd->decl_map, (void *) var);
> > +  tree *valp = wd->decl_map->get (var);
> >    if (valp)
> >      {
> >        tree val = (tree) *valp;
> > @@ -907,7 +903,7 @@ add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
> >        if (how != ADD_WRITE)
> >         return;
> >        /* This variable might have been entered as read but is now written.  */
> > -      *valp = (void *) var;
> > +      *valp = var;
> >        wd->nested = true;
> >        return;
> >      }
> > @@ -971,7 +967,7 @@ add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
> >               break;
> >             }
> >         }
> > -      *pointer_map_insert (wd->decl_map, (void *) var) = val;
> > +      wd->decl_map->put (var, val);
> >      }
> >  }
> >
> > diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
> > index 06fd565..bedb63e 100644
> > --- a/gcc/c/c-typeck.c
> > +++ b/gcc/c/c-typeck.c
> > @@ -11783,15 +11783,15 @@ c_clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
> >                  tree decl, tree placeholder)
> >  {
> >    copy_body_data id;
> > -  struct pointer_map_t *decl_map = pointer_map_create ();
> > +  hash_map<tree, tree> decl_map;
> >
> > -  *pointer_map_insert (decl_map, omp_decl1) = placeholder;
> > -  *pointer_map_insert (decl_map, omp_decl2) = decl;
> > +  decl_map.put (omp_decl1, placeholder);
> > +  decl_map.put (omp_decl2, decl);
> >    memset (&id, 0, sizeof (id));
> >    id.src_fn = DECL_CONTEXT (omp_decl1);
> >    id.dst_fn = current_function_decl;
> >    id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
> > -  id.decl_map = decl_map;
> > +  id.decl_map = &decl_map;
> >
> >    id.copy_decl = copy_decl_no_change;
> >    id.transform_call_graph_edges = CB_CGE_DUPLICATE;
> > @@ -11800,7 +11800,6 @@ c_clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
> >    id.transform_lang_insert_block = NULL;
> >    id.eh_lp_nr = 0;
> >    walk_tree (&stmt, copy_tree_body_r, &id, NULL);
> > -  pointer_map_destroy (decl_map);
> >    return stmt;
> >  }
> >
> > diff --git a/gcc/cgraph.h b/gcc/cgraph.h
> > index f8f76c4..0fa8635 100644
> > --- a/gcc/cgraph.h
> > +++ b/gcc/cgraph.h
> > @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #ifndef GCC_CGRAPH_H
> >  #define GCC_CGRAPH_H
> >
> > +#include "hash-map.h"
> >  #include "is-a.h"
> >  #include "plugin-api.h"
> >  #include "vec.h"
> > @@ -1204,7 +1205,7 @@ public:
> >     can appear in multiple sets.  */
> >  struct cgraph_node_set_def
> >  {
> > -  struct pointer_map_t *map;
> > +  hash_map<cgraph_node *, size_t> *map;
> >    vec<cgraph_node *> nodes;
> >  };
> >
> > @@ -1217,7 +1218,7 @@ class varpool_node;
> >     can appear in multiple sets.  */
> >  struct varpool_node_set_def
> >  {
> > -  struct pointer_map_t * map;
> > +  hash_map<varpool_node *, size_t> * map;
> >    vec<varpool_node *> nodes;
> >  };
> >
> > diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
> > index 3cd8047..6eeca4d 100644
> > --- a/gcc/cp/optimize.c
> > +++ b/gcc/cp/optimize.c
> > @@ -86,7 +86,7 @@ clone_body (tree clone, tree fn, void *arg_map)
> >    id.src_fn = fn;
> >    id.dst_fn = clone;
> >    id.src_cfun = DECL_STRUCT_FUNCTION (fn);
> > -  id.decl_map = (struct pointer_map_t *) arg_map;
> > +  id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
> >
> >    id.copy_decl = copy_decl_no_change;
> >    id.transform_call_graph_edges = CB_CGE_DUPLICATE;
> > @@ -527,7 +527,7 @@ maybe_clone_body (tree fn)
> >        tree parm;
> >        tree clone_parm;
> >        int parmno;
> > -      struct pointer_map_t *decl_map;
> > +      hash_map<tree, tree> *decl_map;
> >        bool alias = false;
> >
> >        clone = fns[idx];
> > @@ -587,7 +587,7 @@ maybe_clone_body (tree fn)
> >             }
> >
> >            /* Remap the parameters.  */
> > -          decl_map = pointer_map_create ();
> > +          decl_map = new hash_map<tree, tree>;
> >            for (parmno = 0,
> >                  parm = DECL_ARGUMENTS (fn),
> >                  clone_parm = DECL_ARGUMENTS (clone);
> > @@ -600,7 +600,7 @@ maybe_clone_body (tree fn)
> >                  {
> >                    tree in_charge;
> >                    in_charge = in_charge_arg_for_name (DECL_NAME (clone));
> > -                  *pointer_map_insert (decl_map, parm) = in_charge;
> > +                  decl_map->put (parm, in_charge);
> >                  }
> >                else if (DECL_ARTIFICIAL (parm)
> >                         && DECL_NAME (parm) == vtt_parm_identifier)
> > @@ -611,19 +611,22 @@ maybe_clone_body (tree fn)
> >                    if (DECL_HAS_VTT_PARM_P (clone))
> >                      {
> >                        DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
> > -                      *pointer_map_insert (decl_map, parm) = clone_parm;
> > +                      decl_map->put (parm, clone_parm);
> >                        clone_parm = DECL_CHAIN (clone_parm);
> >                      }
> >                    /* Otherwise, map the VTT parameter to `NULL'.  */
> >                    else
> > -                    *pointer_map_insert (decl_map, parm)
> > -                       = fold_convert (TREE_TYPE (parm), null_pointer_node);
> > +                   {
> > +                     tree t
> > +                       = fold_convert (TREE_TYPE (parm), null_pointer_node);
> > +                     decl_map->put (parm, t);
> > +                   }
> >                  }
> >                /* Map other parameters to their equivalents in the cloned
> >                   function.  */
> >                else
> >                  {
> > -                  *pointer_map_insert (decl_map, parm) = clone_parm;
> > +                  decl_map->put (parm, clone_parm);
> >                    clone_parm = DECL_CHAIN (clone_parm);
> >                  }
> >              }
> > @@ -632,14 +635,14 @@ maybe_clone_body (tree fn)
> >              {
> >                parm = DECL_RESULT (fn);
> >                clone_parm = DECL_RESULT (clone);
> > -              *pointer_map_insert (decl_map, parm) = clone_parm;
> > +              decl_map->put (parm, clone_parm);
> >              }
> >
> >            /* Clone the body.  */
> >            clone_body (clone, fn, decl_map);
> >
> >            /* Clean up.  */
> > -          pointer_map_destroy (decl_map);
> > +          delete decl_map;
> >          }
> >
> >        /* The clone can throw iff the original function can throw.  */
> > diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
> > index 735284e..4868d69 100644
> > --- a/gcc/cp/semantics.c
> > +++ b/gcc/cp/semantics.c
> > @@ -4977,15 +4977,15 @@ clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
> >                tree decl, tree placeholder)
> >  {
> >    copy_body_data id;
> > -  struct pointer_map_t *decl_map = pointer_map_create ();
> > +  hash_map<tree, tree> decl_map;
> >
> > -  *pointer_map_insert (decl_map, omp_decl1) = placeholder;
> > -  *pointer_map_insert (decl_map, omp_decl2) = decl;
> > +  decl_map.put (omp_decl1, placeholder);
> > +  decl_map.put (omp_decl2, decl);
> >    memset (&id, 0, sizeof (id));
> >    id.src_fn = DECL_CONTEXT (omp_decl1);
> >    id.dst_fn = current_function_decl;
> >    id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
> > -  id.decl_map = decl_map;
> > +  id.decl_map = &decl_map;
> >
> >    id.copy_decl = copy_decl_no_change;
> >    id.transform_call_graph_edges = CB_CGE_DUPLICATE;
> > @@ -4994,7 +4994,6 @@ clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
> >    id.transform_lang_insert_block = NULL;
> >    id.eh_lp_nr = 0;
> >    walk_tree (&stmt, copy_tree_body_r, &id, NULL);
> > -  pointer_map_destroy (decl_map);
> >    return stmt;
> >  }
> >
> > diff --git a/gcc/except.c b/gcc/except.c
> > index c8dbc50..ec08e91 100644
> > --- a/gcc/except.c
> > +++ b/gcc/except.c
> > @@ -527,7 +527,7 @@ struct duplicate_eh_regions_data
> >  {
> >    duplicate_eh_regions_map label_map;
> >    void *label_map_data;
> > -  struct pointer_map_t *eh_map;
> > +  hash_map<void *, void *> *eh_map;
> >  };
> >
> >  static void
> > @@ -536,12 +536,9 @@ duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
> >  {
> >    eh_landing_pad old_lp, new_lp;
> >    eh_region new_r;
> > -  void **slot;
> >
> >    new_r = gen_eh_region (old_r->type, outer);
> > -  slot = pointer_map_insert (data->eh_map, (void *)old_r);
> > -  gcc_assert (*slot == NULL);
> > -  *slot = (void *)new_r;
> > +  gcc_assert (!data->eh_map->put (old_r, new_r));
> >
> >    switch (old_r->type)
> >      {
> > @@ -586,9 +583,7 @@ duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
> >         continue;
> >
> >        new_lp = gen_eh_landing_pad (new_r);
> > -      slot = pointer_map_insert (data->eh_map, (void *)old_lp);
> > -      gcc_assert (*slot == NULL);
> > -      *slot = (void *)new_lp;
> > +      gcc_assert (!data->eh_map->put (old_lp, new_lp));
> >
> >        new_lp->post_landing_pad
> >         = data->label_map (old_lp->post_landing_pad, data->label_map_data);
> > @@ -609,7 +604,7 @@ duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
> >     that allows the caller to remap uses of both EH regions and
> >     EH landing pads.  */
> >
> > -struct pointer_map_t *
> > +hash_map<void *, void *> *
> >  duplicate_eh_regions (struct function *ifun,
> >                       eh_region copy_region, int outer_lp,
> >                       duplicate_eh_regions_map map, void *map_data)
> > @@ -623,7 +618,7 @@ duplicate_eh_regions (struct function *ifun,
> >
> >    data.label_map = map;
> >    data.label_map_data = map_data;
> > -  data.eh_map = pointer_map_create ();
> > +  data.eh_map = new hash_map<void *, void *>;
> >
> >    outer_region = get_eh_region_from_lp_number (outer_lp);
> >
> > diff --git a/gcc/except.h b/gcc/except.h
> > index bab13e1..5c2aa3d 100644
> > --- a/gcc/except.h
> > +++ b/gcc/except.h
> > @@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #  define GCC_EXCEPT_H
> >  #endif
> >
> > +#include "hash-map.h"
> >  #include "hashtab.h"
> >
> >  struct function;
> > @@ -249,7 +250,7 @@ extern rtx expand_builtin_extend_pointer (tree);
> >  extern void expand_dw2_landing_pad_for_region (eh_region);
> >
> >  typedef tree (*duplicate_eh_regions_map) (tree, void *);
> > -extern struct pointer_map_t *duplicate_eh_regions
> > +extern hash_map<void *, void *> *duplicate_eh_regions
> >    (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
> >
> >  extern void sjlj_emit_function_exit_after (rtx);
> > diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
> > index d7c5db5..b13b7f7 100644
> > --- a/gcc/gimple-ssa-strength-reduction.c
> > +++ b/gcc/gimple-ssa-strength-reduction.c
> > @@ -38,6 +38,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "coretypes.h"
> >  #include "tree.h"
> >  #include "pointer-set.h"
> > +#include "hash-map.h"
> >  #include "hash-table.h"
> >  #include "basic-block.h"
> >  #include "tree-ssa-alias.h"
> > @@ -373,7 +374,7 @@ enum count_phis_status
> >  };
> >
> >  /* Pointer map embodying a mapping from statements to candidates.  */
> > -static struct pointer_map_t *stmt_cand_map;
> > +static hash_map<gimple, slsr_cand_t> *stmt_cand_map;
> >
> >  /* Obstack for candidates.  */
> >  static struct obstack cand_obstack;
> > @@ -435,7 +436,7 @@ static hash_table<cand_chain_hasher> *base_cand_map;
> >  /* Pointer map used by tree_to_aff_combination_expand.  */
> >  static struct pointer_map_t *name_expansions;
> >  /* Pointer map embodying a mapping from bases to alternative bases.  */
> > -static struct pointer_map_t *alt_base_map;
> > +static hash_map<tree, tree> *alt_base_map;
> >
> >  /* Given BASE, use the tree affine combiniation facilities to
> >     find the underlying tree expression for BASE, with any
> > @@ -447,7 +448,7 @@ static struct pointer_map_t *alt_base_map;
> >  static tree
> >  get_alternative_base (tree base)
> >  {
> > -  tree *result = (tree *) pointer_map_contains (alt_base_map, base);
> > +  tree *result = alt_base_map->get (base);
> >
> >    if (result == NULL)
> >      {
> > @@ -459,13 +460,9 @@ get_alternative_base (tree base)
> >        aff.offset = 0;
> >        expr = aff_combination_to_tree (&aff);
> >
> > -      result = (tree *) pointer_map_insert (alt_base_map, base);
> > -      gcc_assert (!*result);
> > +      gcc_assert (!alt_base_map->put (base, base == expr ? NULL : expr));
> >
> > -      if (expr == base)
> > -       *result = NULL;
> > -      else
> > -       *result = expr;
> > +      return expr == base ? NULL : expr;
> >      }
> >
> >    return *result;
> > @@ -724,7 +721,7 @@ base_cand_from_table (tree base_in)
> >    if (!def)
> >      return (slsr_cand_t) NULL;
> >
> > -  result = (slsr_cand_t *) pointer_map_contains (stmt_cand_map, def);
> > +  result = stmt_cand_map->get (def);
> >
> >    if (result && (*result)->kind != CAND_REF)
> >      return *result;
> > @@ -737,9 +734,7 @@ base_cand_from_table (tree base_in)
> >  static void
> >  add_cand_for_stmt (gimple gs, slsr_cand_t c)
> >  {
> > -  void **slot = pointer_map_insert (stmt_cand_map, gs);
> > -  gcc_assert (!*slot);
> > -  *slot = c;
> > +  gcc_assert (!stmt_cand_map->put (gs, c));
> >  }
> >
> >  /* Given PHI which contains a phi statement, determine whether it
> > @@ -3628,7 +3623,7 @@ pass_strength_reduction::execute (function *fun)
> >    cand_vec.create (128);
> >
> >    /* Allocate the mapping from statements to candidate indices.  */
> > -  stmt_cand_map = pointer_map_create ();
> > +  stmt_cand_map = new hash_map<gimple, slsr_cand_t>;
> >
> >    /* Create the obstack where candidate chains will reside.  */
> >    gcc_obstack_init (&chain_obstack);
> > @@ -3637,7 +3632,7 @@ pass_strength_reduction::execute (function *fun)
> >    base_cand_map = new hash_table<cand_chain_hasher> (500);
> >
> >    /* Allocate the mapping from bases to alternative bases.  */
> > -  alt_base_map = pointer_map_create ();
> > +  alt_base_map = new hash_map<tree, tree>;
> >
> >    /* Initialize the loop optimizer.  We need to detect flow across
> >       back edges, and this gives us dominator information as well.  */
> > @@ -3654,7 +3649,7 @@ pass_strength_reduction::execute (function *fun)
> >        dump_cand_chains ();
> >      }
> >
> > -  pointer_map_destroy (alt_base_map);
> > +  delete alt_base_map;
> >    free_affine_expand_cache (&name_expansions);
> >
> >    /* Analyze costs and make appropriate replacements.  */
> > @@ -3664,7 +3659,7 @@ pass_strength_reduction::execute (function *fun)
> >    delete base_cand_map;
> >    base_cand_map = NULL;
> >    obstack_free (&chain_obstack, NULL);
> > -  pointer_map_destroy (stmt_cand_map);
> > +  delete stmt_cand_map;
> >    cand_vec.release ();
> >    obstack_free (&cand_obstack, NULL);
> >
> > diff --git a/gcc/hash-map.h b/gcc/hash-map.h
> > index 0b50f72..ec48844 100644
> > --- a/gcc/hash-map.h
> > +++ b/gcc/hash-map.h
> > @@ -93,7 +93,7 @@ private:
> >    static void
> >    mark_key_deleted (T *&k)
> >      {
> > -      k = static_cast<T *> (1);
> > +      k = reinterpret_cast<T *> (1);
> >      }
> >
> >    template<typename T>
> > @@ -185,6 +185,11 @@ public:
> >        return e->m_value;
> >      }
> >
> > +  void remove (const Key &k)
> > +    {
> > +      m_table.remove_elt_with_hash (k, Traits::hash (k));
> > +    }
> > +
> >    /* Call the call back on each pair of key and value with the passed in
> >       arg.  */
> >
> > @@ -196,6 +201,15 @@ public:
> >         f ((*iter).m_key, (*iter).m_value, a);
> >      }
> >
> > +  template<typename Arg, bool (*f)(const Key &, Value *, Arg)>
> > +  void traverse (Arg a) const
> > +    {
> > +      for (typename hash_table<hash_entry>::iterator iter = m_table.begin ();
> > +          iter != m_table.end (); ++iter)
> > +       if (!f ((*iter).m_key, &(*iter).m_value, a))
> > +         break;
> > +    }
> > +
> >  private:
> >    hash_table<hash_entry> m_table;
> >  };
> > diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
> > index 7810e55..a391b5d 100644
> > --- a/gcc/ipa-utils.c
> > +++ b/gcc/ipa-utils.c
> > @@ -389,7 +389,7 @@ cgraph_node_set_new (void)
> >    cgraph_node_set new_node_set;
> >
> >    new_node_set = XCNEW (struct cgraph_node_set_def);
> > -  new_node_set->map = pointer_map_create ();
> > +  new_node_set->map = new hash_map<cgraph_node *, size_t>;
> >    new_node_set->nodes.create (0);
> >    return new_node_set;
> >  }
> > @@ -400,19 +400,17 @@ cgraph_node_set_new (void)
> >  void
> >  cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
> >  {
> > -  void **slot;
> > +  bool existed_p;
> > +  size_t &index = set->map->get_or_insert (node, &existed_p);
> >
> > -  slot = pointer_map_insert (set->map, node);
> > -
> > -  if (*slot)
> > +  if (existed_p)
> >      {
> > -      int index = (size_t) *slot - 1;
> >        gcc_checking_assert ((set->nodes[index]
> >                            == node));
> >        return;
> >      }
> >
> > -  *slot = (void *)(size_t) (set->nodes.length () + 1);
> > +  index = set->nodes.length () + 1;
> >
> >    /* Insert into node vector.  */
> >    set->nodes.safe_push (node);
> > @@ -424,15 +422,14 @@ cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
> >  void
> >  cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
> >  {
> > -  void **slot, **last_slot;
> >    int index;
> >    struct cgraph_node *last_node;
> >
> > -  slot = pointer_map_contains (set->map, node);
> > +  size_t *slot = set->map->get (node);
> >    if (slot == NULL || !*slot)
> >      return;
> >
> > -  index = (size_t) *slot - 1;
> > +  index = *slot - 1;
> >    gcc_checking_assert (set->nodes[index]
> >                        == node);
> >
> > @@ -441,16 +438,16 @@ cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
> >    last_node = set->nodes.pop ();
> >    if (last_node != node)
> >      {
> > -      last_slot = pointer_map_contains (set->map, last_node);
> > +      size_t *last_slot = set->map->get (last_node);
> >        gcc_checking_assert (last_slot && *last_slot);
> > -      *last_slot = (void *)(size_t) (index + 1);
> > +      *last_slot = index + 1;
> >
> >        /* Move the last element to the original spot of NODE.  */
> >        set->nodes[index] = last_node;
> >      }
> >
> >    /* Remove element from hash table.  */
> > -  *slot = NULL;
> > +  set->map->remove (node);
> >  }
> >
> >
> > @@ -460,14 +457,14 @@ cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
> >  cgraph_node_set_iterator
> >  cgraph_node_set_find (cgraph_node_set set, struct cgraph_node *node)
> >  {
> > -  void **slot;
> > +  size_t *slot;
> >    cgraph_node_set_iterator csi;
> >
> > -  slot = pointer_map_contains (set->map, node);
> > +  slot = set->map->get (node);
> >    if (slot == NULL || !*slot)
> >      csi.index = (unsigned) ~0;
> >    else
> > -    csi.index = (size_t)*slot - 1;
> > +    csi.index = *slot - 1;
> >    csi.set = set;
> >
> >    return csi;
> > @@ -505,7 +502,7 @@ void
> >  free_cgraph_node_set (cgraph_node_set set)
> >  {
> >    set->nodes.release ();
> > -  pointer_map_destroy (set->map);
> > +  delete set->map;
> >    free (set);
> >  }
> >
> > @@ -518,7 +515,7 @@ varpool_node_set_new (void)
> >    varpool_node_set new_node_set;
> >
> >    new_node_set = XCNEW (struct varpool_node_set_def);
> > -  new_node_set->map = pointer_map_create ();
> > +  new_node_set->map = new hash_map<varpool_node *, size_t>;
> >    new_node_set->nodes.create (0);
> >    return new_node_set;
> >  }
> > @@ -529,19 +526,18 @@ varpool_node_set_new (void)
> >  void
> >  varpool_node_set_add (varpool_node_set set, varpool_node *node)
> >  {
> > -  void **slot;
> > -
> > -  slot = pointer_map_insert (set->map, node);
> > +  bool existed;
> > +  size_t &slot = set->map->get_or_insert (node, &existed);
> >
> > -  if (*slot)
> > +  if (existed)
> >      {
> > -      int index = (size_t) *slot - 1;
> > +      int index = slot - 1;
> >        gcc_checking_assert ((set->nodes[index]
> >                            == node));
> >        return;
> >      }
> >
> > -  *slot = (void *)(size_t) (set->nodes.length () + 1);
> > +  slot = set->nodes.length () + 1;
> >
> >    /* Insert into node vector.  */
> >    set->nodes.safe_push (node);
> > @@ -553,15 +549,14 @@ varpool_node_set_add (varpool_node_set set, varpool_node *node)
> >  void
> >  varpool_node_set_remove (varpool_node_set set, varpool_node *node)
> >  {
> > -  void **slot, **last_slot;
> >    int index;
> >    varpool_node *last_node;
> >
> > -  slot = pointer_map_contains (set->map, node);
> > +  size_t *slot = set->map->get (node);
> >    if (slot == NULL || !*slot)
> >      return;
> >
> > -  index = (size_t) *slot - 1;
> > +  index = *slot - 1;
> >    gcc_checking_assert (set->nodes[index]
> >                        == node);
> >
> > @@ -570,16 +565,16 @@ varpool_node_set_remove (varpool_node_set set, varpool_node *node)
> >    last_node = set->nodes.pop ();
> >    if (last_node != node)
> >      {
> > -      last_slot = pointer_map_contains (set->map, last_node);
> > +      size_t *last_slot = set->map->get (last_node);
> >        gcc_checking_assert (last_slot && *last_slot);
> > -      *last_slot = (void *)(size_t) (index + 1);
> > +      *last_slot = index + 1;
> >
> >        /* Move the last element to the original spot of NODE.  */
> >        set->nodes[index] = last_node;
> >      }
> >
> >    /* Remove element from hash table.  */
> > -  *slot = NULL;
> > +  set->map->remove (node);
> >  }
> >
> >
> > @@ -589,14 +584,13 @@ varpool_node_set_remove (varpool_node_set set, varpool_node *node)
> >  varpool_node_set_iterator
> >  varpool_node_set_find (varpool_node_set set, varpool_node *node)
> >  {
> > -  void **slot;
> >    varpool_node_set_iterator vsi;
> >
> > -  slot = pointer_map_contains (set->map, node);
> > +  size_t *slot = set->map->get (node);
> >    if (slot == NULL || !*slot)
> >      vsi.index = (unsigned) ~0;
> >    else
> > -    vsi.index = (size_t)*slot - 1;
> > +    vsi.index = *slot - 1;
> >    vsi.set = set;
> >
> >    return vsi;
> > @@ -625,7 +619,7 @@ void
> >  free_varpool_node_set (varpool_node_set set)
> >  {
> >    set->nodes.release ();
> > -  pointer_map_destroy (set->map);
> > +  delete set->map;
> >    free (set);
> >  }
> >
> > diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
> > index 42b0790..28a30ad 100644
> > --- a/gcc/lto-cgraph.c
> > +++ b/gcc/lto-cgraph.c
> > @@ -93,7 +93,7 @@ lto_symtab_encoder_new (bool for_input)
> >    lto_symtab_encoder_t encoder = XCNEW (struct lto_symtab_encoder_d);
> >
> >    if (!for_input)
> > -    encoder->map = pointer_map_create ();
> > +    encoder->map = new hash_map<symtab_node *, size_t>;
> >    encoder->nodes.create (0);
> >    return encoder;
> >  }
> > @@ -106,7 +106,7 @@ lto_symtab_encoder_delete (lto_symtab_encoder_t encoder)
> >  {
> >     encoder->nodes.release ();
> >     if (encoder->map)
> > -     pointer_map_destroy (encoder->map);
> > +     delete encoder->map;
> >     free (encoder);
> >  }
> >
> > @@ -120,7 +120,6 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
> >                            symtab_node *node)
> >  {
> >    int ref;
> > -  void **slot;
> >
> >    if (!encoder->map)
> >      {
> > @@ -131,18 +130,17 @@ lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
> >        return ref;
> >      }
> >
> > -  slot = pointer_map_contains (encoder->map, node);
> > +  size_t *slot = encoder->map->get (node);
> >    if (!slot || !*slot)
> >      {
> >        lto_encoder_entry entry = {node, false, false, false};
> >        ref = encoder->nodes.length ();
> >        if (!slot)
> > -        slot = pointer_map_insert (encoder->map, node);
> > -      *slot = (void *) (intptr_t) (ref + 1);
> > +        encoder->map->put (node, ref + 1);
> >        encoder->nodes.safe_push (entry);
> >      }
> >    else
> > -    ref = (size_t) *slot - 1;
> > +    ref = *slot - 1;
> >
> >    return ref;
> >  }
> > @@ -153,15 +151,14 @@ bool
> >  lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
> >                                 symtab_node *node)
> >  {
> > -  void **slot, **last_slot;
> >    int index;
> >    lto_encoder_entry last_node;
> >
> > -  slot = pointer_map_contains (encoder->map, node);
> > +  size_t *slot = encoder->map->get (node);
> >    if (slot == NULL || !*slot)
> >      return false;
> >
> > -  index = (size_t) *slot - 1;
> > +  index = *slot - 1;
> >    gcc_checking_assert (encoder->nodes[index].node == node);
> >
> >    /* Remove from vector. We do this by swapping node with the last element
> > @@ -169,16 +166,14 @@ lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
> >    last_node = encoder->nodes.pop ();
> >    if (last_node.node != node)
> >      {
> > -      last_slot = pointer_map_contains (encoder->map, last_node.node);
> > -      gcc_checking_assert (last_slot && *last_slot);
> > -      *last_slot = (void *)(size_t) (index + 1);
> > +      gcc_assert (encoder->map->put (last_node.node, index + 1));
> >
> >        /* Move the last element to the original spot of NODE.  */
> >        encoder->nodes[index] = last_node;
> >      }
> >
> >    /* Remove element from hash table.  */
> > -  *slot = NULL;
> > +  encoder->map->remove (node);
> >    return true;
> >  }
> >
> > diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
> > index d350ad9..b2486dd 100644
> > --- a/gcc/lto-streamer.h
> > +++ b/gcc/lto-streamer.h
> > @@ -443,7 +443,7 @@ struct lto_encoder_entry
> >  struct lto_symtab_encoder_d
> >  {
> >    vec<lto_encoder_entry> nodes;
> > -  pointer_map_t *map;
> > +  hash_map<symtab_node *, size_t> *map;
> >  };
> >
> >  typedef struct lto_symtab_encoder_d *lto_symtab_encoder_t;
> > @@ -1046,8 +1046,8 @@ static inline int
> >  lto_symtab_encoder_lookup (lto_symtab_encoder_t encoder,
> >                            symtab_node *node)
> >  {
> > -  void **slot = pointer_map_contains (encoder->map, node);
> > -  return (slot && *slot ? (size_t) *(slot) - 1 : LCC_NOT_FOUND);
> > +  size_t *slot = encoder->map->get (node);
> > +  return (slot && *slot ? *(slot) - 1 : LCC_NOT_FOUND);
> >  }
> >
> >  /* Return true if iterator LSE points to nothing.  */
> > diff --git a/gcc/omp-low.c b/gcc/omp-low.c
> > index b46693b..0fe2a40 100644
> > --- a/gcc/omp-low.c
> > +++ b/gcc/omp-low.c
> > @@ -812,16 +812,14 @@ is_reference (tree decl)
> >  static inline tree
> >  lookup_decl (tree var, omp_context *ctx)
> >  {
> > -  tree *n;
> > -  n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
> > +  tree *n = ctx->cb.decl_map->get (var);
> >    return *n;
> >  }
> >
> >  static inline tree
> >  maybe_lookup_decl (const_tree var, omp_context *ctx)
> >  {
> > -  tree *n;
> > -  n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
> > +  tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
> >    return n ? *n : NULL_TREE;
> >  }
> >
> > @@ -1359,7 +1357,7 @@ new_omp_context (gimple stmt, omp_context *outer_ctx)
> >        ctx->depth = 1;
> >      }
> >
> > -  ctx->cb.decl_map = pointer_map_create ();
> > +  ctx->cb.decl_map = new hash_map<tree, tree>;
> >
> >    return ctx;
> >  }
> > @@ -1408,7 +1406,7 @@ delete_omp_context (splay_tree_value value)
> >  {
> >    omp_context *ctx = (omp_context *) value;
> >
> > -  pointer_map_destroy (ctx->cb.decl_map);
> > +  delete ctx->cb.decl_map;
> >
> >    if (ctx->field_map)
> >      splay_tree_delete (ctx->field_map);
> > @@ -6541,7 +6539,6 @@ expand_omp_for_static_chunk (struct omp_region *region,
> >        gimple_stmt_iterator psi;
> >        gimple phi;
> >        edge re, ene;
> > -      edge_var_map_vector *head;
> >        edge_var_map *vm;
> >        size_t i;
> >
> > @@ -6552,7 +6549,7 @@ expand_omp_for_static_chunk (struct omp_region *region,
> >          appropriate phi nodes in iter_part_bb instead.  */
> >        se = single_pred_edge (fin_bb);
> >        re = single_succ_edge (trip_update_bb);
> > -      head = redirect_edge_var_map_vector (re);
> > +      vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
> >        ene = single_succ_edge (entry_bb);
> >
> >        psi = gsi_start_phis (fin_bb);
> > @@ -9219,7 +9216,7 @@ task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
> >        walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
> >                  &tcctx->cb, NULL);
> >        new_fields = new_f;
> > -      *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
> > +      tcctx->cb.decl_map->put (f, new_f);
> >      }
> >    TYPE_FIELDS (type) = nreverse (new_fields);
> >    layout_type (type);
> > @@ -9286,7 +9283,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >        tcctx.cb.copy_decl = task_copyfn_copy_decl;
> >        tcctx.cb.eh_lp_nr = 0;
> >        tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
> > -      tcctx.cb.decl_map = pointer_map_create ();
> > +      tcctx.cb.decl_map = new hash_map<tree, tree>;
> >        tcctx.ctx = ctx;
> >
> >        if (record_needs_remap)
> > @@ -9311,12 +9308,12 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >           tree *p;
> >
> >           decl = OMP_CLAUSE_DECL (c);
> > -         p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
> > +         p = tcctx.cb.decl_map->get (decl);
> >           if (p == NULL)
> >             continue;
> >           n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
> >           sf = (tree) n->value;
> > -         sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> > +         sf = *tcctx.cb.decl_map->get (sf);
> >           src = build_simple_mem_ref_loc (loc, sarg);
> >           src = omp_build_component_ref (src, sf);
> >           t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
> > @@ -9335,11 +9332,11 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >           break;
> >         f = (tree) n->value;
> >         if (tcctx.cb.decl_map)
> > -         f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
> > +         f = *tcctx.cb.decl_map->get (f);
> >         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
> >         sf = (tree) n->value;
> >         if (tcctx.cb.decl_map)
> > -         sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> > +         sf = *tcctx.cb.decl_map->get (sf);
> >         src = build_simple_mem_ref_loc (loc, sarg);
> >         src = omp_build_component_ref (src, sf);
> >         dst = build_simple_mem_ref_loc (loc, arg);
> > @@ -9356,13 +9353,13 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >           break;
> >         f = (tree) n->value;
> >         if (tcctx.cb.decl_map)
> > -         f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
> > +         f = *tcctx.cb.decl_map->get (f);
> >         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
> >         if (n != NULL)
> >           {
> >             sf = (tree) n->value;
> >             if (tcctx.cb.decl_map)
> > -             sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> > +             sf = *tcctx.cb.decl_map->get (sf);
> >             src = build_simple_mem_ref_loc (loc, sarg);
> >             src = omp_build_component_ref (src, sf);
> >             if (use_pointer_for_field (decl, NULL) || is_reference (decl))
> > @@ -9382,13 +9379,13 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >         n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
> >         f = (tree) n->value;
> >         if (tcctx.cb.decl_map)
> > -         f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
> > +         f = *tcctx.cb.decl_map->get (f);
> >         n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
> >         if (n != NULL)
> >           {
> >             sf = (tree) n->value;
> >             if (tcctx.cb.decl_map)
> > -             sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> > +             sf = *tcctx.cb.decl_map->get (sf);
> >             src = build_simple_mem_ref_loc (loc, sarg);
> >             src = omp_build_component_ref (src, sf);
> >             if (use_pointer_for_field (decl, NULL))
> > @@ -9419,7 +9416,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >           if (n == NULL)
> >             continue;
> >           f = (tree) n->value;
> > -         f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
> > +         f = *tcctx.cb.decl_map->get (f);
> >           gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
> >           ind = DECL_VALUE_EXPR (decl);
> >           gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
> > @@ -9427,7 +9424,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >           n = splay_tree_lookup (ctx->sfield_map,
> >                                  (splay_tree_key) TREE_OPERAND (ind, 0));
> >           sf = (tree) n->value;
> > -         sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
> > +         sf = *tcctx.cb.decl_map->get (sf);
> >           src = build_simple_mem_ref_loc (loc, sarg);
> >           src = omp_build_component_ref (src, sf);
> >           src = build_simple_mem_ref_loc (loc, src);
> > @@ -9438,7 +9435,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >           n = splay_tree_lookup (ctx->field_map,
> >                                  (splay_tree_key) TREE_OPERAND (ind, 0));
> >           df = (tree) n->value;
> > -         df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
> > +         df = *tcctx.cb.decl_map->get (df);
> >           ptr = build_simple_mem_ref_loc (loc, arg);
> >           ptr = omp_build_component_ref (ptr, df);
> >           t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
> > @@ -9450,7 +9447,7 @@ create_task_copyfn (gimple task_stmt, omp_context *ctx)
> >    append_to_statement_list (t, &list);
> >
> >    if (tcctx.cb.decl_map)
> > -    pointer_map_destroy (tcctx.cb.decl_map);
> > +    delete tcctx.cb.decl_map;
> >    pop_gimplify_context (NULL);
> >    BIND_EXPR_BODY (bind) = list;
> >    pop_cfun ();
> > diff --git a/gcc/predict.c b/gcc/predict.c
> > index 72a3b53..34ebdc3 100644
> > --- a/gcc/predict.c
> > +++ b/gcc/predict.c
> > @@ -52,6 +52,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "target.h"
> >  #include "cfgloop.h"
> >  #include "pointer-set.h"
> > +#include "hash-map.h"
> >  #include "tree-ssa-alias.h"
> >  #include "internal-fn.h"
> >  #include "gimple-expr.h"
> > @@ -490,11 +491,6 @@ rtl_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
> >    return false;
> >  }
> >
> > -/* This map contains for a basic block the list of predictions for the
> > -   outgoing edges.  */
> > -
> > -static struct pointer_map_t *bb_predictions;
> > -
> >  /*  Structure representing predictions in tree level. */
> >
> >  struct edge_prediction {
> > @@ -504,6 +500,11 @@ struct edge_prediction {
> >      int ep_probability;
> >  };
> >
> > +/* This map contains for a basic block the list of predictions for the
> > +   outgoing edges.  */
> > +
> > +static hash_map<const_basic_block, edge_prediction *> *bb_predictions;
> > +
> >  /* Return true if the one of outgoing edges is already predicted by
> >     PREDICTOR.  */
> >
> > @@ -511,12 +512,12 @@ bool
> >  gimple_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
> >  {
> >    struct edge_prediction *i;
> > -  void **preds = pointer_map_contains (bb_predictions, bb);
> > +  edge_prediction **preds = bb_predictions->get (bb);
> >
> >    if (!preds)
> >      return false;
> >
> > -  for (i = (struct edge_prediction *) *preds; i; i = i->ep_next)
> > +  for (i = *preds; i; i = i->ep_next)
> >      if (i->ep_predictor == predictor)
> >        return true;
> >    return false;
> > @@ -618,10 +619,10 @@ gimple_predict_edge (edge e, enum br_predictor predictor, int probability)
> >        && flag_guess_branch_prob && optimize)
> >      {
> >        struct edge_prediction *i = XNEW (struct edge_prediction);
> > -      void **preds = pointer_map_insert (bb_predictions, e->src);
> > +      edge_prediction *&preds = bb_predictions->get_or_insert (e->src);
> >
> > -      i->ep_next = (struct edge_prediction *) *preds;
> > -      *preds = i;
> > +      i->ep_next = preds;
> > +      preds = i;
> >        i->ep_probability = probability;
> >        i->ep_predictor = predictor;
> >        i->ep_edge = e;
> > @@ -633,16 +634,14 @@ gimple_predict_edge (edge e, enum br_predictor predictor, int probability)
> >  void
> >  remove_predictions_associated_with_edge (edge e)
> >  {
> > -  void **preds;
> > -
> >    if (!bb_predictions)
> >      return;
> >
> > -  preds = pointer_map_contains (bb_predictions, e->src);
> > +  edge_prediction **preds = bb_predictions->get (e->src);
> >
> >    if (preds)
> >      {
> > -      struct edge_prediction **prediction = (struct edge_prediction **) preds;
> > +      struct edge_prediction **prediction = preds;
> >        struct edge_prediction *next;
> >
> >        while (*prediction)
> > @@ -664,13 +663,13 @@ remove_predictions_associated_with_edge (edge e)
> >  static void
> >  clear_bb_predictions (basic_block bb)
> >  {
> > -  void **preds = pointer_map_contains (bb_predictions, bb);
> > +  edge_prediction **preds = bb_predictions->get (bb);
> >    struct edge_prediction *pred, *next;
> >
> >    if (!preds)
> >      return;
> >
> > -  for (pred = (struct edge_prediction *) *preds; pred; pred = next)
> > +  for (pred = *preds; pred; pred = next)
> >      {
> >        next = pred->ep_next;
> >        free (pred);
> > @@ -903,7 +902,6 @@ combine_predictions_for_bb (basic_block bb)
> >    int nedges = 0;
> >    edge e, first = NULL, second = NULL;
> >    edge_iterator ei;
> > -  void **preds;
> >
> >    FOR_EACH_EDGE (e, ei, bb->succs)
> >      if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
> > @@ -935,12 +933,12 @@ combine_predictions_for_bb (basic_block bb)
> >    if (dump_file)
> >      fprintf (dump_file, "Predictions for bb %i\n", bb->index);
> >
> > -  preds = pointer_map_contains (bb_predictions, bb);
> > +  edge_prediction **preds = bb_predictions->get (bb);
> >    if (preds)
> >      {
> >        /* We implement "first match" heuristics and use probability guessed
> >          by predictor with smallest index.  */
> > -      for (pred = (struct edge_prediction *) *preds; pred; pred = pred->ep_next)
> > +      for (pred = *preds; pred; pred = pred->ep_next)
> >         {
> >           enum br_predictor predictor = pred->ep_predictor;
> >           int probability = pred->ep_probability;
> > @@ -2243,14 +2241,14 @@ tree_bb_level_predictions (void)
> >
> >  #ifdef ENABLE_CHECKING
> >
> > -/* Callback for pointer_map_traverse, asserts that the pointer map is
> > +/* Callback for hash_map::traverse, asserts that the pointer map is
> >     empty.  */
> >
> > -static bool
> > -assert_is_empty (const void *key ATTRIBUTE_UNUSED, void **value,
> > -                void *data ATTRIBUTE_UNUSED)
> > +bool
> > +assert_is_empty (const_basic_block const &, edge_prediction *const &value,
> > +                void *)
> >  {
> > -  gcc_assert (!*value);
> > +  gcc_assert (!value);
> >    return false;
> >  }
> >  #endif
> > @@ -2375,7 +2373,7 @@ tree_estimate_probability (void)
> >    create_preheaders (CP_SIMPLE_PREHEADERS);
> >    calculate_dominance_info (CDI_POST_DOMINATORS);
> >
> > -  bb_predictions = pointer_map_create ();
> > +  bb_predictions = new hash_map<const_basic_block, edge_prediction *>;
> >    tree_bb_level_predictions ();
> >    record_loop_exits ();
> >
> > @@ -2389,9 +2387,9 @@ tree_estimate_probability (void)
> >      combine_predictions_for_bb (bb);
> >
> >  #ifdef ENABLE_CHECKING
> > -  pointer_map_traverse (bb_predictions, assert_is_empty, NULL);
> > +  bb_predictions->traverse<void *, assert_is_empty> (NULL);
> >  #endif
> > -  pointer_map_destroy (bb_predictions);
> > +  delete bb_predictions;
> >    bb_predictions = NULL;
> >
> >    estimate_bb_frequencies (false);
> > diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
> > index e034762..cfa6527 100644
> > --- a/gcc/tree-cfg.c
> > +++ b/gcc/tree-cfg.c
> > @@ -22,6 +22,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "system.h"
> >  #include "coretypes.h"
> >  #include "hash-table.h"
> > +#include "hash-map.h"
> >  #include "tm.h"
> >  #include "tree.h"
> >  #include "trans-mem.h"
> > @@ -92,7 +93,7 @@ static const int initial_cfg_capacity = 20;
> >     more persistent.  The key is getting notification of changes to
> >     the CFG (particularly edge removal, creation and redirection).  */
> >
> > -static struct pointer_map_t *edge_to_cases;
> > +static hash_map<edge, tree> *edge_to_cases;
> >
> >  /* If we record edge_to_cases, this bitmap will hold indexes
> >     of basic blocks that end in a GIMPLE_SWITCH which we touched
> > @@ -1048,19 +1049,17 @@ make_cond_expr_edges (basic_block bb)
> >     SWITCH_EXPRs and structure sharing rules, then free the hash table
> >     element.  */
> >
> > -static bool
> > -edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value,
> > -                      void *data ATTRIBUTE_UNUSED)
> > +bool
> > +edge_to_cases_cleanup (edge const &, tree const &value, void *)
> >  {
> >    tree t, next;
> >
> > -  for (t = (tree) *value; t; t = next)
> > +  for (t = value; t; t = next)
> >      {
> >        next = CASE_CHAIN (t);
> >        CASE_CHAIN (t) = NULL;
> >      }
> >
> > -  *value = NULL;
> >    return true;
> >  }
> >
> > @@ -1070,7 +1069,7 @@ void
> >  start_recording_case_labels (void)
> >  {
> >    gcc_assert (edge_to_cases == NULL);
> > -  edge_to_cases = pointer_map_create ();
> > +  edge_to_cases = new hash_map<edge, tree>;
> >    touched_switch_bbs = BITMAP_ALLOC (NULL);
> >  }
> >
> > @@ -1089,8 +1088,8 @@ end_recording_case_labels (void)
> >  {
> >    bitmap_iterator bi;
> >    unsigned i;
> > -  pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL);
> > -  pointer_map_destroy (edge_to_cases);
> > +  edge_to_cases->traverse<void *, edge_to_cases_cleanup> (NULL);
> > +  delete edge_to_cases;
> >    edge_to_cases = NULL;
> >    EXECUTE_IF_SET_IN_BITMAP (touched_switch_bbs, 0, i, bi)
> >      {
> > @@ -1113,7 +1112,7 @@ end_recording_case_labels (void)
> >  static tree
> >  get_cases_for_edge (edge e, gimple t)
> >  {
> > -  void **slot;
> > +  tree *slot;
> >    size_t i, n;
> >
> >    /* If we are not recording cases, then we do not have CASE_LABEL_EXPR
> > @@ -1121,9 +1120,9 @@ get_cases_for_edge (edge e, gimple t)
> >    if (!recording_case_labels_p ())
> >      return NULL;
> >
> > -  slot = pointer_map_contains (edge_to_cases, e);
> > +  slot = edge_to_cases->get (e);
> >    if (slot)
> > -    return (tree) *slot;
> > +    return *slot;
> >
> >    /* If we did not find E in the hash table, then this must be the first
> >       time we have been queried for information about E & T.  Add all the
> > @@ -1139,12 +1138,12 @@ get_cases_for_edge (edge e, gimple t)
> >
> >        /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
> >          a new chain.  */
> > -      slot = pointer_map_insert (edge_to_cases, this_edge);
> > -      CASE_CHAIN (elt) = (tree) *slot;
> > -      *slot = elt;
> > +      tree &s = edge_to_cases->get_or_insert (this_edge);
> > +      CASE_CHAIN (elt) = s;
> > +      s = elt;
> >      }
> >
> > -  return (tree) *pointer_map_contains (edge_to_cases, e);
> > +  return *edge_to_cases->get (e);
> >  }
> >
> >  /* Create the edges for a GIMPLE_SWITCH starting at block BB.  */
> > @@ -2577,12 +2576,11 @@ last_and_only_stmt (basic_block bb)
> >  static void
> >  reinstall_phi_args (edge new_edge, edge old_edge)
> >  {
> > -  edge_var_map_vector *v;
> >    edge_var_map *vm;
> >    int i;
> >    gimple_stmt_iterator phis;
> >
> > -  v = redirect_edge_var_map_vector (old_edge);
> > +  vec<edge_var_map> *v = redirect_edge_var_map_vector (old_edge);
> >    if (!v)
> >      return;
> >
> > @@ -6268,22 +6266,20 @@ gather_blocks_in_sese_region (basic_block entry, basic_block exit,
> >     The duplicates are recorded in VARS_MAP.  */
> >
> >  static void
> > -replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
> > +replace_by_duplicate_decl (tree *tp, hash_map<tree, tree> *vars_map,
> >                            tree to_context)
> >  {
> >    tree t = *tp, new_t;
> >    struct function *f = DECL_STRUCT_FUNCTION (to_context);
> > -  void **loc;
> >
> >    if (DECL_CONTEXT (t) == to_context)
> >      return;
> >
> > -  loc = pointer_map_contains (vars_map, t);
> > +  bool existed;
> > +  tree &loc = vars_map->get_or_insert (t, &existed);
> >
> > -  if (!loc)
> > +  if (!existed)
> >      {
> > -      loc = pointer_map_insert (vars_map, t);
> > -
> >        if (SSA_VAR_P (t))
> >         {
> >           new_t = copy_var_decl (t, DECL_NAME (t), TREE_TYPE (t));
> > @@ -6296,10 +6292,10 @@ replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
> >         }
> >        DECL_CONTEXT (new_t) = to_context;
> >
> > -      *loc = new_t;
> > +      loc = new_t;
> >      }
> >    else
> > -    new_t = (tree) *loc;
> > +    new_t = loc;
> >
> >    *tp = new_t;
> >  }
> > @@ -6309,15 +6305,14 @@ replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
> >     VARS_MAP maps old ssa names and var_decls to the new ones.  */
> >
> >  static tree
> > -replace_ssa_name (tree name, struct pointer_map_t *vars_map,
> > +replace_ssa_name (tree name, hash_map<tree, tree> *vars_map,
> >                   tree to_context)
> >  {
> > -  void **loc;
> >    tree new_name;
> >
> >    gcc_assert (!virtual_operand_p (name));
> >
> > -  loc = pointer_map_contains (vars_map, name);
> > +  tree *loc = vars_map->get (name);
> >
> >    if (!loc)
> >      {
> > @@ -6335,11 +6330,10 @@ replace_ssa_name (tree name, struct pointer_map_t *vars_map,
> >         new_name = copy_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context),
> >                                      name, SSA_NAME_DEF_STMT (name));
> >
> > -      loc = pointer_map_insert (vars_map, name);
> > -      *loc = new_name;
> > +      vars_map->put (name, new_name);
> >      }
> >    else
> > -    new_name = (tree) *loc;
> > +    new_name = *loc;
> >
> >    return new_name;
> >  }
> > @@ -6350,9 +6344,9 @@ struct move_stmt_d
> >    tree new_block;
> >    tree from_context;
> >    tree to_context;
> > -  struct pointer_map_t *vars_map;
> > +  hash_map<tree, tree> *vars_map;
> >    htab_t new_label_map;
> > -  struct pointer_map_t *eh_map;
> > +  hash_map<void *, void *> *eh_map;
> >    bool remap_decls_p;
> >  };
> >
> > @@ -6429,11 +6423,9 @@ static int
> >  move_stmt_eh_region_nr (int old_nr, struct move_stmt_d *p)
> >  {
> >    eh_region old_r, new_r;
> > -  void **slot;
> >
> >    old_r = get_eh_region_from_number (old_nr);
> > -  slot = pointer_map_contains (p->eh_map, old_r);
> > -  new_r = (eh_region) *slot;
> > +  new_r = static_cast<eh_region> (*p->eh_map->get (old_r));
> >
> >    return new_r->index;
> >  }
> > @@ -6767,7 +6759,7 @@ new_label_mapper (tree decl, void *data)
> >     subblocks.  */
> >
> >  static void
> > -replace_block_vars_by_duplicates (tree block, struct pointer_map_t *vars_map,
> > +replace_block_vars_by_duplicates (tree block, hash_map<tree, tree> *vars_map,
> >                                   tree to_context)
> >  {
> >    tree *tp, t;
> > @@ -6845,7 +6837,7 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
> >    edge e;
> >    edge_iterator ei;
> >    htab_t new_label_map;
> > -  struct pointer_map_t *vars_map, *eh_map;
> > +  hash_map<void *, void *> *eh_map;
> >    struct loop *loop = entry_bb->loop_father;
> >    struct loop *loop0 = get_loop (saved_cfun, 0);
> >    struct move_stmt_d d;
> > @@ -6989,14 +6981,14 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
> >    /* Move blocks from BBS into DEST_CFUN.  */
> >    gcc_assert (bbs.length () >= 2);
> >    after = dest_cfun->cfg->x_entry_block_ptr;
> > -  vars_map = pointer_map_create ();
> > +  hash_map<tree, tree> vars_map;
> >
> >    memset (&d, 0, sizeof (d));
> >    d.orig_block = orig_block;
> >    d.new_block = DECL_INITIAL (dest_cfun->decl);
> >    d.from_context = cfun->decl;
> >    d.to_context = dest_cfun->decl;
> > -  d.vars_map = vars_map;
> > +  d.vars_map = &vars_map;
> >    d.new_label_map = new_label_map;
> >    d.eh_map = eh_map;
> >    d.remap_decls_p = true;
> > @@ -7051,13 +7043,12 @@ move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
> >      }
> >
> >    replace_block_vars_by_duplicates (DECL_INITIAL (dest_cfun->decl),
> > -                                   vars_map, dest_cfun->decl);
> > +                                   &vars_map, dest_cfun->decl);
> >
> >    if (new_label_map)
> >      htab_delete (new_label_map);
> >    if (eh_map)
> > -    pointer_map_destroy (eh_map);
> > -  pointer_map_destroy (vars_map);
> > +    delete eh_map;
> >
> >    /* Rewire the entry and exit blocks.  The successor to the entry
> >       block turns into the successor of DEST_FN's ENTRY_BLOCK_PTR in
> > diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
> > index bc4d83e..2b6927e 100644
> > --- a/gcc/tree-cfgcleanup.c
> > +++ b/gcc/tree-cfgcleanup.c
> > @@ -865,16 +865,14 @@ remove_forwarder_block_with_phi (basic_block bb)
> >
> >           if (TREE_CODE (def) == SSA_NAME)
> >             {
> > -             edge_var_map_vector *head;
> > -             edge_var_map *vm;
> > -             size_t i;
> > -
> >               /* If DEF is one of the results of PHI nodes removed during
> >                  redirection, replace it with the PHI argument that used
> >                  to be on E.  */
> > -             head = redirect_edge_var_map_vector (e);
> > -             FOR_EACH_VEC_SAFE_ELT (head, i, vm)
> > +             vec<edge_var_map> *head = redirect_edge_var_map_vector (e);
> > +             size_t length = head ? head->length () : 0;
> > +             for (size_t i = 0; i < length; i++)
> >                 {
> > +                 edge_var_map *vm = &(*head)[i];
> >                   tree old_arg = redirect_edge_var_map_result (vm);
> >                   tree new_arg = redirect_edge_var_map_def (vm);
> >
> > diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
> > index 38842e8..db28184 100644
> > --- a/gcc/tree-eh.c
> > +++ b/gcc/tree-eh.c
> > @@ -406,7 +406,7 @@ struct leh_tf_state
> >    size_t goto_queue_active;
> >
> >    /* Pointer map to help in searching goto_queue when it is large.  */
> > -  struct pointer_map_t *goto_queue_map;
> > +  hash_map<gimple, goto_queue_node *> *goto_queue_map;
> >
> >    /* The set of unique labels seen as entries in the goto queue.  */
> >    vec<tree> dest_array;
> > @@ -441,7 +441,6 @@ static gimple_seq
> >  find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
> >  {
> >    unsigned int i;
> > -  void **slot;
> >
> >    if (tf->goto_queue_active < LARGE_GOTO_QUEUE)
> >      {
> > @@ -456,19 +455,18 @@ find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
> >
> >    if (!tf->goto_queue_map)
> >      {
> > -      tf->goto_queue_map = pointer_map_create ();
> > +      tf->goto_queue_map = new hash_map<gimple, goto_queue_node *>;
> >        for (i = 0; i < tf->goto_queue_active; i++)
> >         {
> > -         slot = pointer_map_insert (tf->goto_queue_map,
> > -                                     tf->goto_queue[i].stmt.g);
> > -          gcc_assert (*slot == NULL);
> > -         *slot = &tf->goto_queue[i];
> > +         bool existed = tf->goto_queue_map->put (tf->goto_queue[i].stmt.g,
> > +                                                 &tf->goto_queue[i]);
> > +         gcc_assert (!existed);
> >         }
> >      }
> >
> > -  slot = pointer_map_contains (tf->goto_queue_map, stmt.g);
> > +  goto_queue_node **slot = tf->goto_queue_map->get (stmt.g);
> >    if (slot != NULL)
> > -    return (((struct goto_queue_node *) *slot)->repl_stmt);
> > +    return ((*slot)->repl_stmt);
> >
> >    return NULL;
> >  }
> > @@ -1372,7 +1370,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
> >    tree tmp;
> >    gimple switch_stmt;
> >    gimple_seq finally;
> > -  struct pointer_map_t *cont_map = NULL;
> > +  hash_map<tree, gimple> *cont_map = NULL;
> >    /* The location of the TRY_FINALLY stmt.  */
> >    location_t tf_loc = gimple_location (tf->try_finally_expr);
> >    /* The location of the finally block.  */
> > @@ -1511,32 +1509,27 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
> >        if (case_label_vec.length () <= case_index || !case_label_vec[case_index])
> >          {
> >            tree case_lab;
> > -          void **slot;
> >           tmp = build_int_cst (integer_type_node, switch_id);
> >            case_lab = build_case_label (tmp, NULL,
> >                                        create_artificial_label (tf_loc));
> >            /* We store the cont_stmt in the pointer map, so that we can recover
> >               it in the loop below.  */
> >            if (!cont_map)
> > -            cont_map = pointer_map_create ();
> > -          slot = pointer_map_insert (cont_map, case_lab);
> > -          *slot = q->cont_stmt;
> > +            cont_map = new hash_map<tree, gimple>;
> > +          cont_map->put (case_lab, q->cont_stmt);
> >            case_label_vec.quick_push (case_lab);
> >          }
> >      }
> >    for (j = last_case_index; j < last_case_index + nlabels; j++)
> >      {
> >        gimple cont_stmt;
> > -      void **slot;
> >
> >        last_case = case_label_vec[j];
> >
> >        gcc_assert (last_case);
> >        gcc_assert (cont_map);
> >
> > -      slot = pointer_map_contains (cont_map, last_case);
> > -      gcc_assert (slot);
> > -      cont_stmt = *(gimple *) slot;
> > +      cont_stmt = *cont_map->get (last_case);
> >
> >        x = gimple_build_label (CASE_LABEL (last_case));
> >        gimple_seq_add_stmt (&switch_body, x);
> > @@ -1544,7 +1537,7 @@ lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
> >        maybe_record_in_goto_queue (state, cont_stmt);
> >      }
> >    if (cont_map)
> > -    pointer_map_destroy (cont_map);
> > +    delete cont_map;
> >
> >    replace_goto_queue (tf);
> >
> > @@ -1734,7 +1727,7 @@ lower_try_finally (struct leh_state *state, gimple tp)
> >    this_tf.dest_array.release ();
> >    free (this_tf.goto_queue);
> >    if (this_tf.goto_queue_map)
> > -    pointer_map_destroy (this_tf.goto_queue_map);
> > +    delete this_tf.goto_queue_map;
> >
> >    /* If there was an old (aka outer) eh_seq, append the current eh_seq.
> >       If there was no old eh_seq, then the append is trivially already done.  */
> > @@ -2921,10 +2914,10 @@ maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
> >  bool
> >  maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
> >                             struct function *old_fun, gimple old_stmt,
> > -                           struct pointer_map_t *map, int default_lp_nr)
> > +                           hash_map<void *, void *> *map,
> > +                           int default_lp_nr)
> >  {
> >    int old_lp_nr, new_lp_nr;
> > -  void **slot;
> >
> >    if (!stmt_could_throw_p (new_stmt))
> >      return false;
> > @@ -2941,8 +2934,7 @@ maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
> >        eh_landing_pad old_lp, new_lp;
> >
> >        old_lp = (*old_fun->eh->lp_array)[old_lp_nr];
> > -      slot = pointer_map_contains (map, old_lp);
> > -      new_lp = (eh_landing_pad) *slot;
> > +      new_lp = static_cast<eh_landing_pad> (*map->get (old_lp));
> >        new_lp_nr = new_lp->index;
> >      }
> >    else
> > @@ -2950,8 +2942,7 @@ maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
> >        eh_region old_r, new_r;
> >
> >        old_r = (*old_fun->eh->region_array)[-old_lp_nr];
> > -      slot = pointer_map_contains (map, old_r);
> > -      new_r = (eh_region) *slot;
> > +      new_r = static_cast<eh_region> (*map->get (old_r));
> >        new_lp_nr = -new_r->index;
> >      }
> >
> > @@ -3154,7 +3145,7 @@ make_pass_refactor_eh (gcc::context *ctxt)
> >  /* At the end of gimple optimization, we can lower RESX.  */
> >
> >  static bool
> > -lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
> > +lower_resx (basic_block bb, gimple stmt, hash_map<eh_region, tree> *mnt_map)
> >  {
> >    int lp_nr;
> >    eh_region src_r, dst_r;
> > @@ -3199,14 +3190,13 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
> >        if (lp_nr < 0)
> >         {
> >           basic_block new_bb;
> > -         void **slot;
> >           tree lab;
> >
> >           /* We are resuming into a MUST_NOT_CALL region.  Expand a call to
> >              the failure decl into a new block, if needed.  */
> >           gcc_assert (dst_r->type == ERT_MUST_NOT_THROW);
> >
> > -         slot = pointer_map_contains (mnt_map, dst_r);
> > +         tree *slot = mnt_map->get (dst_r);
> >           if (slot == NULL)
> >             {
> >               gimple_stmt_iterator gsi2;
> > @@ -3221,12 +3211,11 @@ lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
> >               gimple_set_location (x, dst_r->u.must_not_throw.failure_loc);
> >               gsi_insert_after (&gsi2, x, GSI_CONTINUE_LINKING);
> >
> > -             slot = pointer_map_insert (mnt_map, dst_r);
> > -             *slot = lab;
> > +             mnt_map->put (dst_r, lab);
> >             }
> >           else
> >             {
> > -             lab = (tree) *slot;
> > +             lab = *slot;
> >               new_bb = label_to_block (lab);
> >             }
> >
> > @@ -3334,24 +3323,21 @@ unsigned
> >  pass_lower_resx::execute (function *fun)
> >  {
> >    basic_block bb;
> > -  struct pointer_map_t *mnt_map;
> >    bool dominance_invalidated = false;
> >    bool any_rewritten = false;
> >
> > -  mnt_map = pointer_map_create ();
> > +  hash_map<eh_region, tree> mnt_map;
> >
> >    FOR_EACH_BB_FN (bb, fun)
> >      {
> >        gimple last = last_stmt (bb);
> >        if (last && is_gimple_resx (last))
> >         {
> > -         dominance_invalidated |= lower_resx (bb, last, mnt_map);
> > +         dominance_invalidated |= lower_resx (bb, last, &mnt_map);
> >           any_rewritten = true;
> >         }
> >      }
> >
> > -  pointer_map_destroy (mnt_map);
> > -
> >    if (dominance_invalidated)
> >      {
> >        free_dominance_info (CDI_DOMINATORS);
> > diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h
> > index cd9b40d..51c2adc 100644
> > --- a/gcc/tree-eh.h
> > +++ b/gcc/tree-eh.h
> > @@ -20,6 +20,10 @@ along with GCC; see the file COPYING3.  If not see
> >  #ifndef GCC_TREE_EH_H
> >  #define GCC_TREE_EH_H
> >
> > +#include "hash-map.h"
> > +
> > +typedef struct eh_region_d *eh_region;
> > +
> >  extern void using_eh_for_cleanups (void);
> >  extern void add_stmt_to_eh_lp (gimple, int);
> >  extern bool remove_stmt_from_eh_lp_fn (struct function *, gimple);
> > @@ -43,7 +47,7 @@ extern bool maybe_clean_eh_stmt (gimple);
> >  extern bool maybe_clean_or_replace_eh_stmt (gimple, gimple);
> >  extern bool maybe_duplicate_eh_stmt_fn (struct function *, gimple,
> >                                         struct function *, gimple,
> > -                                       struct pointer_map_t *, int);
> > +                                       hash_map<void *, void *> *, int);
> >  extern bool maybe_duplicate_eh_stmt (gimple, gimple);
> >  extern void maybe_remove_unreachable_handlers (void);
> >  extern bool verify_eh_edges (gimple);
> > diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
> > index 6af4912..e2b7990 100644
> > --- a/gcc/tree-inline.c
> > +++ b/gcc/tree-inline.c
> > @@ -135,7 +135,7 @@ static tree declare_return_variable (copy_body_data *, tree, tree, basic_block);
> >  static void remap_block (tree *, copy_body_data *);
> >  static void copy_bind_expr (tree *, int *, copy_body_data *);
> >  static void declare_inline_vars (tree, tree);
> > -static void remap_save_expr (tree *, void *, int *);
> > +static void remap_save_expr (tree *, hash_map<tree, tree> *, int *);
> >  static void prepend_lexical_block (tree current_block, tree new_block);
> >  static tree copy_decl_to_var (tree, copy_body_data *);
> >  static tree copy_result_decl_to_var (tree, copy_body_data *);
> > @@ -149,12 +149,12 @@ static bool delete_unreachable_blocks_update_callgraph (copy_body_data *id);
> >  void
> >  insert_decl_map (copy_body_data *id, tree key, tree value)
> >  {
> > -  *pointer_map_insert (id->decl_map, key) = value;
> > +  id->decl_map->put (key, value);
> >
> >    /* Always insert an identity map as well.  If we see this same new
> >       node again, we won't want to duplicate it a second time.  */
> >    if (key != value)
> > -    *pointer_map_insert (id->decl_map, value) = value;
> > +    id->decl_map->put (value, value);
> >  }
> >
> >  /* Insert a tree->tree mapping for ID.  This is only used for
> > @@ -176,9 +176,9 @@ insert_debug_decl_map (copy_body_data *id, tree key, tree value)
> >    gcc_assert (TREE_CODE (value) == VAR_DECL);
> >
> >    if (!id->debug_map)
> > -    id->debug_map = pointer_map_create ();
> > +    id->debug_map = new hash_map<tree, tree>;
> >
> > -  *pointer_map_insert (id->debug_map, key) = value;
> > +  id->debug_map->put (key, value);
> >  }
> >
> >  /* If nonzero, we're remapping the contents of inlined debug
> > @@ -197,7 +197,7 @@ remap_ssa_name (tree name, copy_body_data *id)
> >
> >    gcc_assert (TREE_CODE (name) == SSA_NAME);
> >
> > -  n = (tree *) pointer_map_contains (id->decl_map, name);
> > +  n = id->decl_map->get (name);
> >    if (n)
> >      return unshare_expr (*n);
> >
> > @@ -213,7 +213,7 @@ remap_ssa_name (tree name, copy_body_data *id)
> >           gimple_stmt_iterator gsi;
> >           tree val = SSA_NAME_VAR (name);
> >
> > -         n = (tree *) pointer_map_contains (id->decl_map, val);
> > +         n = id->decl_map->get (val);
> >           if (n != NULL)
> >             val = *n;
> >           if (TREE_CODE (val) != PARM_DECL)
> > @@ -342,7 +342,7 @@ remap_decl (tree decl, copy_body_data *id)
> >
> >    /* See if we have remapped this declaration.  */
> >
> > -  n = (tree *) pointer_map_contains (id->decl_map, decl);
> > +  n = id->decl_map->get (decl);
> >
> >    if (!n && processing_debug_stmt)
> >      {
> > @@ -562,7 +562,7 @@ remap_type (tree type, copy_body_data *id)
> >      return type;
> >
> >    /* See if we have remapped this type.  */
> > -  node = (tree *) pointer_map_contains (id->decl_map, type);
> > +  node = id->decl_map->get (type);
> >    if (node)
> >      return *node;
> >
> > @@ -887,7 +887,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
> >      {
> >        /* If the enclosing record type is variably_modified_type_p, the field
> >          has already been remapped.  Otherwise, it need not be.  */
> > -      tree *n = (tree *) pointer_map_contains (id->decl_map, *tp);
> > +      tree *n = id->decl_map->get (*tp);
> >        if (n)
> >         *tp = *n;
> >        *walk_subtrees = 0;
> > @@ -981,8 +981,7 @@ remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
> >        if (old_block)
> >         {
> >           tree *n;
> > -         n = (tree *) pointer_map_contains (id->decl_map,
> > -                                            TREE_BLOCK (*tp));
> > +         n = id->decl_map->get (TREE_BLOCK (*tp));
> >           if (n)
> >             new_block = *n;
> >         }
> > @@ -1108,7 +1107,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
> >           tree decl = TREE_OPERAND (*tp, 0), value;
> >           tree *n;
> >
> > -         n = (tree *) pointer_map_contains (id->decl_map, decl);
> > +         n = id->decl_map->get (decl);
> >           if (n)
> >             {
> >               value = *n;
> > @@ -1125,7 +1124,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
> >           /* Get rid of *& from inline substitutions that can happen when a
> >              pointer argument is an ADDR_EXPR.  */
> >           tree decl = TREE_OPERAND (*tp, 0);
> > -         tree *n = (tree *) pointer_map_contains (id->decl_map, decl);
> > +         tree *n = id->decl_map->get (decl);
> >           if (n)
> >             {
> >               /* If we happen to get an ADDR_EXPR in n->value, strip
> > @@ -1206,8 +1205,7 @@ copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
> >           if (TREE_BLOCK (*tp))
> >             {
> >               tree *n;
> > -             n = (tree *) pointer_map_contains (id->decl_map,
> > -                                                TREE_BLOCK (*tp));
> > +             n = id->decl_map->get (TREE_BLOCK (*tp));
> >               if (n)
> >                 new_block = *n;
> >             }
> > @@ -1261,11 +1259,9 @@ static int
> >  remap_eh_region_nr (int old_nr, copy_body_data *id)
> >  {
> >    eh_region old_r, new_r;
> > -  void **slot;
> >
> >    old_r = get_eh_region_from_number_fn (id->src_cfun, old_nr);
> > -  slot = pointer_map_contains (id->eh_map, old_r);
> > -  new_r = (eh_region) *slot;
> > +  new_r = static_cast<eh_region> (*id->eh_map->get (old_r));
> >
> >    return new_r->index;
> >  }
> > @@ -1483,7 +1479,7 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
> >           tree decl = gimple_assign_lhs (stmt), value;
> >           tree *n;
> >
> > -         n = (tree *) pointer_map_contains (id->decl_map, decl);
> > +         n = id->decl_map->get (decl);
> >           if (n)
> >             {
> >               value = *n;
> > @@ -1597,7 +1593,7 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
> >    if (gimple_block (copy))
> >      {
> >        tree *n;
> > -      n = (tree *) pointer_map_contains (id->decl_map, gimple_block (copy));
> > +      n = id->decl_map->get (gimple_block (copy));
> >        gcc_assert (n);
> >        gimple_set_block (copy, *n);
> >      }
> > @@ -2191,8 +2187,7 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
> >               if (LOCATION_BLOCK (locus))
> >                 {
> >                   tree *n;
> > -                 n = (tree *) pointer_map_contains (id->decl_map,
> > -                       LOCATION_BLOCK (locus));
> > +                 n = id->decl_map->get (LOCATION_BLOCK (locus));
> >                   gcc_assert (n);
> >                   if (*n)
> >                     locus = COMBINE_LOCATION_DATA (line_table, locus, *n);
> > @@ -2638,7 +2633,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
> >
> >    if (id->eh_map)
> >      {
> > -      pointer_map_destroy (id->eh_map);
> > +      delete id->eh_map;
> >        id->eh_map = NULL;
> >      }
> >
> > @@ -2659,7 +2654,7 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
> >
> >    if (gimple_block (stmt))
> >      {
> > -      n = (tree *) pointer_map_contains (id->decl_map, gimple_block (stmt));
> > +      n = id->decl_map->get (gimple_block (stmt));
> >        gimple_set_block (stmt, n ? *n : id->block);
> >      }
> >
> > @@ -2675,14 +2670,14 @@ copy_debug_stmt (gimple stmt, copy_body_data *id)
> >      t = gimple_debug_bind_get_var (stmt);
> >
> >    if (TREE_CODE (t) == PARM_DECL && id->debug_map
> > -      && (n = (tree *) pointer_map_contains (id->debug_map, t)))
> > +      && (n = id->debug_map->get (t)))
> >      {
> >        gcc_assert (TREE_CODE (*n) == VAR_DECL);
> >        t = *n;
> >      }
> >    else if (TREE_CODE (t) == VAR_DECL
> >            && !is_global_var (t)
> > -          && !pointer_map_contains (id->decl_map, t))
> > +          && !id->decl_map->get (t))
> >      /* T is a non-localized variable.  */;
> >    else
> >      walk_tree (&t, remap_gimple_op_r, &wi, NULL);
> > @@ -3076,7 +3071,7 @@ initialize_inlined_parameters (copy_body_data *id, gimple stmt,
> >       parameter following the array.  */
> >    for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
> >      {
> > -      tree *varp = (tree *) pointer_map_contains (id->decl_map, p);
> > +      tree *varp = id->decl_map->get (p);
> >        if (varp
> >           && TREE_CODE (*varp) == VAR_DECL)
> >         {
> > @@ -3089,7 +3084,7 @@ initialize_inlined_parameters (copy_body_data *id, gimple stmt,
> >              by the parameter setup.  */
> >           if (def)
> >             {
> > -             tree *defp = (tree *) pointer_map_contains (id->decl_map, def);
> > +             tree *defp = id->decl_map->get (def);
> >               if (defp
> >                   && TREE_CODE (*defp) == SSA_NAME
> >                   && SSA_NAME_VAR (*defp) == var)
> > @@ -4135,7 +4130,8 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
> >  {
> >    tree use_retvar;
> >    tree fn;
> > -  struct pointer_map_t *st, *dst;
> > +  hash_map<tree, tree> *dst;
> > +  hash_map<tree, tree> *st = NULL;
> >    tree return_slot;
> >    tree modify_dest;
> >    location_t saved_location;
> > @@ -4291,7 +4287,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
> >    /* Local declarations will be replaced by their equivalents in this
> >       map.  */
> >    st = id->decl_map;
> > -  id->decl_map = pointer_map_create ();
> > +  id->decl_map = new hash_map<tree, tree>;
> >    dst = id->debug_map;
> >    id->debug_map = NULL;
> >
> > @@ -4415,10 +4411,10 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
> >    /* Clean up.  */
> >    if (id->debug_map)
> >      {
> > -      pointer_map_destroy (id->debug_map);
> > +      delete id->debug_map;
> >        id->debug_map = dst;
> >      }
> > -  pointer_map_destroy (id->decl_map);
> > +  delete id->decl_map;
> >    id->decl_map = st;
> >
> >    /* Unlink the calls virtual operands before replacing it.  */
> > @@ -4772,14 +4768,13 @@ copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
> >     the function into which the copy will be placed.  */
> >
> >  static void
> > -remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
> > +remap_save_expr (tree *tp, hash_map<tree, tree> *st, int *walk_subtrees)
> >  {
> > -  struct pointer_map_t *st = (struct pointer_map_t *) st_;
> >    tree *n;
> >    tree t;
> >
> >    /* See if we already encountered this SAVE_EXPR.  */
> > -  n = (tree *) pointer_map_contains (st, *tp);
> > +  n = st->get (*tp);
> >
> >    /* If we didn't already remap this SAVE_EXPR, do so now.  */
> >    if (!n)
> > @@ -4787,9 +4782,9 @@ remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
> >        t = copy_node (*tp);
> >
> >        /* Remember this SAVE_EXPR.  */
> > -      *pointer_map_insert (st, *tp) = t;
> > +      st->put (*tp, t);
> >        /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
> > -      *pointer_map_insert (st, t) = t;
> > +      st->put (t, t);
> >      }
> >    else
> >      {
> > @@ -4836,7 +4831,7 @@ replace_locals_op (tree *tp, int *walk_subtrees, void *data)
> >  {
> >    struct walk_stmt_info *wi = (struct walk_stmt_info*) data;
> >    copy_body_data *id = (copy_body_data *) wi->info;
> > -  struct pointer_map_t *st = id->decl_map;
> > +  hash_map<tree, tree> *st = id->decl_map;
> >    tree *n;
> >    tree expr = *tp;
> >
> > @@ -4846,7 +4841,7 @@ replace_locals_op (tree *tp, int *walk_subtrees, void *data)
> >        || TREE_CODE (expr) == LABEL_DECL)
> >      {
> >        /* Lookup the declaration.  */
> > -      n = (tree *) pointer_map_contains (st, expr);
> > +      n = st->get (expr);
> >
> >        /* If it's there, remap it.  */
> >        if (n)
> > @@ -4928,7 +4923,7 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
> >    memset (&id, 0, sizeof (id));
> >    id.src_fn = current_function_decl;
> >    id.dst_fn = current_function_decl;
> > -  id.decl_map = pointer_map_create ();
> > +  id.decl_map = new hash_map<tree, tree>;
> >    id.debug_map = NULL;
> >
> >    id.copy_decl = copy_decl_no_change;
> > @@ -4953,9 +4948,9 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
> >    walk_gimple_seq (copy, replace_locals_stmt, replace_locals_op, &wi);
> >
> >    /* Clean up.  */
> > -  pointer_map_destroy (id.decl_map);
> > +  delete id.decl_map;
> >    if (id.debug_map)
> > -    pointer_map_destroy (id.debug_map);
> > +    delete id.debug_map;
> >
> >    return copy;
> >  }
> > @@ -5145,7 +5140,7 @@ copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
> >          *parg = new_tree;
> >         parg = &DECL_CHAIN (new_tree);
> >        }
> > -    else if (!pointer_map_contains (id->decl_map, arg))
> > +    else if (!id->decl_map->get (arg))
> >        {
> >         /* Make an equivalent VAR_DECL.  If the argument was used
> >            as temporary variable later in function, the uses will be
> > @@ -5368,7 +5363,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
> >    /* Generate a new name for the new version. */
> >    id.statements_to_fold = new hash_set<gimple>;
> >
> > -  id.decl_map = pointer_map_create ();
> > +  id.decl_map = new hash_map<tree, tree>;
> >    id.debug_map = NULL;
> >    id.src_fn = old_decl;
> >    id.dst_fn = new_decl;
> > @@ -5530,9 +5525,9 @@ tree_function_versioning (tree old_decl, tree new_decl,
> >      }
> >
> >    /* Clean up.  */
> > -  pointer_map_destroy (id.decl_map);
> > +  delete id.decl_map;
> >    if (id.debug_map)
> > -    pointer_map_destroy (id.debug_map);
> > +    delete id.debug_map;
> >    free_dominance_info (CDI_DOMINATORS);
> >    free_dominance_info (CDI_POST_DOMINATORS);
> >
> > @@ -5587,22 +5582,22 @@ maybe_inline_call_in_expr (tree exp)
> >    /* We can only try to inline "const" functions.  */
> >    if (fn && TREE_READONLY (fn) && DECL_SAVED_TREE (fn))
> >      {
> > -      struct pointer_map_t *decl_map = pointer_map_create ();
> >        call_expr_arg_iterator iter;
> >        copy_body_data id;
> >        tree param, arg, t;
> > +      hash_map<tree, tree> decl_map;
> >
> >        /* Remap the parameters.  */
> >        for (param = DECL_ARGUMENTS (fn), arg = first_call_expr_arg (exp, &iter);
> >            param;
> >            param = DECL_CHAIN (param), arg = next_call_expr_arg (&iter))
> > -       *pointer_map_insert (decl_map, param) = arg;
> > +       decl_map.put (param, arg);
> >
> >        memset (&id, 0, sizeof (id));
> >        id.src_fn = fn;
> >        id.dst_fn = current_function_decl;
> >        id.src_cfun = DECL_STRUCT_FUNCTION (fn);
> > -      id.decl_map = decl_map;
> > +      id.decl_map = &decl_map;
> >
> >        id.copy_decl = copy_decl_no_change;
> >        id.transform_call_graph_edges = CB_CGE_DUPLICATE;
> > @@ -5620,7 +5615,6 @@ maybe_inline_call_in_expr (tree exp)
> >        id.eh_lp_nr = 0;
> >
> >        t = copy_tree_body (&id);
> > -      pointer_map_destroy (decl_map);
> >
> >        /* We can only return something suitable for use in a GENERIC
> >          expression tree.  */
> > @@ -5642,15 +5636,15 @@ build_duplicate_type (tree type)
> >    id.src_fn = current_function_decl;
> >    id.dst_fn = current_function_decl;
> >    id.src_cfun = cfun;
> > -  id.decl_map = pointer_map_create ();
> > +  id.decl_map = new hash_map<tree, tree>;
> >    id.debug_map = NULL;
> >    id.copy_decl = copy_decl_no_change;
> >
> >    type = remap_type_1 (type, &id);
> >
> > -  pointer_map_destroy (id.decl_map);
> > +  delete id.decl_map;
> >    if (id.debug_map)
> > -    pointer_map_destroy (id.debug_map);
> > +    delete id.debug_map;
> >
> >    TYPE_CANONICAL (type) = type;
> >
> > diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
> > index c13e6c7..53059da 100644
> > --- a/gcc/tree-inline.h
> > +++ b/gcc/tree-inline.h
> > @@ -21,6 +21,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #ifndef GCC_TREE_INLINE_H
> >  #define GCC_TREE_INLINE_H
> >
> > +#include "hash-map.h"
> >  #include "hash-set.h"
> >
> >  struct cgraph_edge;
> > @@ -64,7 +65,7 @@ struct copy_body_data
> >
> >    /* The map from local declarations in the inlined function to
> >       equivalents in the function into which it is being inlined.  */
> > -  struct pointer_map_t *decl_map;
> > +  hash_map<tree, tree> *decl_map;
> >
> >    /* Create a new decl to replace DECL in the destination function.  */
> >    tree (*copy_decl) (tree, struct copy_body_data *);
> > @@ -81,7 +82,7 @@ struct copy_body_data
> >
> >    /* Maps region and landing pad structures from the function being copied
> >       to duplicates created within the function we inline into.  */
> > -  struct pointer_map_t *eh_map;
> > +  hash_map<void *, void *> *eh_map;
> >
> >    /* We use the same mechanism do all sorts of different things.  Rather
> >       than enumerating the different cases, we categorize the behavior
> > @@ -132,7 +133,7 @@ struct copy_body_data
> >       equivalents in the function into which it is being inlined, where
> >       the originals have been mapped to a value rather than to a
> >       variable.  */
> > -  struct pointer_map_t *debug_map;
> > +  hash_map<tree, tree> *debug_map;
> >
> >    /* Cilk keywords currently need to replace some variables that
> >       ordinary nested functions do not.  */
> > diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
> > index 45c5cf7..7d5c039 100644
> > --- a/gcc/tree-nested.c
> > +++ b/gcc/tree-nested.c
> > @@ -93,8 +93,8 @@ struct nesting_info
> >    struct nesting_info *inner;
> >    struct nesting_info *next;
> >
> > -  struct pointer_map_t *field_map;
> > -  struct pointer_map_t *var_map;
> > +  hash_map<tree, tree> *field_map;
> > +  hash_map<tree, tree> *var_map;
> >    hash_set<tree *> *mem_refs;
> >    bitmap suppress_expansion;
> >
> > @@ -286,15 +286,13 @@ static tree
> >  lookup_field_for_decl (struct nesting_info *info, tree decl,
> >                        enum insert_option insert)
> >  {
> > -  void **slot;
> > -
> >    if (insert == NO_INSERT)
> >      {
> > -      slot = pointer_map_contains (info->field_map, decl);
> > -      return slot ? (tree) *slot : NULL_TREE;
> > +      tree *slot = info->field_map->get (decl);
> > +      return slot ? *slot : NULL_TREE;
> >      }
> >
> > -  slot = pointer_map_insert (info->field_map, decl);
> > +  tree *slot = &info->field_map->get_or_insert (decl);
> >    if (!*slot)
> >      {
> >        tree field = make_node (FIELD_DECL);
> > @@ -324,7 +322,7 @@ lookup_field_for_decl (struct nesting_info *info, tree decl,
> >         info->any_parm_remapped = true;
> >      }
> >
> > -  return (tree) *slot;
> > +  return *slot;
> >  }
> >
> >  /* Build or return the variable that holds the static chain within
> > @@ -521,15 +519,13 @@ static tree
> >  lookup_tramp_for_decl (struct nesting_info *info, tree decl,
> >                        enum insert_option insert)
> >  {
> > -  void **slot;
> > -
> >    if (insert == NO_INSERT)
> >      {
> > -      slot = pointer_map_contains (info->var_map, decl);
> > -      return slot ? (tree) *slot : NULL_TREE;
> > +      tree *slot = info->var_map->get (decl);
> > +      return slot ? *slot : NULL_TREE;
> >      }
> >
> > -  slot = pointer_map_insert (info->var_map, decl);
> > +  tree *slot = &info->var_map->get_or_insert (decl);
> >    if (!*slot)
> >      {
> >        tree field = make_node (FIELD_DECL);
> > @@ -543,7 +539,7 @@ lookup_tramp_for_decl (struct nesting_info *info, tree decl,
> >        info->any_tramp_created = true;
> >      }
> >
> > -  return (tree) *slot;
> > +  return *slot;
> >  }
> >
> >  /* Build or return the field within the non-local frame state that holds
> > @@ -730,8 +726,8 @@ static struct nesting_info *
> >  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->field_map = new hash_map<tree, tree>;
> > +  info->var_map = new hash_map<tree, tree>;
> >    info->mem_refs = new hash_set<tree *>;
> >    info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
> >    info->context = cgn->decl;
> > @@ -834,12 +830,11 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
> >    tree target_context;
> >    struct nesting_info *i;
> >    tree x, field, new_decl;
> > -  void **slot;
> >
> > -  slot = pointer_map_insert (info->var_map, decl);
> > +  tree *slot = &info->var_map->get_or_insert (decl);
> >
> >    if (*slot)
> > -    return (tree) *slot;
> > +    return *slot;
> >
> >    target_context = decl_function_context (decl);
> >
> > @@ -1483,11 +1478,10 @@ static tree
> >  get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
> >  {
> >    tree x, new_decl;
> > -  void **slot;
> >
> > -  slot = pointer_map_insert (info->var_map, decl);
> > +  tree *slot = &info->var_map->get_or_insert (decl);
> >    if (*slot)
> > -    return (tree) *slot;
> > +    return *slot;
> >
> >    /* Make sure frame_decl gets created.  */
> >    (void) get_frame_type (info);
> > @@ -2064,7 +2058,6 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
> >  {
> >    struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
> >    tree label, new_label, target_context, x, field;
> > -  void **slot;
> >    gimple call;
> >    gimple stmt = gsi_stmt (*gsi);
> >
> > @@ -2098,7 +2091,7 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
> >       (hairy target-specific) non-local goto receiver code to be generated
> >       when we expand rtl.  Enter this association into var_map so that we
> >       can insert the new label into the IL during a second pass.  */
> > -  slot = pointer_map_insert (i->var_map, label);
> > +  tree *slot = &i->var_map->get_or_insert (label);
> >    if (*slot == NULL)
> >      {
> >        new_label = create_artificial_label (UNKNOWN_LOCATION);
> > @@ -2106,7 +2099,7 @@ convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
> >        *slot = new_label;
> >      }
> >    else
> > -    new_label = (tree) *slot;
> > +    new_label = *slot;
> >
> >    /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field).  */
> >    field = get_nl_goto_field (i);
> > @@ -2136,7 +2129,6 @@ convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
> >    struct nesting_info *const info = (struct nesting_info *) wi->info;
> >    tree label, new_label;
> >    gimple_stmt_iterator tmp_gsi;
> > -  void **slot;
> >    gimple stmt = gsi_stmt (*gsi);
> >
> >    if (gimple_code (stmt) != GIMPLE_LABEL)
> > @@ -2147,7 +2139,7 @@ convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
> >
> >    label = gimple_label_label (stmt);
> >
> > -  slot = pointer_map_contains (info->var_map, label);
> > +  tree *slot = info->var_map->get (label);
> >    if (!slot)
> >      {
> >        *handled_ops_p = false;
> > @@ -2513,7 +2505,7 @@ static tree
> >  nesting_copy_decl (tree decl, copy_body_data *id)
> >  {
> >    struct nesting_copy_body_data *nid = (struct nesting_copy_body_data *) id;
> > -  void **slot = pointer_map_contains (nid->root->var_map, decl);
> > +  tree *slot = nid->root->var_map->get (decl);
> >
> >    if (slot)
> >      return (tree) *slot;
> > @@ -2542,15 +2534,14 @@ contains_remapped_vars (tree *tp, int *walk_subtrees, void *data)
> >  {
> >    struct nesting_info *root = (struct nesting_info *) data;
> >    tree t = *tp;
> > -  void **slot;
> >
> >    if (DECL_P (t))
> >      {
> >        *walk_subtrees = 0;
> > -      slot = pointer_map_contains (root->var_map, t);
> > +      tree *slot = root->var_map->get (t);
> >
> >        if (slot)
> > -       return (tree) *slot;
> > +       return *slot;
> >      }
> >    return NULL;
> >  }
> > @@ -2580,7 +2571,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
> >               && variably_modified_type_p (type, NULL)))
> >           continue;
> >
> > -       if (pointer_map_contains (root->var_map, TREE_OPERAND (val, 0))
> > +       if (root->var_map->get (TREE_OPERAND (val, 0))
> >             || walk_tree (&type, contains_remapped_vars, root, NULL))
> >           break;
> >        }
> > @@ -2590,7 +2581,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
> >
> >    memset (&id, 0, sizeof (id));
> >    id.cb.copy_decl = nesting_copy_decl;
> > -  id.cb.decl_map = pointer_map_create ();
> > +  id.cb.decl_map = new hash_map<tree, tree>;
> >    id.root = root;
> >
> >    for (; var; var = DECL_CHAIN (var))
> > @@ -2598,7 +2589,6 @@ remap_vla_decls (tree block, struct nesting_info *root)
> >        {
> >         struct nesting_info *i;
> >         tree newt, context;
> > -       void **slot;
> >
> >         val = DECL_VALUE_EXPR (var);
> >         type = TREE_TYPE (var);
> > @@ -2608,7 +2598,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
> >               && variably_modified_type_p (type, NULL)))
> >           continue;
> >
> > -       slot = pointer_map_contains (root->var_map, TREE_OPERAND (val, 0));
> > +       tree *slot = root->var_map->get (TREE_OPERAND (val, 0));
> >         if (!slot && !walk_tree (&type, contains_remapped_vars, root, NULL))
> >           continue;
> >
> > @@ -2651,7 +2641,7 @@ remap_vla_decls (tree block, struct nesting_info *root)
> >           SET_DECL_VALUE_EXPR (var, val);
> >        }
> >
> > -  pointer_map_destroy (id.cb.decl_map);
> > +  delete id.cb.decl_map;
> >  }
> >
> >  /* Fold the MEM_REF *E.  */
> > @@ -2830,7 +2820,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
> >
> >           memset (&id, 0, sizeof (id));
> >           id.cb.copy_decl = nesting_copy_decl;
> > -         id.cb.decl_map = pointer_map_create ();
> > +         id.cb.decl_map = new hash_map<tree, tree>;
> >           id.root = root;
> >
> >           for (; debug_var; debug_var = DECL_CHAIN (debug_var))
> > @@ -2865,7 +2855,7 @@ finalize_nesting_tree_1 (struct nesting_info *root)
> >                   TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
> >               }
> >
> > -         pointer_map_destroy (id.cb.decl_map);
> > +         delete id.cb.decl_map;
> >         }
> >
> >        scope = gimple_seq_first_stmt (gimple_body (root->context));
> > @@ -2931,8 +2921,8 @@ free_nesting_tree (struct nesting_info *root)
> >    do
> >      {
> >        next = iter_nestinfo_next (node);
> > -      pointer_map_destroy (node->var_map);
> > -      pointer_map_destroy (node->field_map);
> > +      delete node->var_map;
> > +      delete node->field_map;
> >        delete node->mem_refs;
> >        free (node);
> >        node = next;
> > diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
> > index f9d39ac..2231314 100644
> > --- a/gcc/tree-sra.c
> > +++ b/gcc/tree-sra.c
> > @@ -74,11 +74,11 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "config.h"
> >  #include "system.h"
> >  #include "coretypes.h"
> > +#include "hash-map.h"
> >  #include "hash-table.h"
> >  #include "alloc-pool.h"
> >  #include "tm.h"
> >  #include "tree.h"
> > -#include "pointer-set.h"
> >  #include "basic-block.h"
> >  #include "tree-ssa-alias.h"
> >  #include "internal-fn.h"
> > @@ -290,7 +290,7 @@ struct assign_link
> >  static alloc_pool link_pool;
> >
> >  /* Base (tree) -> Vector (vec<access_p> *) map.  */
> > -static struct pointer_map_t *base_access_vec;
> > +static hash_map<tree, auto_vec<access_p> > *base_access_vec;
> >
> >  /* Candidate hash table helpers.  */
> >
> > @@ -518,13 +518,7 @@ access_has_replacements_p (struct access *acc)
> >  static vec<access_p> *
> >  get_base_access_vector (tree base)
> >  {
> > -  void **slot;
> > -
> > -  slot = pointer_map_contains (base_access_vec, base);
> > -  if (!slot)
> > -    return NULL;
> > -  else
> > -    return *(vec<access_p> **) slot;
> > +  return base_access_vec->get (base);
> >  }
> >
> >  /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
> > @@ -667,24 +661,13 @@ sra_initialize (void)
> >    gcc_obstack_init (&name_obstack);
> >    access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
> >    link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
> > -  base_access_vec = pointer_map_create ();
> > +  base_access_vec = new hash_map<tree, auto_vec<access_p> >;
> >    memset (&sra_stats, 0, sizeof (sra_stats));
> >    encountered_apply_args = false;
> >    encountered_recursive_call = false;
> >    encountered_unchangable_recursive_call = false;
> >  }
> >
> > -/* Hook fed to pointer_map_traverse, deallocate stored vectors.  */
> > -
> > -static bool
> > -delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
> > -                    void *data ATTRIBUTE_UNUSED)
> > -{
> > -  vec<access_p> *access_vec = (vec<access_p> *) *value;
> > -  vec_free (access_vec);
> > -  return true;
> > -}
> > -
> >  /* Deallocate all general structures.  */
> >
> >  static void
> > @@ -699,8 +682,7 @@ sra_deinitialize (void)
> >    free_alloc_pool (link_pool);
> >    obstack_free (&name_obstack, NULL);
> >
> > -  pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
> > -  pointer_map_destroy (base_access_vec);
> > +  delete base_access_vec;
> >  }
> >
> >  /* Remove DECL from candidates for SRA and write REASON to the dump file if
> > @@ -849,9 +831,7 @@ mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
> >  static struct access *
> >  create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
> >  {
> > -  vec<access_p> *v;
> >    struct access *access;
> > -  void **slot;
> >
> >    access = (struct access *) pool_alloc (access_pool);
> >    memset (access, 0, sizeof (struct access));
> > @@ -859,16 +839,7 @@ create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
> >    access->offset = offset;
> >    access->size = size;
> >
> > -  slot = pointer_map_contains (base_access_vec, base);
> > -  if (slot)
> > -    v = (vec<access_p> *) *slot;
> > -  else
> > -    vec_alloc (v, 32);
> > -
> > -  v->safe_push (access);
> > -
> > -  *((vec<access_p> **)
> > -       pointer_map_insert (base_access_vec, base)) = v;
> > +  base_access_vec->get_or_insert (base).safe_push (access);
> >
> >    return access;
> >  }
> > diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
> > index c614978..0cbb3ae 100644
> > --- a/gcc/tree-ssa-loop-im.c
> > +++ b/gcc/tree-ssa-loop-im.c
> > @@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "basic-block.h"
> >  #include "gimple-pretty-print.h"
> >  #include "pointer-set.h"
> > +#include "hash-map.h"
> >  #include "hash-table.h"
> >  #include "tree-ssa-alias.h"
> >  #include "internal-fn.h"
> > @@ -103,7 +104,7 @@ struct lim_aux_data
> >
> >  /* Maps statements to their lim_aux_data.  */
> >
> > -static struct pointer_map_t *lim_aux_data_map;
> > +static hash_map<gimple, lim_aux_data *> *lim_aux_data_map;
> >
> >  /* Description of a memory reference location.  */
> >
> > @@ -225,20 +226,20 @@ static bool ref_indep_loop_p (struct loop *, mem_ref_p);
> >  static struct lim_aux_data *
> >  init_lim_data (gimple stmt)
> >  {
> > -  void **p = pointer_map_insert (lim_aux_data_map, stmt);
> > +  lim_aux_data *p = XCNEW (struct lim_aux_data);
> > +  lim_aux_data_map->put (stmt, p);
> >
> > -  *p = XCNEW (struct lim_aux_data);
> > -  return (struct lim_aux_data *) *p;
> > +  return p;
> >  }
> >
> >  static struct lim_aux_data *
> >  get_lim_data (gimple stmt)
> >  {
> > -  void **p = pointer_map_contains (lim_aux_data_map, stmt);
> > +  lim_aux_data **p = lim_aux_data_map->get (stmt);
> >    if (!p)
> >      return NULL;
> >
> > -  return (struct lim_aux_data *) *p;
> > +  return *p;
> >  }
> >
> >  /* Releases the memory occupied by DATA.  */
> > @@ -253,11 +254,11 @@ free_lim_aux_data (struct lim_aux_data *data)
> >  static void
> >  clear_lim_data (gimple stmt)
> >  {
> > -  void **p = pointer_map_contains (lim_aux_data_map, stmt);
> > +  lim_aux_data **p = lim_aux_data_map->get (stmt);
> >    if (!p)
> >      return;
> >
> > -  free_lim_aux_data ((struct lim_aux_data *) *p);
> > +  free_lim_aux_data (*p);
> >    *p = NULL;
> >  }
> >
> > @@ -2429,7 +2430,7 @@ tree_ssa_lim_initialize (void)
> >
> >    bitmap_obstack_initialize (&lim_bitmap_obstack);
> >    gcc_obstack_init (&mem_ref_obstack);
> > -  lim_aux_data_map = pointer_map_create ();
> > +  lim_aux_data_map = new hash_map<gimple, lim_aux_data *>;
> >
> >    if (flag_tm)
> >      compute_transaction_bits ();
> > @@ -2484,7 +2485,7 @@ tree_ssa_lim_finalize (void)
> >      SET_ALWAYS_EXECUTED_IN (bb, NULL);
> >
> >    bitmap_obstack_release (&lim_bitmap_obstack);
> > -  pointer_map_destroy (lim_aux_data_map);
> > +  delete lim_aux_data_map;
> >
> >    delete memory_accesses.refs;
> >    memory_accesses.refs = NULL;
> > diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
> > index 3b4a6cd..158a081 100644
> > --- a/gcc/tree-ssa-loop-ivopts.c
> > +++ b/gcc/tree-ssa-loop-ivopts.c
> > @@ -70,7 +70,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "tm_p.h"
> >  #include "basic-block.h"
> >  #include "gimple-pretty-print.h"
> > -#include "pointer-set.h"
> > +#include "hash-map.h"
> >  #include "hash-table.h"
> >  #include "tree-ssa-alias.h"
> >  #include "internal-fn.h"
> > @@ -293,7 +293,7 @@ struct ivopts_data
> >    struct loop *current_loop;
> >
> >    /* Numbers of iterations for all exits of the current loop.  */
> > -  struct pointer_map_t *niters;
> > +  hash_map<edge, tree_niter_desc *> *niters;
> >
> >    /* Number of registers used in it.  */
> >    unsigned regs_used;
> > @@ -814,15 +814,15 @@ static struct tree_niter_desc *
> >  niter_for_exit (struct ivopts_data *data, edge exit)
> >  {
> >    struct tree_niter_desc *desc;
> > -  void **slot;
> > +  tree_niter_desc **slot;
> >
> >    if (!data->niters)
> >      {
> > -      data->niters = pointer_map_create ();
> > +      data->niters = new hash_map<edge, tree_niter_desc *>;
> >        slot = NULL;
> >      }
> >    else
> > -    slot = pointer_map_contains (data->niters, exit);
> > +    slot = data->niters->get (exit);
> >
> >    if (!slot)
> >      {
> > @@ -837,11 +837,10 @@ niter_for_exit (struct ivopts_data *data, edge exit)
> >           XDELETE (desc);
> >           desc = NULL;
> >         }
> > -      slot = pointer_map_insert (data->niters, exit);
> > -      *slot = desc;
> > +      data->niters->put (exit, desc);
> >      }
> >    else
> > -    desc = (struct tree_niter_desc *) *slot;
> > +    desc = *slot;
> >
> >    return desc;
> >  }
> > @@ -6704,15 +6703,12 @@ remove_unused_ivs (struct ivopts_data *data)
> >  }
> >
> >  /* Frees memory occupied by struct tree_niter_desc in *VALUE. Callback
> > -   for pointer_map_traverse.  */
> > +   for hash_map::traverse.  */
> >
> > -static bool
> > -free_tree_niter_desc (const void *key ATTRIBUTE_UNUSED, void **value,
> > -                      void *data ATTRIBUTE_UNUSED)
> > +bool
> > +free_tree_niter_desc (edge const &, tree_niter_desc *const &value, void *)
> >  {
> > -  struct tree_niter_desc *const niter = (struct tree_niter_desc *) *value;
> > -
> > -  free (niter);
> > +  free (value);
> >    return true;
> >  }
> >
> > @@ -6727,8 +6723,8 @@ free_loop_data (struct ivopts_data *data)
> >
> >    if (data->niters)
> >      {
> > -      pointer_map_traverse (data->niters, free_tree_niter_desc, NULL);
> > -      pointer_map_destroy (data->niters);
> > +      data->niters->traverse<void *, free_tree_niter_desc> (NULL);
> > +      delete data->niters;
> >        data->niters = NULL;
> >      }
> >
> > diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
> > index f9bd9a4..2e8337c 100644
> > --- a/gcc/tree-ssa-reassoc.c
> > +++ b/gcc/tree-ssa-reassoc.c
> > @@ -30,7 +30,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "basic-block.h"
> >  #include "gimple-pretty-print.h"
> >  #include "tree-inline.h"
> > -#include "pointer-set.h"
> > +#include "hash-map.h"
> >  #include "tree-ssa-alias.h"
> >  #include "internal-fn.h"
> >  #include "gimple-fold.h"
> > @@ -216,7 +216,7 @@ static int next_operand_entry_id;
> >  static long *bb_rank;
> >
> >  /* Operand->rank hashtable.  */
> > -static struct pointer_map_t *operand_rank;
> > +static hash_map<tree, long> *operand_rank;
> >
> >  /* Forward decls.  */
> >  static long get_rank (tree);
> > @@ -362,8 +362,8 @@ propagate_rank (long rank, tree op)
> >  static inline long
> >  find_operand_rank (tree e)
> >  {
> > -  void **slot = pointer_map_contains (operand_rank, e);
> > -  return slot ? (long) (intptr_t) *slot : -1;
> > +  long *slot = operand_rank->get (e);
> > +  return slot ? *slot : -1;
> >  }
> >
> >  /* Insert {E,RANK} into the operand rank hashtable.  */
> > @@ -371,11 +371,8 @@ find_operand_rank (tree e)
> >  static inline void
> >  insert_operand_rank (tree e, long rank)
> >  {
> > -  void **slot;
> >    gcc_assert (rank > 0);
> > -  slot = pointer_map_insert (operand_rank, e);
> > -  gcc_assert (!*slot);
> > -  *slot = (void *) (intptr_t) rank;
> > +  gcc_assert (!operand_rank->put (e, rank));
> >  }
> >
> >  /* Given an expression E, return the rank of the expression.  */
> > @@ -4635,7 +4632,7 @@ init_reassoc (void)
> >       deeper loops come later.  */
> >    pre_and_rev_post_order_compute (NULL, bbs, false);
> >    bb_rank = XCNEWVEC (long, last_basic_block_for_fn (cfun));
> > -  operand_rank = pointer_map_create ();
> > +  operand_rank = new hash_map<tree, long>;
> >
> >    /* Give each default definition a distinct rank.  This includes
> >       parameters and the static chain.  Walk backwards over all
> > @@ -4676,7 +4673,7 @@ fini_reassoc (void)
> >    statistics_counter_event (cfun, "Built-in powi calls created",
> >                             reassociate_stats.pows_created);
> >
> > -  pointer_map_destroy (operand_rank);
> > +  delete operand_rank;
> >    free_alloc_pool (operand_entry_pool);
> >    free (bb_rank);
> >    plus_negates.release ();
> > diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
> > index 1879fc0..08e384b 100644
> > --- a/gcc/tree-ssa-structalias.c
> > +++ b/gcc/tree-ssa-structalias.c
> > @@ -319,7 +319,7 @@ static inline bool type_can_have_subvars (const_tree);
> >  static alloc_pool variable_info_pool;
> >
> >  /* Map varinfo to final pt_solution.  */
> > -static pointer_map_t *final_solutions;
> > +static hash_map<varinfo_t, pt_solution *> *final_solutions;
> >  struct obstack final_solutions_obstack;
> >
> >  /* Table of variable info structures for constraint variables.
> > @@ -393,19 +393,19 @@ new_var_info (tree t, const char *name)
> >
> >  /* A map mapping call statements to per-stmt variables for uses
> >     and clobbers specific to the call.  */
> > -static struct pointer_map_t *call_stmt_vars;
> > +static hash_map<gimple, varinfo_t> *call_stmt_vars;
> >
> >  /* Lookup or create the variable for the call statement CALL.  */
> >
> >  static varinfo_t
> >  get_call_vi (gimple call)
> >  {
> > -  void **slot_p;
> >    varinfo_t vi, vi2;
> >
> > -  slot_p = pointer_map_insert (call_stmt_vars, call);
> > -  if (*slot_p)
> > -    return (varinfo_t) *slot_p;
> > +  bool existed;
> > +  varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
> > +  if (existed)
> > +    return *slot_p;
> >
> >    vi = new_var_info (NULL_TREE, "CALLUSED");
> >    vi->offset = 0;
> > @@ -421,7 +421,7 @@ get_call_vi (gimple call)
> >
> >    vi->next = vi2->id;
> >
> > -  *slot_p = (void *) vi;
> > +  *slot_p = vi;
> >    return vi;
> >  }
> >
> > @@ -431,11 +431,9 @@ get_call_vi (gimple call)
> >  static varinfo_t
> >  lookup_call_use_vi (gimple call)
> >  {
> > -  void **slot_p;
> > -
> > -  slot_p = pointer_map_contains (call_stmt_vars, call);
> > +  varinfo_t *slot_p = call_stmt_vars->get (call);
> >    if (slot_p)
> > -    return (varinfo_t) *slot_p;
> > +    return *slot_p;
> >
> >    return NULL;
> >  }
> > @@ -2794,7 +2792,7 @@ solve_graph (constraint_graph_t graph)
> >  }
> >
> >  /* Map from trees to variable infos.  */
> > -static struct pointer_map_t *vi_for_tree;
> > +static hash_map<tree, varinfo_t> *vi_for_tree;
> >
> >
> >  /* Insert ID as the variable id for tree T in the vi_for_tree map.  */
> > @@ -2802,10 +2800,8 @@ static struct pointer_map_t *vi_for_tree;
> >  static void
> >  insert_vi_for_tree (tree t, varinfo_t vi)
> >  {
> > -  void **slot = pointer_map_insert (vi_for_tree, t);
> >    gcc_assert (vi);
> > -  gcc_assert (*slot == NULL);
> > -  *slot = vi;
> > +  gcc_assert (!vi_for_tree->put (t, vi));
> >  }
> >
> >  /* Find the variable info for tree T in VI_FOR_TREE.  If T does not
> > @@ -2814,11 +2810,11 @@ insert_vi_for_tree (tree t, varinfo_t vi)
> >  static varinfo_t
> >  lookup_vi_for_tree (tree t)
> >  {
> > -  void **slot = pointer_map_contains (vi_for_tree, t);
> > +  varinfo_t *slot = vi_for_tree->get (t);
> >    if (slot == NULL)
> >      return NULL;
> >
> > -  return (varinfo_t) *slot;
> > +  return *slot;
> >  }
> >
> >  /* Return a printable name for DECL  */
> > @@ -2876,11 +2872,11 @@ alias_get_name (tree decl)
> >  static varinfo_t
> >  get_vi_for_tree (tree t)
> >  {
> > -  void **slot = pointer_map_contains (vi_for_tree, t);
> > +  varinfo_t *slot = vi_for_tree->get (t);
> >    if (slot == NULL)
> >      return get_varinfo (create_variable_info_for (t, alias_get_name (t)));
> >
> > -  return (varinfo_t) *slot;
> > +  return *slot;
> >  }
> >
> >  /* Get a scalar constraint expression for a new temporary variable.  */
> > @@ -6075,7 +6071,6 @@ find_what_var_points_to (varinfo_t orig_vi)
> >    bitmap finished_solution;
> >    bitmap result;
> >    varinfo_t vi;
> > -  void **slot;
> >    struct pt_solution *pt;
> >
> >    /* This variable may have been collapsed, let's get the real
> > @@ -6083,9 +6078,9 @@ find_what_var_points_to (varinfo_t orig_vi)
> >    vi = get_varinfo (find (orig_vi->id));
> >
> >    /* See if we have already computed the solution and return it.  */
> > -  slot = pointer_map_insert (final_solutions, vi);
> > +  pt_solution **slot = &final_solutions->get_or_insert (vi);
> >    if (*slot != NULL)
> > -    return *(struct pt_solution *)*slot;
> > +    return **slot;
> >
> >    *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution);
> >    memset (pt, 0, sizeof (struct pt_solution));
> > @@ -6685,8 +6680,8 @@ init_alias_vars (void)
> >                                           sizeof (struct variable_info), 30);
> >    constraints.create (8);
> >    varmap.create (8);
> > -  vi_for_tree = pointer_map_create ();
> > -  call_stmt_vars = pointer_map_create ();
> > +  vi_for_tree = new hash_map<tree, varinfo_t>;
> > +  call_stmt_vars = new hash_map<gimple, varinfo_t>;
> >
> >    memset (&stats, 0, sizeof (stats));
> >    shared_bitmap_table = new hash_table<shared_bitmap_hasher> (511);
> > @@ -6694,7 +6689,7 @@ init_alias_vars (void)
> >
> >    gcc_obstack_init (&fake_var_decl_obstack);
> >
> > -  final_solutions = pointer_map_create ();
> > +  final_solutions = new hash_map<varinfo_t, pt_solution *>;
> >    gcc_obstack_init (&final_solutions_obstack);
> >  }
> >
> > @@ -6943,8 +6938,8 @@ delete_points_to_sets (void)
> >      fprintf (dump_file, "Points to sets created:%d\n",
> >              stats.points_to_sets_created);
> >
> > -  pointer_map_destroy (vi_for_tree);
> > -  pointer_map_destroy (call_stmt_vars);
> > +  delete vi_for_tree;
> > +  delete call_stmt_vars;
> >    bitmap_obstack_release (&pta_obstack);
> >    constraints.release ();
> >
> > @@ -6965,7 +6960,7 @@ delete_points_to_sets (void)
> >
> >    obstack_free (&fake_var_decl_obstack, NULL);
> >
> > -  pointer_map_destroy (final_solutions);
> > +  delete final_solutions;
> >    obstack_free (&final_solutions_obstack, NULL);
> >  }
> >
> > diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
> > index 73a4d1c..217b9fc 100644
> > --- a/gcc/tree-ssa.c
> > +++ b/gcc/tree-ssa.c
> > @@ -49,6 +49,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "tree-into-ssa.h"
> >  #include "tree-ssa.h"
> >  #include "tree-inline.h"
> > +#include "hash-map.h"
> >  #include "hashtab.h"
> >  #include "tree-pass.h"
> >  #include "diagnostic-core.h"
> > @@ -56,7 +57,7 @@ along with GCC; see the file COPYING3.  If not see
> >  #include "cfgexpand.h"
> >
> >  /* Pointer map of variable mappings, keyed by edge.  */
> > -static struct pointer_map_t *edge_var_maps;
> > +static hash_map<edge, auto_vec<edge_var_map> > *edge_var_maps;
> >
> >
> >  /* Add a mapping with PHI RESULT and PHI DEF associated with edge E.  */
> > @@ -64,23 +65,17 @@ static struct pointer_map_t *edge_var_maps;
> >  void
> >  redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
> >  {
> > -  void **slot;
> > -  edge_var_map_vector *head;
> >    edge_var_map new_node;
> >
> >    if (edge_var_maps == NULL)
> > -    edge_var_maps = pointer_map_create ();
> > +    edge_var_maps = new hash_map<edge, auto_vec<edge_var_map> >;
> >
> > -  slot = pointer_map_insert (edge_var_maps, e);
> > -  head = (edge_var_map_vector *) *slot;
> > -  if (!head)
> > -    vec_safe_reserve (head, 5);
> > +  auto_vec<edge_var_map> &slot = edge_var_maps->get_or_insert (e);
> >    new_node.def = def;
> >    new_node.result = result;
> >    new_node.locus = locus;
> >
> > -  vec_safe_push (head, new_node);
> > -  *slot = head;
> > +  slot.safe_push (new_node);
> >  }
> >
> >
> > @@ -89,82 +84,51 @@ redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
> >  void
> >  redirect_edge_var_map_clear (edge e)
> >  {
> > -  void **slot;
> > -  edge_var_map_vector *head;
> > -
> >    if (!edge_var_maps)
> >      return;
> >
> > -  slot = pointer_map_contains (edge_var_maps, e);
> > +  auto_vec<edge_var_map> *head = edge_var_maps->get (e);
> >
> > -  if (slot)
> > -    {
> > -      head = (edge_var_map_vector *) *slot;
> > -      vec_free (head);
> > -      *slot = NULL;
> > -    }
> > +  if (head)
> > +    head->release ();
> >  }
> >
> >
> >  /* Duplicate the redirected var mappings in OLDE in NEWE.
> >
> > -   Since we can't remove a mapping, let's just duplicate it.  This assumes a
> > -   pointer_map can have multiple edges mapping to the same var_map (many to
> > -   one mapping), since we don't remove the previous mappings.  */
> > +   This assumes a hash_map can have multiple edges mapping to the same
> > +   var_map (many to one mapping), since we don't remove the previous mappings.
> > +   */
> >
> >  void
> >  redirect_edge_var_map_dup (edge newe, edge olde)
> >  {
> > -  void **new_slot, **old_slot;
> > -  edge_var_map_vector *head;
> > -
> >    if (!edge_var_maps)
> >      return;
> >
> > -  new_slot = pointer_map_insert (edge_var_maps, newe);
> > -  old_slot = pointer_map_contains (edge_var_maps, olde);
> > -  if (!old_slot)
> > +  auto_vec<edge_var_map> *head = edge_var_maps->get (olde);
> > +  if (!head)
> >      return;
> > -  head = (edge_var_map_vector *) *old_slot;
> >
> > -  edge_var_map_vector *new_head = NULL;
> > -  if (head)
> > -    new_head = vec_safe_copy (head);
> > -  else
> > -    vec_safe_reserve (new_head, 5);
> > -  *new_slot = new_head;
> > +  edge_var_maps->get_or_insert (newe).safe_splice (*head);
> >  }
> >
> >
> >  /* Return the variable mappings for a given edge.  If there is none, return
> >     NULL.  */
> >
> > -edge_var_map_vector *
> > +vec<edge_var_map> *
> >  redirect_edge_var_map_vector (edge e)
> >  {
> > -  void **slot;
> > -
> >    /* Hey, what kind of idiot would... you'd be surprised.  */
> >    if (!edge_var_maps)
> >      return NULL;
> >
> > -  slot = pointer_map_contains (edge_var_maps, e);
> > +  auto_vec<edge_var_map> *slot = edge_var_maps->get (e);
> >    if (!slot)
> >      return NULL;
> >
> > -  return (edge_var_map_vector *) *slot;
> > -}
> > -
> > -/* Used by redirect_edge_var_map_destroy to free all memory.  */
> > -
> > -static bool
> > -free_var_map_entry (const void *key ATTRIBUTE_UNUSED,
> > -                   void **value,
> > -                   void *data ATTRIBUTE_UNUSED)
> > -{
> > -  edge_var_map_vector *head = (edge_var_map_vector *) *value;
> > -  vec_free (head);
> > -  return true;
> > +  return slot;
> >  }
> >
> >  /* Clear the edge variable mappings.  */
> > @@ -172,12 +136,8 @@ free_var_map_entry (const void *key ATTRIBUTE_UNUSED,
> >  void
> >  redirect_edge_var_map_destroy (void)
> >  {
> > -  if (edge_var_maps)
> > -    {
> > -      pointer_map_traverse (edge_var_maps, free_var_map_entry, NULL);
> > -      pointer_map_destroy (edge_var_maps);
> > -      edge_var_maps = NULL;
> > -    }
> > +  delete edge_var_maps;
> > +  edge_var_maps = NULL;
> >  }
> >
> >
> > @@ -223,12 +183,11 @@ void
> >  flush_pending_stmts (edge e)
> >  {
> >    gimple phi;
> > -  edge_var_map_vector *v;
> >    edge_var_map *vm;
> >    int i;
> >    gimple_stmt_iterator gsi;
> >
> > -  v = redirect_edge_var_map_vector (e);
> > +  vec<edge_var_map> *v = redirect_edge_var_map_vector (e);
> >    if (!v)
> >      return;
> >
> > diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h
> > index c866206..835686c 100644
> > --- a/gcc/tree-ssa.h
> > +++ b/gcc/tree-ssa.h
> > @@ -35,7 +35,7 @@ typedef vec<edge_var_map, va_heap, vl_embed> edge_var_map_vector;
> >  extern void redirect_edge_var_map_add (edge, tree, tree, source_location);
> >  extern void redirect_edge_var_map_clear (edge);
> >  extern void redirect_edge_var_map_dup (edge, edge);
> > -extern edge_var_map_vector *redirect_edge_var_map_vector (edge);
> > +extern vec<edge_var_map> *redirect_edge_var_map_vector (edge);
> >  extern void redirect_edge_var_map_destroy (void);
> >  extern edge ssa_redirect_edge (edge, basic_block);
> >  extern void flush_pending_stmts (edge);
> > diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
> > index 00810b9..3b72fce 100644
> > --- a/gcc/var-tracking.c
> > +++ b/gcc/var-tracking.c
> > @@ -94,6 +94,7 @@
> >  #include "varasm.h"
> >  #include "stor-layout.h"
> >  #include "pointer-set.h"
> > +#include "hash-map.h"
> >  #include "hash-table.h"
> >  #include "basic-block.h"
> >  #include "tm_p.h"
> > @@ -2019,12 +2020,12 @@ vt_get_canonicalize_base (rtx loc)
> >
> >  /* This caches canonicalized addresses for VALUEs, computed using
> >     information in the global cselib table.  */
> > -static struct pointer_map_t *global_get_addr_cache;
> > +static hash_map<rtx, rtx> *global_get_addr_cache;
> >
> >  /* This caches canonicalized addresses for VALUEs, computed using
> >     information from the global cache and information pertaining to a
> >     basic block being analyzed.  */
> > -static struct pointer_map_t *local_get_addr_cache;
> > +static hash_map<rtx, rtx> *local_get_addr_cache;
> >
> >  static rtx vt_canonicalize_addr (dataflow_set *, rtx);
> >
> > @@ -2036,13 +2037,13 @@ static rtx
> >  get_addr_from_global_cache (rtx const loc)
> >  {
> >    rtx x;
> > -  void **slot;
> >
> >    gcc_checking_assert (GET_CODE (loc) == VALUE);
> >
> > -  slot = pointer_map_insert (global_get_addr_cache, loc);
> > -  if (*slot)
> > -    return (rtx)*slot;
> > +  bool existed;
> > +  rtx *slot = &global_get_addr_cache->get_or_insert (loc, &existed);
> > +  if (existed)
> > +    return *slot;
> >
> >    x = canon_rtx (get_addr (loc));
> >
> > @@ -2056,8 +2057,7 @@ get_addr_from_global_cache (rtx const loc)
> >         {
> >           /* The table may have moved during recursion, recompute
> >              SLOT.  */
> > -         slot = pointer_map_contains (global_get_addr_cache, loc);
> > -         *slot = x = nx;
> > +         *global_get_addr_cache->get (loc) = x = nx;
> >         }
> >      }
> >
> > @@ -2072,16 +2072,16 @@ static rtx
> >  get_addr_from_local_cache (dataflow_set *set, rtx const loc)
> >  {
> >    rtx x;
> > -  void **slot;
> >    decl_or_value dv;
> >    variable var;
> >    location_chain l;
> >
> >    gcc_checking_assert (GET_CODE (loc) == VALUE);
> >
> > -  slot = pointer_map_insert (local_get_addr_cache, loc);
> > -  if (*slot)
> > -    return (rtx)*slot;
> > +  bool existed;
> > +  rtx *slot = &local_get_addr_cache->get_or_insert (loc, &existed);
> > +  if (existed)
> > +    return *slot;
> >
> >    x = get_addr_from_global_cache (loc);
> >
> > @@ -2095,7 +2095,7 @@ get_addr_from_local_cache (dataflow_set *set, rtx const loc)
> >        rtx nx = vt_canonicalize_addr (set, x);
> >        if (nx != x)
> >         {
> > -         slot = pointer_map_contains (local_get_addr_cache, loc);
> > +         slot = local_get_addr_cache->get (loc);
> >           *slot = x = nx;
> >         }
> >        return x;
> > @@ -2116,7 +2116,7 @@ get_addr_from_local_cache (dataflow_set *set, rtx const loc)
> >           rtx nx = vt_canonicalize_addr (set, l->loc);
> >           if (x != nx)
> >             {
> > -             slot = pointer_map_contains (local_get_addr_cache, loc);
> > +             slot = local_get_addr_cache->get (loc);
> >               *slot = x = nx;
> >             }
> >           break;
> > @@ -2503,11 +2503,10 @@ val_store (dataflow_set *set, rtx val, rtx loc, rtx insn, bool modified)
> >
> >  /* Clear (canonical address) slots that reference X.  */
> >
> > -static bool
> > -local_get_addr_clear_given_value (const void *v ATTRIBUTE_UNUSED,
> > -                                 void **slot, void *x)
> > +bool
> > +local_get_addr_clear_given_value (rtx const &, rtx *slot, rtx x)
> >  {
> > -  if (vt_get_canonicalize_base ((rtx)*slot) == x)
> > +  if (vt_get_canonicalize_base (*slot) == x)
> >      *slot = NULL;
> >    return true;
> >  }
> > @@ -2530,11 +2529,10 @@ val_reset (dataflow_set *set, decl_or_value dv)
> >    if (var->onepart == ONEPART_VALUE)
> >      {
> >        rtx x = dv_as_value (dv);
> > -      void **slot;
> >
> >        /* Relationships in the global cache don't change, so reset the
> >          local cache entry only.  */
> > -      slot = pointer_map_contains (local_get_addr_cache, x);
> > +      rtx *slot = local_get_addr_cache->get (x);
> >        if (slot)
> >         {
> >           /* If the value resolved back to itself, odds are that other
> > @@ -2543,8 +2541,8 @@ val_reset (dataflow_set *set, decl_or_value dv)
> >              old X but resolved to something else remain ok as long as
> >              that something else isn't also reset.  */
> >           if (*slot == x)
> > -           pointer_map_traverse (local_get_addr_cache,
> > -                                 local_get_addr_clear_given_value, x);
> > +           local_get_addr_cache
> > +             ->traverse<rtx, local_get_addr_clear_given_value> (x);
> >           *slot = NULL;
> >         }
> >      }
> > @@ -6660,7 +6658,7 @@ compute_bb_dataflow (basic_block bb)
> >    dataflow_set_copy (out, in);
> >
> >    if (MAY_HAVE_DEBUG_INSNS)
> > -    local_get_addr_cache = pointer_map_create ();
> > +    local_get_addr_cache = new hash_map<rtx, rtx>;
> >
> >    FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
> >      {
> > @@ -6943,7 +6941,7 @@ compute_bb_dataflow (basic_block bb)
> >
> >    if (MAY_HAVE_DEBUG_INSNS)
> >      {
> > -      pointer_map_destroy (local_get_addr_cache);
> > +      delete local_get_addr_cache;
> >        local_get_addr_cache = NULL;
> >
> >        dataflow_set_equiv_regs (out);
> > @@ -9477,13 +9475,13 @@ vt_emit_notes (void)
> >        emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
> >
> >        if (MAY_HAVE_DEBUG_INSNS)
> > -       local_get_addr_cache = pointer_map_create ();
> > +       local_get_addr_cache = new hash_map<rtx, rtx>;
> >
> >        /* Emit the notes for the changes in the basic block itself.  */
> >        emit_notes_in_bb (bb, &cur);
> >
> >        if (MAY_HAVE_DEBUG_INSNS)
> > -       pointer_map_destroy (local_get_addr_cache);
> > +       delete local_get_addr_cache;
> >        local_get_addr_cache = NULL;
> >
> >        /* Free memory occupied by the in hash table, we won't need it
> > @@ -9916,7 +9914,7 @@ vt_initialize (void)
> >        valvar_pool = create_alloc_pool ("small variable_def pool",
> >                                        sizeof (struct variable_def), 256);
> >        preserved_values.create (256);
> > -      global_get_addr_cache = pointer_map_create ();
> > +      global_get_addr_cache = new hash_map<rtx, rtx>;
> >      }
> >    else
> >      {
> > @@ -10263,7 +10261,7 @@ vt_finalize (void)
> >    if (MAY_HAVE_DEBUG_INSNS)
> >      {
> >        if (global_get_addr_cache)
> > -       pointer_map_destroy (global_get_addr_cache);
> > +       delete global_get_addr_cache;
> >        global_get_addr_cache = NULL;
> >        if (loc_exp_dep_pool)
> >         free_alloc_pool (loc_exp_dep_pool);
> > --
> > 2.0.1
> >
Oleg Endo Aug. 2, 2014, 3:38 p.m. UTC | #3
On Sat, 2014-08-02 at 07:34 -0400, Trevor Saunders wrote:
> On Fri, Aug 01, 2014 at 12:52:08PM +0200, Richard Biener wrote:
> > On Fri, Aug 1, 2014 at 12:34 PM,  <tsaunders@mozilla.com> wrote:
> > > From: Trevor Saunders <tsaunders@mozilla.com>
> > >
> > > Hi,
> > >
> > > This patch replaces a bunch of usage of pointer_map with hash_map.  It also
> > > adds an overload to hash_map::traverse that allows modifying the value, and a
> > > remove method.
> > >
> > > bootstrapped + regtested on x86_64-unknown-linux-gnu, ok?
> > 
> > Ok.
> 
> committed as r213517 thanks for the review.
> 
> Trev
> 

Either r213517 or r213516 is causing the following on my sh-elf setup
(i686 host) when doing 'make all':

libtool: compile:  /home/user/code/gcc/gcc-trunk-build-sh-elf/./gcc/xgcc
-shared-libgcc -B/home/user/code/gcc/gcc-trunk-build-sh-elf/./gcc
-nostdinc++ -L/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc
++-v3/src -L/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc
++-v3/src/.libs
-L/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc++-v3/libsupc
++/.libs -B/usr/local/sh-elf/bin/ -B/usr/local/sh-elf/lib/
-isystem /usr/local/sh-elf/include
-isystem /usr/local/sh-elf/sys-include
-I/home/user/code/gcc/gcc-trunk/libstdc++-v3/../libgcc
-I/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc
++-v3/include/sh-elf
-I/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc++-v3/include
-I/home/user/code/gcc/gcc-trunk/libstdc++-v3/libsupc++ -std=gnu++11
-fno-implicit-templates -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi
-fdiagnostics-show-location=once -ffunction-sections -fdata-sections
-frandom-seed=fstream-inst.lo -g -O2 -c ../../../../../gcc-trunk/libstdc
++-v3/src/c++11/fstream-inst.cc -o fstream-inst.o

cc1plus: out of memory allocating 2129023400 bytes after a total of
1589248 bytes
make[5]: *** [fstream-inst.lo] Error 1
make[5]: Leaving directory
`/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc++-v3/src/c
++11'

Cheers,
Oleg
Trevor Saunders Aug. 2, 2014, 3:58 p.m. UTC | #4
On Sat, Aug 02, 2014 at 05:38:42PM +0200, Oleg Endo wrote:
> On Sat, 2014-08-02 at 07:34 -0400, Trevor Saunders wrote:
> > On Fri, Aug 01, 2014 at 12:52:08PM +0200, Richard Biener wrote:
> > > On Fri, Aug 1, 2014 at 12:34 PM,  <tsaunders@mozilla.com> wrote:
> > > > From: Trevor Saunders <tsaunders@mozilla.com>
> > > >
> > > > Hi,
> > > >
> > > > This patch replaces a bunch of usage of pointer_map with hash_map.  It also
> > > > adds an overload to hash_map::traverse that allows modifying the value, and a
> > > > remove method.
> > > >
> > > > bootstrapped + regtested on x86_64-unknown-linux-gnu, ok?
> > > 
> > > Ok.
> > 
> > committed as r213517 thanks for the review.
> > 
> > Trev
> > 
> 
> Either r213517 or r213516 is causing the following on my sh-elf setup
> (i686 host) when doing 'make all':

I'd guess that its r213517, and for  at least one of the hash maps we're
leaking what the entries point at.  Can you try compiling that file
under valgrind? if not I can try in a couple hours.

Trev

> 
> libtool: compile:  /home/user/code/gcc/gcc-trunk-build-sh-elf/./gcc/xgcc
> -shared-libgcc -B/home/user/code/gcc/gcc-trunk-build-sh-elf/./gcc
> -nostdinc++ -L/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc
> ++-v3/src -L/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc
> ++-v3/src/.libs
> -L/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc++-v3/libsupc
> ++/.libs -B/usr/local/sh-elf/bin/ -B/usr/local/sh-elf/lib/
> -isystem /usr/local/sh-elf/include
> -isystem /usr/local/sh-elf/sys-include
> -I/home/user/code/gcc/gcc-trunk/libstdc++-v3/../libgcc
> -I/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc
> ++-v3/include/sh-elf
> -I/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc++-v3/include
> -I/home/user/code/gcc/gcc-trunk/libstdc++-v3/libsupc++ -std=gnu++11
> -fno-implicit-templates -Wall -Wextra -Wwrite-strings -Wcast-qual -Wabi
> -fdiagnostics-show-location=once -ffunction-sections -fdata-sections
> -frandom-seed=fstream-inst.lo -g -O2 -c ../../../../../gcc-trunk/libstdc
> ++-v3/src/c++11/fstream-inst.cc -o fstream-inst.o
> 
> cc1plus: out of memory allocating 2129023400 bytes after a total of
> 1589248 bytes
> make[5]: *** [fstream-inst.lo] Error 1
> make[5]: Leaving directory
> `/home/user/code/gcc/gcc-trunk-build-sh-elf/sh-elf/libstdc++-v3/src/c
> ++11'
> 
> Cheers,
> Oleg
>
Oleg Endo Aug. 2, 2014, 5 p.m. UTC | #5
On 02 Aug 2014, at 17:58, Trevor Saunders <tsaunders@mozilla.com> wrote:

> On Sat, Aug 02, 2014 at 05:38:42PM +0200, Oleg Endo wrote:
>> On Sat, 2014-08-02 at 07:34 -0400, Trevor Saunders wrote:
>>> On Fri, Aug 01, 2014 at 12:52:08PM +0200, Richard Biener wrote:
>>>> On Fri, Aug 1, 2014 at 12:34 PM,  <tsaunders@mozilla.com> wrote:
>>>>> From: Trevor Saunders <tsaunders@mozilla.com>
>>>>> 
>>>>> Hi,
>>>>> 
>>>>> This patch replaces a bunch of usage of pointer_map with hash_map.  It also
>>>>> adds an overload to hash_map::traverse that allows modifying the value, and a
>>>>> remove method.
>>>>> 
>>>>> bootstrapped + regtested on x86_64-unknown-linux-gnu, ok?
>>>> 
>>>> Ok.
>>> 
>>> committed as r213517 thanks for the review.
>>> 
>>> Trev
>>> 
>> 
>> Either r213517 or r213516 is causing the following on my sh-elf setup
>> (i686 host) when doing 'make all':
> 
> I'd guess that its r213517, and for  at least one of the hash maps we're
> leaking what the entries point at.  Can you try compiling that file
> under valgrind? if not I can try in a couple hours.

I think you'll be faster than me.

Cheers,
Oleg
diff mbox

Patch

diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index b864bb1..e0d1141 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -64,7 +64,7 @@  struct wrapper_data
   /* Containing function.  */
   tree context;
   /* Disposition of all variables in the inner statement.  */
-  struct pointer_map_t *decl_map;
+  hash_map<tree, tree> *decl_map;
   /* True if this function needs a static chain.  */
   bool nested;
   /* Arguments to be passed to wrapper function, currently a list.  */
@@ -335,12 +335,11 @@  create_cilk_helper_decl (struct wrapper_data *wd)
 
 /* A function used by walk tree to find wrapper parms.  */
 
-static bool
-wrapper_parm_cb (const void *key0, void **val0, void *data)
+bool
+wrapper_parm_cb (tree const &key0, tree *val0, wrapper_data *wd)
 {
-  struct wrapper_data *wd = (struct wrapper_data *) data;
-  tree arg = * (tree *)&key0;
-  tree val = (tree)*val0;
+  tree arg = key0;
+  tree val = *val0;
   tree parm;
 
   if (val == error_mark_node || val == arg)
@@ -387,7 +386,7 @@  build_wrapper_type (struct wrapper_data *wd)
   wd->parms = NULL_TREE;
   wd->argtypes = void_list_node;
 
-  pointer_map_traverse (wd->decl_map, wrapper_parm_cb, wd);
+  wd->decl_map->traverse<wrapper_data *, wrapper_parm_cb> (wd);
   gcc_assert (wd->type != CILK_BLOCK_FOR);
 
   /* Now build a function.
@@ -452,25 +451,22 @@  copy_decl_for_cilk (tree decl, copy_body_data *id)
 
 /* Copy all local variables.  */
 
-static bool
-for_local_cb (const void *k_v, void **vp, void *p)
+bool
+for_local_cb (tree const &k, tree *vp, copy_body_data *id)
 {
-  tree k = *(tree *) &k_v;
-  tree v = (tree) *vp;
+  tree v = *vp;
 
   if (v == error_mark_node)
-    *vp = copy_decl_no_change (k, (copy_body_data *) p);
+    *vp = copy_decl_no_change (k, id);
   return true;
 }
 
 /* Copy all local declarations from a _Cilk_spawned function's body.  */
 
-static bool
-wrapper_local_cb (const void *k_v, void **vp, void *data)
+bool
+wrapper_local_cb (tree const &key, tree *vp, copy_body_data *id)
 {
-  copy_body_data *id = (copy_body_data *) data;
-  tree key = *(tree *) &k_v;
-  tree val = (tree) *vp;
+  tree val = *vp;
 
   if (val == error_mark_node)
     *vp = copy_decl_for_cilk (key, id);
@@ -514,8 +510,11 @@  cilk_outline (tree inner_fn, tree *stmt_p, void *w)
   insert_decl_map (&id, wd->block, DECL_INITIAL (inner_fn));
 
   /* We don't want the private variables any more.  */
-  pointer_map_traverse (wd->decl_map, nested ? for_local_cb : wrapper_local_cb,
-			&id);
+  if (nested)
+    wd->decl_map->traverse<copy_body_data *, for_local_cb> (&id);
+  else
+    wd->decl_map->traverse<copy_body_data *, wrapper_local_cb> (&id);
+
   walk_tree (stmt_p, copy_tree_body_r, (void *) &id, NULL);
 
   /* See if this function can throw or calls something that should
@@ -576,7 +575,7 @@  init_wd (struct wrapper_data *wd, enum cilk_block_type type)
   wd->type = type;
   wd->fntype = NULL_TREE;
   wd->context = current_function_decl;
-  wd->decl_map = pointer_map_create ();
+  wd->decl_map = new hash_map<tree, tree>;
   /* _Cilk_for bodies are always nested.  Others start off as 
      normal functions.  */
   wd->nested = (type == CILK_BLOCK_FOR);
@@ -590,7 +589,7 @@  init_wd (struct wrapper_data *wd, enum cilk_block_type type)
 static void
 free_wd (struct wrapper_data *wd)
 {
-  pointer_map_destroy (wd->decl_map);
+  delete wd->decl_map;
   wd->nested = false;
   wd->arglist = NULL_TREE;
   wd->argtypes = NULL_TREE;
@@ -618,12 +617,11 @@  free_wd (struct wrapper_data *wd)
    (var, ???) -- Pure output argument, handled similarly to above.
 */
 
-static bool
-declare_one_free_variable (const void *var0, void **map0,
-			   void *data ATTRIBUTE_UNUSED)
+bool
+declare_one_free_variable (tree const &var0, tree *map0, wrapper_data &)
 {
-  const_tree var = (const_tree) var0;
-  tree map = (tree)*map0;
+  const_tree var = var0;
+  tree map = *map0;
   tree var_type = TREE_TYPE (var), arg_type;
   bool by_reference;
   tree parm;
@@ -713,7 +711,7 @@  create_cilk_wrapper (tree exp, tree *args_out)
     }
   else
     extract_free_variables (exp, &wd, ADD_READ);
-  pointer_map_traverse (wd.decl_map, declare_one_free_variable, &wd);
+  wd.decl_map->traverse<wrapper_data &, declare_one_free_variable> (wd);
   wd.block = TREE_BLOCK (exp);
   if (!wd.block)
     wd.block = DECL_INITIAL (current_function_decl);
@@ -884,9 +882,7 @@  cilk_install_body_pedigree_operations (tree frame_ptr)
 static void
 add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
 {
-  void **valp;
-  
-  valp = pointer_map_contains (wd->decl_map, (void *) var);
+  tree *valp = wd->decl_map->get (var);
   if (valp)
     {
       tree val = (tree) *valp;
@@ -907,7 +903,7 @@  add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
       if (how != ADD_WRITE)
 	return;
       /* This variable might have been entered as read but is now written.  */
-      *valp = (void *) var;
+      *valp = var;
       wd->nested = true;
       return;
     }
@@ -971,7 +967,7 @@  add_variable (struct wrapper_data *wd, tree var, enum add_variable_type how)
 	      break;
 	    }
 	}
-      *pointer_map_insert (wd->decl_map, (void *) var) = val;
+      wd->decl_map->put (var, val);
     }
 }
 
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 06fd565..bedb63e 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -11783,15 +11783,15 @@  c_clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
 		 tree decl, tree placeholder)
 {
   copy_body_data id;
-  struct pointer_map_t *decl_map = pointer_map_create ();
+  hash_map<tree, tree> decl_map;
 
-  *pointer_map_insert (decl_map, omp_decl1) = placeholder;
-  *pointer_map_insert (decl_map, omp_decl2) = decl;
+  decl_map.put (omp_decl1, placeholder);
+  decl_map.put (omp_decl2, decl);
   memset (&id, 0, sizeof (id));
   id.src_fn = DECL_CONTEXT (omp_decl1);
   id.dst_fn = current_function_decl;
   id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
-  id.decl_map = decl_map;
+  id.decl_map = &decl_map;
 
   id.copy_decl = copy_decl_no_change;
   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
@@ -11800,7 +11800,6 @@  c_clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
   id.transform_lang_insert_block = NULL;
   id.eh_lp_nr = 0;
   walk_tree (&stmt, copy_tree_body_r, &id, NULL);
-  pointer_map_destroy (decl_map);
   return stmt;
 }
 
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index f8f76c4..0fa8635 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -21,6 +21,7 @@  along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_CGRAPH_H
 #define GCC_CGRAPH_H
 
+#include "hash-map.h"
 #include "is-a.h"
 #include "plugin-api.h"
 #include "vec.h"
@@ -1204,7 +1205,7 @@  public:
    can appear in multiple sets.  */
 struct cgraph_node_set_def
 {
-  struct pointer_map_t *map;
+  hash_map<cgraph_node *, size_t> *map;
   vec<cgraph_node *> nodes;
 };
 
@@ -1217,7 +1218,7 @@  class varpool_node;
    can appear in multiple sets.  */
 struct varpool_node_set_def
 {
-  struct pointer_map_t * map;
+  hash_map<varpool_node *, size_t> * map;
   vec<varpool_node *> nodes;
 };
 
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index 3cd8047..6eeca4d 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -86,7 +86,7 @@  clone_body (tree clone, tree fn, void *arg_map)
   id.src_fn = fn;
   id.dst_fn = clone;
   id.src_cfun = DECL_STRUCT_FUNCTION (fn);
-  id.decl_map = (struct pointer_map_t *) arg_map;
+  id.decl_map = static_cast<hash_map<tree, tree> *> (arg_map);
 
   id.copy_decl = copy_decl_no_change;
   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
@@ -527,7 +527,7 @@  maybe_clone_body (tree fn)
       tree parm;
       tree clone_parm;
       int parmno;
-      struct pointer_map_t *decl_map;
+      hash_map<tree, tree> *decl_map;
       bool alias = false;
 
       clone = fns[idx];
@@ -587,7 +587,7 @@  maybe_clone_body (tree fn)
 	    }
 
           /* Remap the parameters.  */
-          decl_map = pointer_map_create ();
+          decl_map = new hash_map<tree, tree>;
           for (parmno = 0,
                 parm = DECL_ARGUMENTS (fn),
                 clone_parm = DECL_ARGUMENTS (clone);
@@ -600,7 +600,7 @@  maybe_clone_body (tree fn)
                 {
                   tree in_charge;
                   in_charge = in_charge_arg_for_name (DECL_NAME (clone));
-                  *pointer_map_insert (decl_map, parm) = in_charge;
+                  decl_map->put (parm, in_charge);
                 }
               else if (DECL_ARTIFICIAL (parm)
                        && DECL_NAME (parm) == vtt_parm_identifier)
@@ -611,19 +611,22 @@  maybe_clone_body (tree fn)
                   if (DECL_HAS_VTT_PARM_P (clone))
                     {
                       DECL_ABSTRACT_ORIGIN (clone_parm) = parm;
-                      *pointer_map_insert (decl_map, parm) = clone_parm;
+                      decl_map->put (parm, clone_parm);
                       clone_parm = DECL_CHAIN (clone_parm);
                     }
                   /* Otherwise, map the VTT parameter to `NULL'.  */
                   else
-                    *pointer_map_insert (decl_map, parm)
-                       = fold_convert (TREE_TYPE (parm), null_pointer_node);
+		    {
+		      tree t
+			= fold_convert (TREE_TYPE (parm), null_pointer_node);
+		      decl_map->put (parm, t);
+		    }
                 }
               /* Map other parameters to their equivalents in the cloned
                  function.  */
               else
                 {
-                  *pointer_map_insert (decl_map, parm) = clone_parm;
+                  decl_map->put (parm, clone_parm);
                   clone_parm = DECL_CHAIN (clone_parm);
                 }
             }
@@ -632,14 +635,14 @@  maybe_clone_body (tree fn)
             {
               parm = DECL_RESULT (fn);
               clone_parm = DECL_RESULT (clone);
-              *pointer_map_insert (decl_map, parm) = clone_parm;
+              decl_map->put (parm, clone_parm);
             }
 
           /* Clone the body.  */
           clone_body (clone, fn, decl_map);
 
           /* Clean up.  */
-          pointer_map_destroy (decl_map);
+          delete decl_map;
         }
 
       /* The clone can throw iff the original function can throw.  */
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 735284e..4868d69 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -4977,15 +4977,15 @@  clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
 	       tree decl, tree placeholder)
 {
   copy_body_data id;
-  struct pointer_map_t *decl_map = pointer_map_create ();
+  hash_map<tree, tree> decl_map;
 
-  *pointer_map_insert (decl_map, omp_decl1) = placeholder;
-  *pointer_map_insert (decl_map, omp_decl2) = decl;
+  decl_map.put (omp_decl1, placeholder);
+  decl_map.put (omp_decl2, decl);
   memset (&id, 0, sizeof (id));
   id.src_fn = DECL_CONTEXT (omp_decl1);
   id.dst_fn = current_function_decl;
   id.src_cfun = DECL_STRUCT_FUNCTION (id.src_fn);
-  id.decl_map = decl_map;
+  id.decl_map = &decl_map;
 
   id.copy_decl = copy_decl_no_change;
   id.transform_call_graph_edges = CB_CGE_DUPLICATE;
@@ -4994,7 +4994,6 @@  clone_omp_udr (tree stmt, tree omp_decl1, tree omp_decl2,
   id.transform_lang_insert_block = NULL;
   id.eh_lp_nr = 0;
   walk_tree (&stmt, copy_tree_body_r, &id, NULL);
-  pointer_map_destroy (decl_map);
   return stmt;
 }
 
diff --git a/gcc/except.c b/gcc/except.c
index c8dbc50..ec08e91 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -527,7 +527,7 @@  struct duplicate_eh_regions_data
 {
   duplicate_eh_regions_map label_map;
   void *label_map_data;
-  struct pointer_map_t *eh_map;
+  hash_map<void *, void *> *eh_map;
 };
 
 static void
@@ -536,12 +536,9 @@  duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
 {
   eh_landing_pad old_lp, new_lp;
   eh_region new_r;
-  void **slot;
 
   new_r = gen_eh_region (old_r->type, outer);
-  slot = pointer_map_insert (data->eh_map, (void *)old_r);
-  gcc_assert (*slot == NULL);
-  *slot = (void *)new_r;
+  gcc_assert (!data->eh_map->put (old_r, new_r));
 
   switch (old_r->type)
     {
@@ -586,9 +583,7 @@  duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
 	continue;
 
       new_lp = gen_eh_landing_pad (new_r);
-      slot = pointer_map_insert (data->eh_map, (void *)old_lp);
-      gcc_assert (*slot == NULL);
-      *slot = (void *)new_lp;
+      gcc_assert (!data->eh_map->put (old_lp, new_lp));
 
       new_lp->post_landing_pad
 	= data->label_map (old_lp->post_landing_pad, data->label_map_data);
@@ -609,7 +604,7 @@  duplicate_eh_regions_1 (struct duplicate_eh_regions_data *data,
    that allows the caller to remap uses of both EH regions and
    EH landing pads.  */
 
-struct pointer_map_t *
+hash_map<void *, void *> *
 duplicate_eh_regions (struct function *ifun,
 		      eh_region copy_region, int outer_lp,
 		      duplicate_eh_regions_map map, void *map_data)
@@ -623,7 +618,7 @@  duplicate_eh_regions (struct function *ifun,
 
   data.label_map = map;
   data.label_map_data = map_data;
-  data.eh_map = pointer_map_create ();
+  data.eh_map = new hash_map<void *, void *>;
 
   outer_region = get_eh_region_from_lp_number (outer_lp);
 
diff --git a/gcc/except.h b/gcc/except.h
index bab13e1..5c2aa3d 100644
--- a/gcc/except.h
+++ b/gcc/except.h
@@ -25,6 +25,7 @@  along with GCC; see the file COPYING3.  If not see
 #  define GCC_EXCEPT_H
 #endif
 
+#include "hash-map.h"
 #include "hashtab.h"
 
 struct function;
@@ -249,7 +250,7 @@  extern rtx expand_builtin_extend_pointer (tree);
 extern void expand_dw2_landing_pad_for_region (eh_region);
 
 typedef tree (*duplicate_eh_regions_map) (tree, void *);
-extern struct pointer_map_t *duplicate_eh_regions
+extern hash_map<void *, void *> *duplicate_eh_regions
   (struct function *, eh_region, int, duplicate_eh_regions_map, void *);
 
 extern void sjlj_emit_function_exit_after (rtx);
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index d7c5db5..b13b7f7 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -38,6 +38,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "coretypes.h"
 #include "tree.h"
 #include "pointer-set.h"
+#include "hash-map.h"
 #include "hash-table.h"
 #include "basic-block.h"
 #include "tree-ssa-alias.h"
@@ -373,7 +374,7 @@  enum count_phis_status
 };
  
 /* Pointer map embodying a mapping from statements to candidates.  */
-static struct pointer_map_t *stmt_cand_map;
+static hash_map<gimple, slsr_cand_t> *stmt_cand_map;
 
 /* Obstack for candidates.  */
 static struct obstack cand_obstack;
@@ -435,7 +436,7 @@  static hash_table<cand_chain_hasher> *base_cand_map;
 /* Pointer map used by tree_to_aff_combination_expand.  */
 static struct pointer_map_t *name_expansions;
 /* Pointer map embodying a mapping from bases to alternative bases.  */
-static struct pointer_map_t *alt_base_map;
+static hash_map<tree, tree> *alt_base_map;
 
 /* Given BASE, use the tree affine combiniation facilities to
    find the underlying tree expression for BASE, with any
@@ -447,7 +448,7 @@  static struct pointer_map_t *alt_base_map;
 static tree
 get_alternative_base (tree base)
 {
-  tree *result = (tree *) pointer_map_contains (alt_base_map, base);
+  tree *result = alt_base_map->get (base);
 
   if (result == NULL)
     {
@@ -459,13 +460,9 @@  get_alternative_base (tree base)
       aff.offset = 0;
       expr = aff_combination_to_tree (&aff);
 
-      result = (tree *) pointer_map_insert (alt_base_map, base);
-      gcc_assert (!*result);
+      gcc_assert (!alt_base_map->put (base, base == expr ? NULL : expr));
 
-      if (expr == base)
-	*result = NULL;
-      else
-	*result = expr;
+      return expr == base ? NULL : expr;
     }
 
   return *result;
@@ -724,7 +721,7 @@  base_cand_from_table (tree base_in)
   if (!def)
     return (slsr_cand_t) NULL;
 
-  result = (slsr_cand_t *) pointer_map_contains (stmt_cand_map, def);
+  result = stmt_cand_map->get (def);
   
   if (result && (*result)->kind != CAND_REF)
     return *result;
@@ -737,9 +734,7 @@  base_cand_from_table (tree base_in)
 static void
 add_cand_for_stmt (gimple gs, slsr_cand_t c)
 {
-  void **slot = pointer_map_insert (stmt_cand_map, gs);
-  gcc_assert (!*slot);
-  *slot = c;
+  gcc_assert (!stmt_cand_map->put (gs, c));
 }
 
 /* Given PHI which contains a phi statement, determine whether it
@@ -3628,7 +3623,7 @@  pass_strength_reduction::execute (function *fun)
   cand_vec.create (128);
 
   /* Allocate the mapping from statements to candidate indices.  */
-  stmt_cand_map = pointer_map_create ();
+  stmt_cand_map = new hash_map<gimple, slsr_cand_t>;
 
   /* Create the obstack where candidate chains will reside.  */
   gcc_obstack_init (&chain_obstack);
@@ -3637,7 +3632,7 @@  pass_strength_reduction::execute (function *fun)
   base_cand_map = new hash_table<cand_chain_hasher> (500);
 
   /* Allocate the mapping from bases to alternative bases.  */
-  alt_base_map = pointer_map_create ();
+  alt_base_map = new hash_map<tree, tree>;
 
   /* Initialize the loop optimizer.  We need to detect flow across
      back edges, and this gives us dominator information as well.  */
@@ -3654,7 +3649,7 @@  pass_strength_reduction::execute (function *fun)
       dump_cand_chains ();
     }
 
-  pointer_map_destroy (alt_base_map);
+  delete alt_base_map;
   free_affine_expand_cache (&name_expansions);
 
   /* Analyze costs and make appropriate replacements.  */
@@ -3664,7 +3659,7 @@  pass_strength_reduction::execute (function *fun)
   delete base_cand_map;
   base_cand_map = NULL;
   obstack_free (&chain_obstack, NULL);
-  pointer_map_destroy (stmt_cand_map);
+  delete stmt_cand_map;
   cand_vec.release ();
   obstack_free (&cand_obstack, NULL);
 
diff --git a/gcc/hash-map.h b/gcc/hash-map.h
index 0b50f72..ec48844 100644
--- a/gcc/hash-map.h
+++ b/gcc/hash-map.h
@@ -93,7 +93,7 @@  private:
   static void
   mark_key_deleted (T *&k)
     {
-      k = static_cast<T *> (1);
+      k = reinterpret_cast<T *> (1);
     }
 
   template<typename T>
@@ -185,6 +185,11 @@  public:
       return e->m_value;
     }
 
+  void remove (const Key &k)
+    {
+      m_table.remove_elt_with_hash (k, Traits::hash (k));
+    }
+
   /* Call the call back on each pair of key and value with the passed in
      arg.  */
 
@@ -196,6 +201,15 @@  public:
 	f ((*iter).m_key, (*iter).m_value, a);
     }
 
+  template<typename Arg, bool (*f)(const Key &, Value *, Arg)>
+  void traverse (Arg a) const
+    {
+      for (typename hash_table<hash_entry>::iterator iter = m_table.begin ();
+	   iter != m_table.end (); ++iter)
+	if (!f ((*iter).m_key, &(*iter).m_value, a))
+	  break;
+    }
+
 private:
   hash_table<hash_entry> m_table;
 };
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 7810e55..a391b5d 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -389,7 +389,7 @@  cgraph_node_set_new (void)
   cgraph_node_set new_node_set;
 
   new_node_set = XCNEW (struct cgraph_node_set_def);
-  new_node_set->map = pointer_map_create ();
+  new_node_set->map = new hash_map<cgraph_node *, size_t>;
   new_node_set->nodes.create (0);
   return new_node_set;
 }
@@ -400,19 +400,17 @@  cgraph_node_set_new (void)
 void
 cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
 {
-  void **slot;
+  bool existed_p;
+  size_t &index = set->map->get_or_insert (node, &existed_p);
 
-  slot = pointer_map_insert (set->map, node);
-
-  if (*slot)
+  if (existed_p)
     {
-      int index = (size_t) *slot - 1;
       gcc_checking_assert ((set->nodes[index]
 		           == node));
       return;
     }
 
-  *slot = (void *)(size_t) (set->nodes.length () + 1);
+  index = set->nodes.length () + 1;
 
   /* Insert into node vector.  */
   set->nodes.safe_push (node);
@@ -424,15 +422,14 @@  cgraph_node_set_add (cgraph_node_set set, struct cgraph_node *node)
 void
 cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
 {
-  void **slot, **last_slot;
   int index;
   struct cgraph_node *last_node;
 
-  slot = pointer_map_contains (set->map, node);
+  size_t *slot = set->map->get (node);
   if (slot == NULL || !*slot)
     return;
 
-  index = (size_t) *slot - 1;
+  index = *slot - 1;
   gcc_checking_assert (set->nodes[index]
 	      	       == node);
 
@@ -441,16 +438,16 @@  cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
   last_node = set->nodes.pop ();
   if (last_node != node)
     {
-      last_slot = pointer_map_contains (set->map, last_node);
+      size_t *last_slot = set->map->get (last_node);
       gcc_checking_assert (last_slot && *last_slot);
-      *last_slot = (void *)(size_t) (index + 1);
+      *last_slot = index + 1;
 
       /* Move the last element to the original spot of NODE.  */
       set->nodes[index] = last_node;
     }
 
   /* Remove element from hash table.  */
-  *slot = NULL;
+  set->map->remove (node);
 }
 
 
@@ -460,14 +457,14 @@  cgraph_node_set_remove (cgraph_node_set set, struct cgraph_node *node)
 cgraph_node_set_iterator
 cgraph_node_set_find (cgraph_node_set set, struct cgraph_node *node)
 {
-  void **slot;
+  size_t *slot;
   cgraph_node_set_iterator csi;
 
-  slot = pointer_map_contains (set->map, node);
+  slot = set->map->get (node);
   if (slot == NULL || !*slot)
     csi.index = (unsigned) ~0;
   else
-    csi.index = (size_t)*slot - 1;
+    csi.index = *slot - 1;
   csi.set = set;
 
   return csi;
@@ -505,7 +502,7 @@  void
 free_cgraph_node_set (cgraph_node_set set)
 {
   set->nodes.release ();
-  pointer_map_destroy (set->map);
+  delete set->map;
   free (set);
 }
 
@@ -518,7 +515,7 @@  varpool_node_set_new (void)
   varpool_node_set new_node_set;
 
   new_node_set = XCNEW (struct varpool_node_set_def);
-  new_node_set->map = pointer_map_create ();
+  new_node_set->map = new hash_map<varpool_node *, size_t>;
   new_node_set->nodes.create (0);
   return new_node_set;
 }
@@ -529,19 +526,18 @@  varpool_node_set_new (void)
 void
 varpool_node_set_add (varpool_node_set set, varpool_node *node)
 {
-  void **slot;
-
-  slot = pointer_map_insert (set->map, node);
+  bool existed;
+  size_t &slot = set->map->get_or_insert (node, &existed);
 
-  if (*slot)
+  if (existed)
     {
-      int index = (size_t) *slot - 1;
+      int index = slot - 1;
       gcc_checking_assert ((set->nodes[index]
 		           == node));
       return;
     }
 
-  *slot = (void *)(size_t) (set->nodes.length () + 1);
+  slot = set->nodes.length () + 1;
 
   /* Insert into node vector.  */
   set->nodes.safe_push (node);
@@ -553,15 +549,14 @@  varpool_node_set_add (varpool_node_set set, varpool_node *node)
 void
 varpool_node_set_remove (varpool_node_set set, varpool_node *node)
 {
-  void **slot, **last_slot;
   int index;
   varpool_node *last_node;
 
-  slot = pointer_map_contains (set->map, node);
+  size_t *slot = set->map->get (node);
   if (slot == NULL || !*slot)
     return;
 
-  index = (size_t) *slot - 1;
+  index = *slot - 1;
   gcc_checking_assert (set->nodes[index]
 	      	       == node);
 
@@ -570,16 +565,16 @@  varpool_node_set_remove (varpool_node_set set, varpool_node *node)
   last_node = set->nodes.pop ();
   if (last_node != node)
     {
-      last_slot = pointer_map_contains (set->map, last_node);
+      size_t *last_slot = set->map->get (last_node);
       gcc_checking_assert (last_slot && *last_slot);
-      *last_slot = (void *)(size_t) (index + 1);
+      *last_slot = index + 1;
 
       /* Move the last element to the original spot of NODE.  */
       set->nodes[index] = last_node;
     }
 
   /* Remove element from hash table.  */
-  *slot = NULL;
+  set->map->remove (node);
 }
 
 
@@ -589,14 +584,13 @@  varpool_node_set_remove (varpool_node_set set, varpool_node *node)
 varpool_node_set_iterator
 varpool_node_set_find (varpool_node_set set, varpool_node *node)
 {
-  void **slot;
   varpool_node_set_iterator vsi;
 
-  slot = pointer_map_contains (set->map, node);
+  size_t *slot = set->map->get (node);
   if (slot == NULL || !*slot)
     vsi.index = (unsigned) ~0;
   else
-    vsi.index = (size_t)*slot - 1;
+    vsi.index = *slot - 1;
   vsi.set = set;
 
   return vsi;
@@ -625,7 +619,7 @@  void
 free_varpool_node_set (varpool_node_set set)
 {
   set->nodes.release ();
-  pointer_map_destroy (set->map);
+  delete set->map;
   free (set);
 }
 
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 42b0790..28a30ad 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -93,7 +93,7 @@  lto_symtab_encoder_new (bool for_input)
   lto_symtab_encoder_t encoder = XCNEW (struct lto_symtab_encoder_d);
 
   if (!for_input)
-    encoder->map = pointer_map_create ();
+    encoder->map = new hash_map<symtab_node *, size_t>;
   encoder->nodes.create (0);
   return encoder;
 }
@@ -106,7 +106,7 @@  lto_symtab_encoder_delete (lto_symtab_encoder_t encoder)
 {
    encoder->nodes.release ();
    if (encoder->map)
-     pointer_map_destroy (encoder->map);
+     delete encoder->map;
    free (encoder);
 }
 
@@ -120,7 +120,6 @@  lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
 			   symtab_node *node)
 {
   int ref;
-  void **slot;
 
   if (!encoder->map)
     {
@@ -131,18 +130,17 @@  lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
       return ref;
     }
 
-  slot = pointer_map_contains (encoder->map, node);
+  size_t *slot = encoder->map->get (node);
   if (!slot || !*slot)
     {
       lto_encoder_entry entry = {node, false, false, false};
       ref = encoder->nodes.length ();
       if (!slot)
-        slot = pointer_map_insert (encoder->map, node);
-      *slot = (void *) (intptr_t) (ref + 1);
+        encoder->map->put (node, ref + 1);
       encoder->nodes.safe_push (entry);
     }
   else
-    ref = (size_t) *slot - 1;
+    ref = *slot - 1;
 
   return ref;
 }
@@ -153,15 +151,14 @@  bool
 lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
 			        symtab_node *node)
 {
-  void **slot, **last_slot;
   int index;
   lto_encoder_entry last_node;
 
-  slot = pointer_map_contains (encoder->map, node);
+  size_t *slot = encoder->map->get (node);
   if (slot == NULL || !*slot)
     return false;
 
-  index = (size_t) *slot - 1;
+  index = *slot - 1;
   gcc_checking_assert (encoder->nodes[index].node == node);
 
   /* Remove from vector. We do this by swapping node with the last element
@@ -169,16 +166,14 @@  lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
   last_node = encoder->nodes.pop ();
   if (last_node.node != node)
     {
-      last_slot = pointer_map_contains (encoder->map, last_node.node);
-      gcc_checking_assert (last_slot && *last_slot);
-      *last_slot = (void *)(size_t) (index + 1);
+      gcc_assert (encoder->map->put (last_node.node, index + 1));
 
       /* Move the last element to the original spot of NODE.  */
       encoder->nodes[index] = last_node;
     }
 
   /* Remove element from hash table.  */
-  *slot = NULL;
+  encoder->map->remove (node);
   return true;
 }
 
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index d350ad9..b2486dd 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -443,7 +443,7 @@  struct lto_encoder_entry
 struct lto_symtab_encoder_d
 {
   vec<lto_encoder_entry> nodes;
-  pointer_map_t *map;
+  hash_map<symtab_node *, size_t> *map;
 };
 
 typedef struct lto_symtab_encoder_d *lto_symtab_encoder_t;
@@ -1046,8 +1046,8 @@  static inline int
 lto_symtab_encoder_lookup (lto_symtab_encoder_t encoder,
 			   symtab_node *node)
 {
-  void **slot = pointer_map_contains (encoder->map, node);
-  return (slot && *slot ? (size_t) *(slot) - 1 : LCC_NOT_FOUND);
+  size_t *slot = encoder->map->get (node);
+  return (slot && *slot ? *(slot) - 1 : LCC_NOT_FOUND);
 }
 
 /* Return true if iterator LSE points to nothing.  */
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index b46693b..0fe2a40 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -812,16 +812,14 @@  is_reference (tree decl)
 static inline tree
 lookup_decl (tree var, omp_context *ctx)
 {
-  tree *n;
-  n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
+  tree *n = ctx->cb.decl_map->get (var);
   return *n;
 }
 
 static inline tree
 maybe_lookup_decl (const_tree var, omp_context *ctx)
 {
-  tree *n;
-  n = (tree *) pointer_map_contains (ctx->cb.decl_map, var);
+  tree *n = ctx->cb.decl_map->get (const_cast<tree> (var));
   return n ? *n : NULL_TREE;
 }
 
@@ -1359,7 +1357,7 @@  new_omp_context (gimple stmt, omp_context *outer_ctx)
       ctx->depth = 1;
     }
 
-  ctx->cb.decl_map = pointer_map_create ();
+  ctx->cb.decl_map = new hash_map<tree, tree>;
 
   return ctx;
 }
@@ -1408,7 +1406,7 @@  delete_omp_context (splay_tree_value value)
 {
   omp_context *ctx = (omp_context *) value;
 
-  pointer_map_destroy (ctx->cb.decl_map);
+  delete ctx->cb.decl_map;
 
   if (ctx->field_map)
     splay_tree_delete (ctx->field_map);
@@ -6541,7 +6539,6 @@  expand_omp_for_static_chunk (struct omp_region *region,
       gimple_stmt_iterator psi;
       gimple phi;
       edge re, ene;
-      edge_var_map_vector *head;
       edge_var_map *vm;
       size_t i;
 
@@ -6552,7 +6549,7 @@  expand_omp_for_static_chunk (struct omp_region *region,
 	 appropriate phi nodes in iter_part_bb instead.  */
       se = single_pred_edge (fin_bb);
       re = single_succ_edge (trip_update_bb);
-      head = redirect_edge_var_map_vector (re);
+      vec<edge_var_map> *head = redirect_edge_var_map_vector (re);
       ene = single_succ_edge (entry_bb);
 
       psi = gsi_start_phis (fin_bb);
@@ -9219,7 +9216,7 @@  task_copyfn_remap_type (struct omp_taskcopy_context *tcctx, tree orig_type)
       walk_tree (&DECL_FIELD_OFFSET (new_f), copy_tree_body_r,
 		 &tcctx->cb, NULL);
       new_fields = new_f;
-      *pointer_map_insert (tcctx->cb.decl_map, f) = new_f;
+      tcctx->cb.decl_map->put (f, new_f);
     }
   TYPE_FIELDS (type) = nreverse (new_fields);
   layout_type (type);
@@ -9286,7 +9283,7 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
       tcctx.cb.copy_decl = task_copyfn_copy_decl;
       tcctx.cb.eh_lp_nr = 0;
       tcctx.cb.transform_call_graph_edges = CB_CGE_MOVE;
-      tcctx.cb.decl_map = pointer_map_create ();
+      tcctx.cb.decl_map = new hash_map<tree, tree>;
       tcctx.ctx = ctx;
 
       if (record_needs_remap)
@@ -9311,12 +9308,12 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
 	  tree *p;
 
 	  decl = OMP_CLAUSE_DECL (c);
-	  p = (tree *) pointer_map_contains (tcctx.cb.decl_map, decl);
+	  p = tcctx.cb.decl_map->get (decl);
 	  if (p == NULL)
 	    continue;
 	  n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
 	  sf = (tree) n->value;
-	  sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
+	  sf = *tcctx.cb.decl_map->get (sf);
 	  src = build_simple_mem_ref_loc (loc, sarg);
 	  src = omp_build_component_ref (src, sf);
 	  t = build2 (MODIFY_EXPR, TREE_TYPE (*p), *p, src);
@@ -9335,11 +9332,11 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
 	  break;
 	f = (tree) n->value;
 	if (tcctx.cb.decl_map)
-	  f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
+	  f = *tcctx.cb.decl_map->get (f);
 	n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
 	sf = (tree) n->value;
 	if (tcctx.cb.decl_map)
-	  sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
+	  sf = *tcctx.cb.decl_map->get (sf);
 	src = build_simple_mem_ref_loc (loc, sarg);
 	src = omp_build_component_ref (src, sf);
 	dst = build_simple_mem_ref_loc (loc, arg);
@@ -9356,13 +9353,13 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
 	  break;
 	f = (tree) n->value;
 	if (tcctx.cb.decl_map)
-	  f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
+	  f = *tcctx.cb.decl_map->get (f);
 	n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
 	if (n != NULL)
 	  {
 	    sf = (tree) n->value;
 	    if (tcctx.cb.decl_map)
-	      sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
+	      sf = *tcctx.cb.decl_map->get (sf);
 	    src = build_simple_mem_ref_loc (loc, sarg);
 	    src = omp_build_component_ref (src, sf);
 	    if (use_pointer_for_field (decl, NULL) || is_reference (decl))
@@ -9382,13 +9379,13 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
 	n = splay_tree_lookup (ctx->field_map, (splay_tree_key) decl);
 	f = (tree) n->value;
 	if (tcctx.cb.decl_map)
-	  f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
+	  f = *tcctx.cb.decl_map->get (f);
 	n = splay_tree_lookup (ctx->sfield_map, (splay_tree_key) decl);
 	if (n != NULL)
 	  {
 	    sf = (tree) n->value;
 	    if (tcctx.cb.decl_map)
-	      sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
+	      sf = *tcctx.cb.decl_map->get (sf);
 	    src = build_simple_mem_ref_loc (loc, sarg);
 	    src = omp_build_component_ref (src, sf);
 	    if (use_pointer_for_field (decl, NULL))
@@ -9419,7 +9416,7 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
 	  if (n == NULL)
 	    continue;
 	  f = (tree) n->value;
-	  f = *(tree *) pointer_map_contains (tcctx.cb.decl_map, f);
+	  f = *tcctx.cb.decl_map->get (f);
 	  gcc_assert (DECL_HAS_VALUE_EXPR_P (decl));
 	  ind = DECL_VALUE_EXPR (decl);
 	  gcc_assert (TREE_CODE (ind) == INDIRECT_REF);
@@ -9427,7 +9424,7 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
 	  n = splay_tree_lookup (ctx->sfield_map,
 				 (splay_tree_key) TREE_OPERAND (ind, 0));
 	  sf = (tree) n->value;
-	  sf = *(tree *) pointer_map_contains (tcctx.cb.decl_map, sf);
+	  sf = *tcctx.cb.decl_map->get (sf);
 	  src = build_simple_mem_ref_loc (loc, sarg);
 	  src = omp_build_component_ref (src, sf);
 	  src = build_simple_mem_ref_loc (loc, src);
@@ -9438,7 +9435,7 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
 	  n = splay_tree_lookup (ctx->field_map,
 				 (splay_tree_key) TREE_OPERAND (ind, 0));
 	  df = (tree) n->value;
-	  df = *(tree *) pointer_map_contains (tcctx.cb.decl_map, df);
+	  df = *tcctx.cb.decl_map->get (df);
 	  ptr = build_simple_mem_ref_loc (loc, arg);
 	  ptr = omp_build_component_ref (ptr, df);
 	  t = build2 (MODIFY_EXPR, TREE_TYPE (ptr), ptr,
@@ -9450,7 +9447,7 @@  create_task_copyfn (gimple task_stmt, omp_context *ctx)
   append_to_statement_list (t, &list);
 
   if (tcctx.cb.decl_map)
-    pointer_map_destroy (tcctx.cb.decl_map);
+    delete tcctx.cb.decl_map;
   pop_gimplify_context (NULL);
   BIND_EXPR_BODY (bind) = list;
   pop_cfun ();
diff --git a/gcc/predict.c b/gcc/predict.c
index 72a3b53..34ebdc3 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -52,6 +52,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "cfgloop.h"
 #include "pointer-set.h"
+#include "hash-map.h"
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
 #include "gimple-expr.h"
@@ -490,11 +491,6 @@  rtl_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
   return false;
 }
 
-/* This map contains for a basic block the list of predictions for the
-   outgoing edges.  */
-
-static struct pointer_map_t *bb_predictions;
-
 /*  Structure representing predictions in tree level. */
 
 struct edge_prediction {
@@ -504,6 +500,11 @@  struct edge_prediction {
     int ep_probability;
 };
 
+/* This map contains for a basic block the list of predictions for the
+   outgoing edges.  */
+
+static hash_map<const_basic_block, edge_prediction *> *bb_predictions;
+
 /* Return true if the one of outgoing edges is already predicted by
    PREDICTOR.  */
 
@@ -511,12 +512,12 @@  bool
 gimple_predicted_by_p (const_basic_block bb, enum br_predictor predictor)
 {
   struct edge_prediction *i;
-  void **preds = pointer_map_contains (bb_predictions, bb);
+  edge_prediction **preds = bb_predictions->get (bb);
 
   if (!preds)
     return false;
 
-  for (i = (struct edge_prediction *) *preds; i; i = i->ep_next)
+  for (i = *preds; i; i = i->ep_next)
     if (i->ep_predictor == predictor)
       return true;
   return false;
@@ -618,10 +619,10 @@  gimple_predict_edge (edge e, enum br_predictor predictor, int probability)
       && flag_guess_branch_prob && optimize)
     {
       struct edge_prediction *i = XNEW (struct edge_prediction);
-      void **preds = pointer_map_insert (bb_predictions, e->src);
+      edge_prediction *&preds = bb_predictions->get_or_insert (e->src);
 
-      i->ep_next = (struct edge_prediction *) *preds;
-      *preds = i;
+      i->ep_next = preds;
+      preds = i;
       i->ep_probability = probability;
       i->ep_predictor = predictor;
       i->ep_edge = e;
@@ -633,16 +634,14 @@  gimple_predict_edge (edge e, enum br_predictor predictor, int probability)
 void
 remove_predictions_associated_with_edge (edge e)
 {
-  void **preds;
-
   if (!bb_predictions)
     return;
 
-  preds = pointer_map_contains (bb_predictions, e->src);
+  edge_prediction **preds = bb_predictions->get (e->src);
 
   if (preds)
     {
-      struct edge_prediction **prediction = (struct edge_prediction **) preds;
+      struct edge_prediction **prediction = preds;
       struct edge_prediction *next;
 
       while (*prediction)
@@ -664,13 +663,13 @@  remove_predictions_associated_with_edge (edge e)
 static void
 clear_bb_predictions (basic_block bb)
 {
-  void **preds = pointer_map_contains (bb_predictions, bb);
+  edge_prediction **preds = bb_predictions->get (bb);
   struct edge_prediction *pred, *next;
 
   if (!preds)
     return;
 
-  for (pred = (struct edge_prediction *) *preds; pred; pred = next)
+  for (pred = *preds; pred; pred = next)
     {
       next = pred->ep_next;
       free (pred);
@@ -903,7 +902,6 @@  combine_predictions_for_bb (basic_block bb)
   int nedges = 0;
   edge e, first = NULL, second = NULL;
   edge_iterator ei;
-  void **preds;
 
   FOR_EACH_EDGE (e, ei, bb->succs)
     if (!(e->flags & (EDGE_EH | EDGE_FAKE)))
@@ -935,12 +933,12 @@  combine_predictions_for_bb (basic_block bb)
   if (dump_file)
     fprintf (dump_file, "Predictions for bb %i\n", bb->index);
 
-  preds = pointer_map_contains (bb_predictions, bb);
+  edge_prediction **preds = bb_predictions->get (bb);
   if (preds)
     {
       /* We implement "first match" heuristics and use probability guessed
 	 by predictor with smallest index.  */
-      for (pred = (struct edge_prediction *) *preds; pred; pred = pred->ep_next)
+      for (pred = *preds; pred; pred = pred->ep_next)
 	{
 	  enum br_predictor predictor = pred->ep_predictor;
 	  int probability = pred->ep_probability;
@@ -2243,14 +2241,14 @@  tree_bb_level_predictions (void)
 
 #ifdef ENABLE_CHECKING
 
-/* Callback for pointer_map_traverse, asserts that the pointer map is
+/* Callback for hash_map::traverse, asserts that the pointer map is
    empty.  */
 
-static bool
-assert_is_empty (const void *key ATTRIBUTE_UNUSED, void **value,
-		 void *data ATTRIBUTE_UNUSED)
+bool
+assert_is_empty (const_basic_block const &, edge_prediction *const &value,
+		 void *)
 {
-  gcc_assert (!*value);
+  gcc_assert (!value);
   return false;
 }
 #endif
@@ -2375,7 +2373,7 @@  tree_estimate_probability (void)
   create_preheaders (CP_SIMPLE_PREHEADERS);
   calculate_dominance_info (CDI_POST_DOMINATORS);
 
-  bb_predictions = pointer_map_create ();
+  bb_predictions = new hash_map<const_basic_block, edge_prediction *>;
   tree_bb_level_predictions ();
   record_loop_exits ();
 
@@ -2389,9 +2387,9 @@  tree_estimate_probability (void)
     combine_predictions_for_bb (bb);
 
 #ifdef ENABLE_CHECKING
-  pointer_map_traverse (bb_predictions, assert_is_empty, NULL);
+  bb_predictions->traverse<void *, assert_is_empty> (NULL);
 #endif
-  pointer_map_destroy (bb_predictions);
+  delete bb_predictions;
   bb_predictions = NULL;
 
   estimate_bb_frequencies (false);
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index e034762..cfa6527 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -22,6 +22,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "system.h"
 #include "coretypes.h"
 #include "hash-table.h"
+#include "hash-map.h"
 #include "tm.h"
 #include "tree.h"
 #include "trans-mem.h"
@@ -92,7 +93,7 @@  static const int initial_cfg_capacity = 20;
    more persistent.  The key is getting notification of changes to
    the CFG (particularly edge removal, creation and redirection).  */
 
-static struct pointer_map_t *edge_to_cases;
+static hash_map<edge, tree> *edge_to_cases;
 
 /* If we record edge_to_cases, this bitmap will hold indexes
    of basic blocks that end in a GIMPLE_SWITCH which we touched
@@ -1048,19 +1049,17 @@  make_cond_expr_edges (basic_block bb)
    SWITCH_EXPRs and structure sharing rules, then free the hash table
    element.  */
 
-static bool
-edge_to_cases_cleanup (const void *key ATTRIBUTE_UNUSED, void **value,
-		       void *data ATTRIBUTE_UNUSED)
+bool
+edge_to_cases_cleanup (edge const &, tree const &value, void *)
 {
   tree t, next;
 
-  for (t = (tree) *value; t; t = next)
+  for (t = value; t; t = next)
     {
       next = CASE_CHAIN (t);
       CASE_CHAIN (t) = NULL;
     }
 
-  *value = NULL;
   return true;
 }
 
@@ -1070,7 +1069,7 @@  void
 start_recording_case_labels (void)
 {
   gcc_assert (edge_to_cases == NULL);
-  edge_to_cases = pointer_map_create ();
+  edge_to_cases = new hash_map<edge, tree>;
   touched_switch_bbs = BITMAP_ALLOC (NULL);
 }
 
@@ -1089,8 +1088,8 @@  end_recording_case_labels (void)
 {
   bitmap_iterator bi;
   unsigned i;
-  pointer_map_traverse (edge_to_cases, edge_to_cases_cleanup, NULL);
-  pointer_map_destroy (edge_to_cases);
+  edge_to_cases->traverse<void *, edge_to_cases_cleanup> (NULL);
+  delete edge_to_cases;
   edge_to_cases = NULL;
   EXECUTE_IF_SET_IN_BITMAP (touched_switch_bbs, 0, i, bi)
     {
@@ -1113,7 +1112,7 @@  end_recording_case_labels (void)
 static tree
 get_cases_for_edge (edge e, gimple t)
 {
-  void **slot;
+  tree *slot;
   size_t i, n;
 
   /* If we are not recording cases, then we do not have CASE_LABEL_EXPR
@@ -1121,9 +1120,9 @@  get_cases_for_edge (edge e, gimple t)
   if (!recording_case_labels_p ())
     return NULL;
 
-  slot = pointer_map_contains (edge_to_cases, e);
+  slot = edge_to_cases->get (e);
   if (slot)
-    return (tree) *slot;
+    return *slot;
 
   /* If we did not find E in the hash table, then this must be the first
      time we have been queried for information about E & T.  Add all the
@@ -1139,12 +1138,12 @@  get_cases_for_edge (edge e, gimple t)
 
       /* Add it to the chain of CASE_LABEL_EXPRs referencing E, or create
 	 a new chain.  */
-      slot = pointer_map_insert (edge_to_cases, this_edge);
-      CASE_CHAIN (elt) = (tree) *slot;
-      *slot = elt;
+      tree &s = edge_to_cases->get_or_insert (this_edge);
+      CASE_CHAIN (elt) = s;
+      s = elt;
     }
 
-  return (tree) *pointer_map_contains (edge_to_cases, e);
+  return *edge_to_cases->get (e);
 }
 
 /* Create the edges for a GIMPLE_SWITCH starting at block BB.  */
@@ -2577,12 +2576,11 @@  last_and_only_stmt (basic_block bb)
 static void
 reinstall_phi_args (edge new_edge, edge old_edge)
 {
-  edge_var_map_vector *v;
   edge_var_map *vm;
   int i;
   gimple_stmt_iterator phis;
 
-  v = redirect_edge_var_map_vector (old_edge);
+  vec<edge_var_map> *v = redirect_edge_var_map_vector (old_edge);
   if (!v)
     return;
 
@@ -6268,22 +6266,20 @@  gather_blocks_in_sese_region (basic_block entry, basic_block exit,
    The duplicates are recorded in VARS_MAP.  */
 
 static void
-replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
+replace_by_duplicate_decl (tree *tp, hash_map<tree, tree> *vars_map,
 			   tree to_context)
 {
   tree t = *tp, new_t;
   struct function *f = DECL_STRUCT_FUNCTION (to_context);
-  void **loc;
 
   if (DECL_CONTEXT (t) == to_context)
     return;
 
-  loc = pointer_map_contains (vars_map, t);
+  bool existed;
+  tree &loc = vars_map->get_or_insert (t, &existed);
 
-  if (!loc)
+  if (!existed)
     {
-      loc = pointer_map_insert (vars_map, t);
-
       if (SSA_VAR_P (t))
 	{
 	  new_t = copy_var_decl (t, DECL_NAME (t), TREE_TYPE (t));
@@ -6296,10 +6292,10 @@  replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
 	}
       DECL_CONTEXT (new_t) = to_context;
 
-      *loc = new_t;
+      loc = new_t;
     }
   else
-    new_t = (tree) *loc;
+    new_t = loc;
 
   *tp = new_t;
 }
@@ -6309,15 +6305,14 @@  replace_by_duplicate_decl (tree *tp, struct pointer_map_t *vars_map,
    VARS_MAP maps old ssa names and var_decls to the new ones.  */
 
 static tree
-replace_ssa_name (tree name, struct pointer_map_t *vars_map,
+replace_ssa_name (tree name, hash_map<tree, tree> *vars_map,
 		  tree to_context)
 {
-  void **loc;
   tree new_name;
 
   gcc_assert (!virtual_operand_p (name));
 
-  loc = pointer_map_contains (vars_map, name);
+  tree *loc = vars_map->get (name);
 
   if (!loc)
     {
@@ -6335,11 +6330,10 @@  replace_ssa_name (tree name, struct pointer_map_t *vars_map,
 	new_name = copy_ssa_name_fn (DECL_STRUCT_FUNCTION (to_context),
 				     name, SSA_NAME_DEF_STMT (name));
 
-      loc = pointer_map_insert (vars_map, name);
-      *loc = new_name;
+      vars_map->put (name, new_name);
     }
   else
-    new_name = (tree) *loc;
+    new_name = *loc;
 
   return new_name;
 }
@@ -6350,9 +6344,9 @@  struct move_stmt_d
   tree new_block;
   tree from_context;
   tree to_context;
-  struct pointer_map_t *vars_map;
+  hash_map<tree, tree> *vars_map;
   htab_t new_label_map;
-  struct pointer_map_t *eh_map;
+  hash_map<void *, void *> *eh_map;
   bool remap_decls_p;
 };
 
@@ -6429,11 +6423,9 @@  static int
 move_stmt_eh_region_nr (int old_nr, struct move_stmt_d *p)
 {
   eh_region old_r, new_r;
-  void **slot;
 
   old_r = get_eh_region_from_number (old_nr);
-  slot = pointer_map_contains (p->eh_map, old_r);
-  new_r = (eh_region) *slot;
+  new_r = static_cast<eh_region> (*p->eh_map->get (old_r));
 
   return new_r->index;
 }
@@ -6767,7 +6759,7 @@  new_label_mapper (tree decl, void *data)
    subblocks.  */
 
 static void
-replace_block_vars_by_duplicates (tree block, struct pointer_map_t *vars_map,
+replace_block_vars_by_duplicates (tree block, hash_map<tree, tree> *vars_map,
 				  tree to_context)
 {
   tree *tp, t;
@@ -6845,7 +6837,7 @@  move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
   edge e;
   edge_iterator ei;
   htab_t new_label_map;
-  struct pointer_map_t *vars_map, *eh_map;
+  hash_map<void *, void *> *eh_map;
   struct loop *loop = entry_bb->loop_father;
   struct loop *loop0 = get_loop (saved_cfun, 0);
   struct move_stmt_d d;
@@ -6989,14 +6981,14 @@  move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
   /* Move blocks from BBS into DEST_CFUN.  */
   gcc_assert (bbs.length () >= 2);
   after = dest_cfun->cfg->x_entry_block_ptr;
-  vars_map = pointer_map_create ();
+  hash_map<tree, tree> vars_map;
 
   memset (&d, 0, sizeof (d));
   d.orig_block = orig_block;
   d.new_block = DECL_INITIAL (dest_cfun->decl);
   d.from_context = cfun->decl;
   d.to_context = dest_cfun->decl;
-  d.vars_map = vars_map;
+  d.vars_map = &vars_map;
   d.new_label_map = new_label_map;
   d.eh_map = eh_map;
   d.remap_decls_p = true;
@@ -7051,13 +7043,12 @@  move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb,
     }
 
   replace_block_vars_by_duplicates (DECL_INITIAL (dest_cfun->decl),
-				    vars_map, dest_cfun->decl);
+				    &vars_map, dest_cfun->decl);
 
   if (new_label_map)
     htab_delete (new_label_map);
   if (eh_map)
-    pointer_map_destroy (eh_map);
-  pointer_map_destroy (vars_map);
+    delete eh_map;
 
   /* Rewire the entry and exit blocks.  The successor to the entry
      block turns into the successor of DEST_FN's ENTRY_BLOCK_PTR in
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index bc4d83e..2b6927e 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -865,16 +865,14 @@  remove_forwarder_block_with_phi (basic_block bb)
 
 	  if (TREE_CODE (def) == SSA_NAME)
 	    {
-	      edge_var_map_vector *head;
-	      edge_var_map *vm;
-	      size_t i;
-
 	      /* If DEF is one of the results of PHI nodes removed during
 		 redirection, replace it with the PHI argument that used
 		 to be on E.  */
-	      head = redirect_edge_var_map_vector (e);
-	      FOR_EACH_VEC_SAFE_ELT (head, i, vm)
+	      vec<edge_var_map> *head = redirect_edge_var_map_vector (e);
+	      size_t length = head ? head->length () : 0;
+	      for (size_t i = 0; i < length; i++)
 		{
+		  edge_var_map *vm = &(*head)[i];
 		  tree old_arg = redirect_edge_var_map_result (vm);
 		  tree new_arg = redirect_edge_var_map_def (vm);
 
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 38842e8..db28184 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -406,7 +406,7 @@  struct leh_tf_state
   size_t goto_queue_active;
 
   /* Pointer map to help in searching goto_queue when it is large.  */
-  struct pointer_map_t *goto_queue_map;
+  hash_map<gimple, goto_queue_node *> *goto_queue_map;
 
   /* The set of unique labels seen as entries in the goto queue.  */
   vec<tree> dest_array;
@@ -441,7 +441,6 @@  static gimple_seq
 find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
 {
   unsigned int i;
-  void **slot;
 
   if (tf->goto_queue_active < LARGE_GOTO_QUEUE)
     {
@@ -456,19 +455,18 @@  find_goto_replacement (struct leh_tf_state *tf, treemple stmt)
 
   if (!tf->goto_queue_map)
     {
-      tf->goto_queue_map = pointer_map_create ();
+      tf->goto_queue_map = new hash_map<gimple, goto_queue_node *>;
       for (i = 0; i < tf->goto_queue_active; i++)
 	{
-	  slot = pointer_map_insert (tf->goto_queue_map,
-                                     tf->goto_queue[i].stmt.g);
-          gcc_assert (*slot == NULL);
-	  *slot = &tf->goto_queue[i];
+	  bool existed = tf->goto_queue_map->put (tf->goto_queue[i].stmt.g,
+						  &tf->goto_queue[i]);
+	  gcc_assert (!existed);
 	}
     }
 
-  slot = pointer_map_contains (tf->goto_queue_map, stmt.g);
+  goto_queue_node **slot = tf->goto_queue_map->get (stmt.g);
   if (slot != NULL)
-    return (((struct goto_queue_node *) *slot)->repl_stmt);
+    return ((*slot)->repl_stmt);
 
   return NULL;
 }
@@ -1372,7 +1370,7 @@  lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
   tree tmp;
   gimple switch_stmt;
   gimple_seq finally;
-  struct pointer_map_t *cont_map = NULL;
+  hash_map<tree, gimple> *cont_map = NULL;
   /* The location of the TRY_FINALLY stmt.  */
   location_t tf_loc = gimple_location (tf->try_finally_expr);
   /* The location of the finally block.  */
@@ -1511,32 +1509,27 @@  lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
       if (case_label_vec.length () <= case_index || !case_label_vec[case_index])
         {
           tree case_lab;
-          void **slot;
 	  tmp = build_int_cst (integer_type_node, switch_id);
           case_lab = build_case_label (tmp, NULL,
 				       create_artificial_label (tf_loc));
           /* We store the cont_stmt in the pointer map, so that we can recover
              it in the loop below.  */
           if (!cont_map)
-            cont_map = pointer_map_create ();
-          slot = pointer_map_insert (cont_map, case_lab);
-          *slot = q->cont_stmt;
+            cont_map = new hash_map<tree, gimple>;
+          cont_map->put (case_lab, q->cont_stmt);
           case_label_vec.quick_push (case_lab);
         }
     }
   for (j = last_case_index; j < last_case_index + nlabels; j++)
     {
       gimple cont_stmt;
-      void **slot;
 
       last_case = case_label_vec[j];
 
       gcc_assert (last_case);
       gcc_assert (cont_map);
 
-      slot = pointer_map_contains (cont_map, last_case);
-      gcc_assert (slot);
-      cont_stmt = *(gimple *) slot;
+      cont_stmt = *cont_map->get (last_case);
 
       x = gimple_build_label (CASE_LABEL (last_case));
       gimple_seq_add_stmt (&switch_body, x);
@@ -1544,7 +1537,7 @@  lower_try_finally_switch (struct leh_state *state, struct leh_tf_state *tf)
       maybe_record_in_goto_queue (state, cont_stmt);
     }
   if (cont_map)
-    pointer_map_destroy (cont_map);
+    delete cont_map;
 
   replace_goto_queue (tf);
 
@@ -1734,7 +1727,7 @@  lower_try_finally (struct leh_state *state, gimple tp)
   this_tf.dest_array.release ();
   free (this_tf.goto_queue);
   if (this_tf.goto_queue_map)
-    pointer_map_destroy (this_tf.goto_queue_map);
+    delete this_tf.goto_queue_map;
 
   /* If there was an old (aka outer) eh_seq, append the current eh_seq.
      If there was no old eh_seq, then the append is trivially already done.  */
@@ -2921,10 +2914,10 @@  maybe_clean_or_replace_eh_stmt (gimple old_stmt, gimple new_stmt)
 bool
 maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
 			    struct function *old_fun, gimple old_stmt,
-			    struct pointer_map_t *map, int default_lp_nr)
+			    hash_map<void *, void *> *map,
+			    int default_lp_nr)
 {
   int old_lp_nr, new_lp_nr;
-  void **slot;
 
   if (!stmt_could_throw_p (new_stmt))
     return false;
@@ -2941,8 +2934,7 @@  maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
       eh_landing_pad old_lp, new_lp;
 
       old_lp = (*old_fun->eh->lp_array)[old_lp_nr];
-      slot = pointer_map_contains (map, old_lp);
-      new_lp = (eh_landing_pad) *slot;
+      new_lp = static_cast<eh_landing_pad> (*map->get (old_lp));
       new_lp_nr = new_lp->index;
     }
   else
@@ -2950,8 +2942,7 @@  maybe_duplicate_eh_stmt_fn (struct function *new_fun, gimple new_stmt,
       eh_region old_r, new_r;
 
       old_r = (*old_fun->eh->region_array)[-old_lp_nr];
-      slot = pointer_map_contains (map, old_r);
-      new_r = (eh_region) *slot;
+      new_r = static_cast<eh_region> (*map->get (old_r));
       new_lp_nr = -new_r->index;
     }
 
@@ -3154,7 +3145,7 @@  make_pass_refactor_eh (gcc::context *ctxt)
 /* At the end of gimple optimization, we can lower RESX.  */
 
 static bool
-lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
+lower_resx (basic_block bb, gimple stmt, hash_map<eh_region, tree> *mnt_map)
 {
   int lp_nr;
   eh_region src_r, dst_r;
@@ -3199,14 +3190,13 @@  lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
       if (lp_nr < 0)
 	{
 	  basic_block new_bb;
-	  void **slot;
 	  tree lab;
 
 	  /* We are resuming into a MUST_NOT_CALL region.  Expand a call to
 	     the failure decl into a new block, if needed.  */
 	  gcc_assert (dst_r->type == ERT_MUST_NOT_THROW);
 
-	  slot = pointer_map_contains (mnt_map, dst_r);
+	  tree *slot = mnt_map->get (dst_r);
 	  if (slot == NULL)
 	    {
 	      gimple_stmt_iterator gsi2;
@@ -3221,12 +3211,11 @@  lower_resx (basic_block bb, gimple stmt, struct pointer_map_t *mnt_map)
 	      gimple_set_location (x, dst_r->u.must_not_throw.failure_loc);
 	      gsi_insert_after (&gsi2, x, GSI_CONTINUE_LINKING);
 
-	      slot = pointer_map_insert (mnt_map, dst_r);
-	      *slot = lab;
+	      mnt_map->put (dst_r, lab);
 	    }
 	  else
 	    {
-	      lab = (tree) *slot;
+	      lab = *slot;
 	      new_bb = label_to_block (lab);
 	    }
 
@@ -3334,24 +3323,21 @@  unsigned
 pass_lower_resx::execute (function *fun)
 {
   basic_block bb;
-  struct pointer_map_t *mnt_map;
   bool dominance_invalidated = false;
   bool any_rewritten = false;
 
-  mnt_map = pointer_map_create ();
+  hash_map<eh_region, tree> mnt_map;
 
   FOR_EACH_BB_FN (bb, fun)
     {
       gimple last = last_stmt (bb);
       if (last && is_gimple_resx (last))
 	{
-	  dominance_invalidated |= lower_resx (bb, last, mnt_map);
+	  dominance_invalidated |= lower_resx (bb, last, &mnt_map);
 	  any_rewritten = true;
 	}
     }
 
-  pointer_map_destroy (mnt_map);
-
   if (dominance_invalidated)
     {
       free_dominance_info (CDI_DOMINATORS);
diff --git a/gcc/tree-eh.h b/gcc/tree-eh.h
index cd9b40d..51c2adc 100644
--- a/gcc/tree-eh.h
+++ b/gcc/tree-eh.h
@@ -20,6 +20,10 @@  along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_TREE_EH_H
 #define GCC_TREE_EH_H
 
+#include "hash-map.h"
+
+typedef struct eh_region_d *eh_region;
+
 extern void using_eh_for_cleanups (void);
 extern void add_stmt_to_eh_lp (gimple, int);
 extern bool remove_stmt_from_eh_lp_fn (struct function *, gimple);
@@ -43,7 +47,7 @@  extern bool maybe_clean_eh_stmt (gimple);
 extern bool maybe_clean_or_replace_eh_stmt (gimple, gimple);
 extern bool maybe_duplicate_eh_stmt_fn (struct function *, gimple,
 					struct function *, gimple,
-					struct pointer_map_t *, int);
+					hash_map<void *, void *> *, int);
 extern bool maybe_duplicate_eh_stmt (gimple, gimple);
 extern void maybe_remove_unreachable_handlers (void);
 extern bool verify_eh_edges (gimple);
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 6af4912..e2b7990 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -135,7 +135,7 @@  static tree declare_return_variable (copy_body_data *, tree, tree, basic_block);
 static void remap_block (tree *, copy_body_data *);
 static void copy_bind_expr (tree *, int *, copy_body_data *);
 static void declare_inline_vars (tree, tree);
-static void remap_save_expr (tree *, void *, int *);
+static void remap_save_expr (tree *, hash_map<tree, tree> *, int *);
 static void prepend_lexical_block (tree current_block, tree new_block);
 static tree copy_decl_to_var (tree, copy_body_data *);
 static tree copy_result_decl_to_var (tree, copy_body_data *);
@@ -149,12 +149,12 @@  static bool delete_unreachable_blocks_update_callgraph (copy_body_data *id);
 void
 insert_decl_map (copy_body_data *id, tree key, tree value)
 {
-  *pointer_map_insert (id->decl_map, key) = value;
+  id->decl_map->put (key, value);
 
   /* Always insert an identity map as well.  If we see this same new
      node again, we won't want to duplicate it a second time.  */
   if (key != value)
-    *pointer_map_insert (id->decl_map, value) = value;
+    id->decl_map->put (value, value);
 }
 
 /* Insert a tree->tree mapping for ID.  This is only used for
@@ -176,9 +176,9 @@  insert_debug_decl_map (copy_body_data *id, tree key, tree value)
   gcc_assert (TREE_CODE (value) == VAR_DECL);
 
   if (!id->debug_map)
-    id->debug_map = pointer_map_create ();
+    id->debug_map = new hash_map<tree, tree>;
 
-  *pointer_map_insert (id->debug_map, key) = value;
+  id->debug_map->put (key, value);
 }
 
 /* If nonzero, we're remapping the contents of inlined debug
@@ -197,7 +197,7 @@  remap_ssa_name (tree name, copy_body_data *id)
 
   gcc_assert (TREE_CODE (name) == SSA_NAME);
 
-  n = (tree *) pointer_map_contains (id->decl_map, name);
+  n = id->decl_map->get (name);
   if (n)
     return unshare_expr (*n);
 
@@ -213,7 +213,7 @@  remap_ssa_name (tree name, copy_body_data *id)
 	  gimple_stmt_iterator gsi;
 	  tree val = SSA_NAME_VAR (name);
 
-	  n = (tree *) pointer_map_contains (id->decl_map, val);
+	  n = id->decl_map->get (val);
 	  if (n != NULL)
 	    val = *n;
 	  if (TREE_CODE (val) != PARM_DECL)
@@ -342,7 +342,7 @@  remap_decl (tree decl, copy_body_data *id)
 
   /* See if we have remapped this declaration.  */
 
-  n = (tree *) pointer_map_contains (id->decl_map, decl);
+  n = id->decl_map->get (decl);
 
   if (!n && processing_debug_stmt)
     {
@@ -562,7 +562,7 @@  remap_type (tree type, copy_body_data *id)
     return type;
 
   /* See if we have remapped this type.  */
-  node = (tree *) pointer_map_contains (id->decl_map, type);
+  node = id->decl_map->get (type);
   if (node)
     return *node;
 
@@ -887,7 +887,7 @@  remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
     {
       /* If the enclosing record type is variably_modified_type_p, the field
 	 has already been remapped.  Otherwise, it need not be.  */
-      tree *n = (tree *) pointer_map_contains (id->decl_map, *tp);
+      tree *n = id->decl_map->get (*tp);
       if (n)
 	*tp = *n;
       *walk_subtrees = 0;
@@ -981,8 +981,7 @@  remap_gimple_op_r (tree *tp, int *walk_subtrees, void *data)
       if (old_block)
 	{
 	  tree *n;
-	  n = (tree *) pointer_map_contains (id->decl_map,
-					     TREE_BLOCK (*tp));
+	  n = id->decl_map->get (TREE_BLOCK (*tp));
 	  if (n)
 	    new_block = *n;
 	}
@@ -1108,7 +1107,7 @@  copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
 	  tree decl = TREE_OPERAND (*tp, 0), value;
 	  tree *n;
 
-	  n = (tree *) pointer_map_contains (id->decl_map, decl);
+	  n = id->decl_map->get (decl);
 	  if (n)
 	    {
 	      value = *n;
@@ -1125,7 +1124,7 @@  copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
 	  /* Get rid of *& from inline substitutions that can happen when a
 	     pointer argument is an ADDR_EXPR.  */
 	  tree decl = TREE_OPERAND (*tp, 0);
-	  tree *n = (tree *) pointer_map_contains (id->decl_map, decl);
+	  tree *n = id->decl_map->get (decl);
 	  if (n)
 	    {
 	      /* If we happen to get an ADDR_EXPR in n->value, strip
@@ -1206,8 +1205,7 @@  copy_tree_body_r (tree *tp, int *walk_subtrees, void *data)
 	  if (TREE_BLOCK (*tp))
 	    {
 	      tree *n;
-	      n = (tree *) pointer_map_contains (id->decl_map,
-						 TREE_BLOCK (*tp));
+	      n = id->decl_map->get (TREE_BLOCK (*tp));
 	      if (n)
 		new_block = *n;
 	    }
@@ -1261,11 +1259,9 @@  static int
 remap_eh_region_nr (int old_nr, copy_body_data *id)
 {
   eh_region old_r, new_r;
-  void **slot;
 
   old_r = get_eh_region_from_number_fn (id->src_cfun, old_nr);
-  slot = pointer_map_contains (id->eh_map, old_r);
-  new_r = (eh_region) *slot;
+  new_r = static_cast<eh_region> (*id->eh_map->get (old_r));
 
   return new_r->index;
 }
@@ -1483,7 +1479,7 @@  remap_gimple_stmt (gimple stmt, copy_body_data *id)
 	  tree decl = gimple_assign_lhs (stmt), value;
 	  tree *n;
 
-	  n = (tree *) pointer_map_contains (id->decl_map, decl);
+	  n = id->decl_map->get (decl);
 	  if (n)
 	    {
 	      value = *n;
@@ -1597,7 +1593,7 @@  remap_gimple_stmt (gimple stmt, copy_body_data *id)
   if (gimple_block (copy))
     {
       tree *n;
-      n = (tree *) pointer_map_contains (id->decl_map, gimple_block (copy));
+      n = id->decl_map->get (gimple_block (copy));
       gcc_assert (n);
       gimple_set_block (copy, *n);
     }
@@ -2191,8 +2187,7 @@  copy_phis_for_bb (basic_block bb, copy_body_data *id)
 	      if (LOCATION_BLOCK (locus))
 		{
 		  tree *n;
-		  n = (tree *) pointer_map_contains (id->decl_map,
-			LOCATION_BLOCK (locus));
+		  n = id->decl_map->get (LOCATION_BLOCK (locus));
 		  gcc_assert (n);
 		  if (*n)
 		    locus = COMBINE_LOCATION_DATA (line_table, locus, *n);
@@ -2638,7 +2633,7 @@  copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
 
   if (id->eh_map)
     {
-      pointer_map_destroy (id->eh_map);
+      delete id->eh_map;
       id->eh_map = NULL;
     }
 
@@ -2659,7 +2654,7 @@  copy_debug_stmt (gimple stmt, copy_body_data *id)
 
   if (gimple_block (stmt))
     {
-      n = (tree *) pointer_map_contains (id->decl_map, gimple_block (stmt));
+      n = id->decl_map->get (gimple_block (stmt));
       gimple_set_block (stmt, n ? *n : id->block);
     }
 
@@ -2675,14 +2670,14 @@  copy_debug_stmt (gimple stmt, copy_body_data *id)
     t = gimple_debug_bind_get_var (stmt);
 
   if (TREE_CODE (t) == PARM_DECL && id->debug_map
-      && (n = (tree *) pointer_map_contains (id->debug_map, t)))
+      && (n = id->debug_map->get (t)))
     {
       gcc_assert (TREE_CODE (*n) == VAR_DECL);
       t = *n;
     }
   else if (TREE_CODE (t) == VAR_DECL
 	   && !is_global_var (t)
-	   && !pointer_map_contains (id->decl_map, t))
+	   && !id->decl_map->get (t))
     /* T is a non-localized variable.  */;
   else
     walk_tree (&t, remap_gimple_op_r, &wi, NULL);
@@ -3076,7 +3071,7 @@  initialize_inlined_parameters (copy_body_data *id, gimple stmt,
      parameter following the array.  */
   for (p = parms, i = 0; p; p = DECL_CHAIN (p), i++)
     {
-      tree *varp = (tree *) pointer_map_contains (id->decl_map, p);
+      tree *varp = id->decl_map->get (p);
       if (varp
 	  && TREE_CODE (*varp) == VAR_DECL)
 	{
@@ -3089,7 +3084,7 @@  initialize_inlined_parameters (copy_body_data *id, gimple stmt,
 	     by the parameter setup.  */
 	  if (def)
 	    {
-	      tree *defp = (tree *) pointer_map_contains (id->decl_map, def);
+	      tree *defp = id->decl_map->get (def);
 	      if (defp
 		  && TREE_CODE (*defp) == SSA_NAME
 		  && SSA_NAME_VAR (*defp) == var)
@@ -4135,7 +4130,8 @@  expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
 {
   tree use_retvar;
   tree fn;
-  struct pointer_map_t *st, *dst;
+  hash_map<tree, tree> *dst;
+  hash_map<tree, tree> *st = NULL;
   tree return_slot;
   tree modify_dest;
   location_t saved_location;
@@ -4291,7 +4287,7 @@  expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
   /* Local declarations will be replaced by their equivalents in this
      map.  */
   st = id->decl_map;
-  id->decl_map = pointer_map_create ();
+  id->decl_map = new hash_map<tree, tree>;
   dst = id->debug_map;
   id->debug_map = NULL;
 
@@ -4415,10 +4411,10 @@  expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
   /* Clean up.  */
   if (id->debug_map)
     {
-      pointer_map_destroy (id->debug_map);
+      delete id->debug_map;
       id->debug_map = dst;
     }
-  pointer_map_destroy (id->decl_map);
+  delete id->decl_map;
   id->decl_map = st;
 
   /* Unlink the calls virtual operands before replacing it.  */
@@ -4772,14 +4768,13 @@  copy_tree_r (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED)
    the function into which the copy will be placed.  */
 
 static void
-remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
+remap_save_expr (tree *tp, hash_map<tree, tree> *st, int *walk_subtrees)
 {
-  struct pointer_map_t *st = (struct pointer_map_t *) st_;
   tree *n;
   tree t;
 
   /* See if we already encountered this SAVE_EXPR.  */
-  n = (tree *) pointer_map_contains (st, *tp);
+  n = st->get (*tp);
 
   /* If we didn't already remap this SAVE_EXPR, do so now.  */
   if (!n)
@@ -4787,9 +4782,9 @@  remap_save_expr (tree *tp, void *st_, int *walk_subtrees)
       t = copy_node (*tp);
 
       /* Remember this SAVE_EXPR.  */
-      *pointer_map_insert (st, *tp) = t;
+      st->put (*tp, t);
       /* Make sure we don't remap an already-remapped SAVE_EXPR.  */
-      *pointer_map_insert (st, t) = t;
+      st->put (t, t);
     }
   else
     {
@@ -4836,7 +4831,7 @@  replace_locals_op (tree *tp, int *walk_subtrees, void *data)
 {
   struct walk_stmt_info *wi = (struct walk_stmt_info*) data;
   copy_body_data *id = (copy_body_data *) wi->info;
-  struct pointer_map_t *st = id->decl_map;
+  hash_map<tree, tree> *st = id->decl_map;
   tree *n;
   tree expr = *tp;
 
@@ -4846,7 +4841,7 @@  replace_locals_op (tree *tp, int *walk_subtrees, void *data)
       || TREE_CODE (expr) == LABEL_DECL)
     {
       /* Lookup the declaration.  */
-      n = (tree *) pointer_map_contains (st, expr);
+      n = st->get (expr);
 
       /* If it's there, remap it.  */
       if (n)
@@ -4928,7 +4923,7 @@  copy_gimple_seq_and_replace_locals (gimple_seq seq)
   memset (&id, 0, sizeof (id));
   id.src_fn = current_function_decl;
   id.dst_fn = current_function_decl;
-  id.decl_map = pointer_map_create ();
+  id.decl_map = new hash_map<tree, tree>;
   id.debug_map = NULL;
 
   id.copy_decl = copy_decl_no_change;
@@ -4953,9 +4948,9 @@  copy_gimple_seq_and_replace_locals (gimple_seq seq)
   walk_gimple_seq (copy, replace_locals_stmt, replace_locals_op, &wi);
 
   /* Clean up.  */
-  pointer_map_destroy (id.decl_map);
+  delete id.decl_map;
   if (id.debug_map)
-    pointer_map_destroy (id.debug_map);
+    delete id.debug_map;
 
   return copy;
 }
@@ -5145,7 +5140,7 @@  copy_arguments_for_versioning (tree orig_parm, copy_body_data * id,
         *parg = new_tree;
 	parg = &DECL_CHAIN (new_tree);
       }
-    else if (!pointer_map_contains (id->decl_map, arg))
+    else if (!id->decl_map->get (arg))
       {
 	/* Make an equivalent VAR_DECL.  If the argument was used
 	   as temporary variable later in function, the uses will be
@@ -5368,7 +5363,7 @@  tree_function_versioning (tree old_decl, tree new_decl,
   /* Generate a new name for the new version. */
   id.statements_to_fold = new hash_set<gimple>;
 
-  id.decl_map = pointer_map_create ();
+  id.decl_map = new hash_map<tree, tree>;
   id.debug_map = NULL;
   id.src_fn = old_decl;
   id.dst_fn = new_decl;
@@ -5530,9 +5525,9 @@  tree_function_versioning (tree old_decl, tree new_decl,
     }
 
   /* Clean up.  */
-  pointer_map_destroy (id.decl_map);
+  delete id.decl_map;
   if (id.debug_map)
-    pointer_map_destroy (id.debug_map);
+    delete id.debug_map;
   free_dominance_info (CDI_DOMINATORS);
   free_dominance_info (CDI_POST_DOMINATORS);
 
@@ -5587,22 +5582,22 @@  maybe_inline_call_in_expr (tree exp)
   /* We can only try to inline "const" functions.  */
   if (fn && TREE_READONLY (fn) && DECL_SAVED_TREE (fn))
     {
-      struct pointer_map_t *decl_map = pointer_map_create ();
       call_expr_arg_iterator iter;
       copy_body_data id;
       tree param, arg, t;
+      hash_map<tree, tree> decl_map;
 
       /* Remap the parameters.  */
       for (param = DECL_ARGUMENTS (fn), arg = first_call_expr_arg (exp, &iter);
 	   param;
 	   param = DECL_CHAIN (param), arg = next_call_expr_arg (&iter))
-	*pointer_map_insert (decl_map, param) = arg;
+	decl_map.put (param, arg);
 
       memset (&id, 0, sizeof (id));
       id.src_fn = fn;
       id.dst_fn = current_function_decl;
       id.src_cfun = DECL_STRUCT_FUNCTION (fn);
-      id.decl_map = decl_map;
+      id.decl_map = &decl_map;
 
       id.copy_decl = copy_decl_no_change;
       id.transform_call_graph_edges = CB_CGE_DUPLICATE;
@@ -5620,7 +5615,6 @@  maybe_inline_call_in_expr (tree exp)
       id.eh_lp_nr = 0;
 
       t = copy_tree_body (&id);
-      pointer_map_destroy (decl_map);
 
       /* We can only return something suitable for use in a GENERIC
 	 expression tree.  */
@@ -5642,15 +5636,15 @@  build_duplicate_type (tree type)
   id.src_fn = current_function_decl;
   id.dst_fn = current_function_decl;
   id.src_cfun = cfun;
-  id.decl_map = pointer_map_create ();
+  id.decl_map = new hash_map<tree, tree>;
   id.debug_map = NULL;
   id.copy_decl = copy_decl_no_change;
 
   type = remap_type_1 (type, &id);
 
-  pointer_map_destroy (id.decl_map);
+  delete id.decl_map;
   if (id.debug_map)
-    pointer_map_destroy (id.debug_map);
+    delete id.debug_map;
 
   TYPE_CANONICAL (type) = type;
 
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index c13e6c7..53059da 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -21,6 +21,7 @@  along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_TREE_INLINE_H
 #define GCC_TREE_INLINE_H
 
+#include "hash-map.h"
 #include "hash-set.h"
 
 struct cgraph_edge;
@@ -64,7 +65,7 @@  struct copy_body_data
 
   /* The map from local declarations in the inlined function to
      equivalents in the function into which it is being inlined.  */
-  struct pointer_map_t *decl_map;
+  hash_map<tree, tree> *decl_map;
 
   /* Create a new decl to replace DECL in the destination function.  */
   tree (*copy_decl) (tree, struct copy_body_data *);
@@ -81,7 +82,7 @@  struct copy_body_data
 
   /* Maps region and landing pad structures from the function being copied
      to duplicates created within the function we inline into.  */
-  struct pointer_map_t *eh_map;
+  hash_map<void *, void *> *eh_map;
 
   /* We use the same mechanism do all sorts of different things.  Rather
      than enumerating the different cases, we categorize the behavior
@@ -132,7 +133,7 @@  struct copy_body_data
      equivalents in the function into which it is being inlined, where
      the originals have been mapped to a value rather than to a
      variable.  */
-  struct pointer_map_t *debug_map;
+  hash_map<tree, tree> *debug_map;
  
   /* Cilk keywords currently need to replace some variables that
      ordinary nested functions do not.  */ 
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index 45c5cf7..7d5c039 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -93,8 +93,8 @@  struct nesting_info
   struct nesting_info *inner;
   struct nesting_info *next;
 
-  struct pointer_map_t *field_map;
-  struct pointer_map_t *var_map;
+  hash_map<tree, tree> *field_map;
+  hash_map<tree, tree> *var_map;
   hash_set<tree *> *mem_refs;
   bitmap suppress_expansion;
 
@@ -286,15 +286,13 @@  static tree
 lookup_field_for_decl (struct nesting_info *info, tree decl,
 		       enum insert_option insert)
 {
-  void **slot;
-
   if (insert == NO_INSERT)
     {
-      slot = pointer_map_contains (info->field_map, decl);
-      return slot ? (tree) *slot : NULL_TREE;
+      tree *slot = info->field_map->get (decl);
+      return slot ? *slot : NULL_TREE;
     }
 
-  slot = pointer_map_insert (info->field_map, decl);
+  tree *slot = &info->field_map->get_or_insert (decl);
   if (!*slot)
     {
       tree field = make_node (FIELD_DECL);
@@ -324,7 +322,7 @@  lookup_field_for_decl (struct nesting_info *info, tree decl,
 	info->any_parm_remapped = true;
     }
 
-  return (tree) *slot;
+  return *slot;
 }
 
 /* Build or return the variable that holds the static chain within
@@ -521,15 +519,13 @@  static tree
 lookup_tramp_for_decl (struct nesting_info *info, tree decl,
 		       enum insert_option insert)
 {
-  void **slot;
-
   if (insert == NO_INSERT)
     {
-      slot = pointer_map_contains (info->var_map, decl);
-      return slot ? (tree) *slot : NULL_TREE;
+      tree *slot = info->var_map->get (decl);
+      return slot ? *slot : NULL_TREE;
     }
 
-  slot = pointer_map_insert (info->var_map, decl);
+  tree *slot = &info->var_map->get_or_insert (decl);
   if (!*slot)
     {
       tree field = make_node (FIELD_DECL);
@@ -543,7 +539,7 @@  lookup_tramp_for_decl (struct nesting_info *info, tree decl,
       info->any_tramp_created = true;
     }
 
-  return (tree) *slot;
+  return *slot;
 }
 
 /* Build or return the field within the non-local frame state that holds
@@ -730,8 +726,8 @@  static struct nesting_info *
 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->field_map = new hash_map<tree, tree>;
+  info->var_map = new hash_map<tree, tree>;
   info->mem_refs = new hash_set<tree *>;
   info->suppress_expansion = BITMAP_ALLOC (&nesting_info_bitmap_obstack);
   info->context = cgn->decl;
@@ -834,12 +830,11 @@  get_nonlocal_debug_decl (struct nesting_info *info, tree decl)
   tree target_context;
   struct nesting_info *i;
   tree x, field, new_decl;
-  void **slot;
 
-  slot = pointer_map_insert (info->var_map, decl);
+  tree *slot = &info->var_map->get_or_insert (decl);
 
   if (*slot)
-    return (tree) *slot;
+    return *slot;
 
   target_context = decl_function_context (decl);
 
@@ -1483,11 +1478,10 @@  static tree
 get_local_debug_decl (struct nesting_info *info, tree decl, tree field)
 {
   tree x, new_decl;
-  void **slot;
 
-  slot = pointer_map_insert (info->var_map, decl);
+  tree *slot = &info->var_map->get_or_insert (decl);
   if (*slot)
-    return (tree) *slot;
+    return *slot;
 
   /* Make sure frame_decl gets created.  */
   (void) get_frame_type (info);
@@ -2064,7 +2058,6 @@  convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 {
   struct nesting_info *const info = (struct nesting_info *) wi->info, *i;
   tree label, new_label, target_context, x, field;
-  void **slot;
   gimple call;
   gimple stmt = gsi_stmt (*gsi);
 
@@ -2098,7 +2091,7 @@  convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
      (hairy target-specific) non-local goto receiver code to be generated
      when we expand rtl.  Enter this association into var_map so that we
      can insert the new label into the IL during a second pass.  */
-  slot = pointer_map_insert (i->var_map, label);
+  tree *slot = &i->var_map->get_or_insert (label);
   if (*slot == NULL)
     {
       new_label = create_artificial_label (UNKNOWN_LOCATION);
@@ -2106,7 +2099,7 @@  convert_nl_goto_reference (gimple_stmt_iterator *gsi, bool *handled_ops_p,
       *slot = new_label;
     }
   else
-    new_label = (tree) *slot;
+    new_label = *slot;
 
   /* Build: __builtin_nl_goto(new_label, &chain->nl_goto_field).  */
   field = get_nl_goto_field (i);
@@ -2136,7 +2129,6 @@  convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
   struct nesting_info *const info = (struct nesting_info *) wi->info;
   tree label, new_label;
   gimple_stmt_iterator tmp_gsi;
-  void **slot;
   gimple stmt = gsi_stmt (*gsi);
 
   if (gimple_code (stmt) != GIMPLE_LABEL)
@@ -2147,7 +2139,7 @@  convert_nl_goto_receiver (gimple_stmt_iterator *gsi, bool *handled_ops_p,
 
   label = gimple_label_label (stmt);
 
-  slot = pointer_map_contains (info->var_map, label);
+  tree *slot = info->var_map->get (label);
   if (!slot)
     {
       *handled_ops_p = false;
@@ -2513,7 +2505,7 @@  static tree
 nesting_copy_decl (tree decl, copy_body_data *id)
 {
   struct nesting_copy_body_data *nid = (struct nesting_copy_body_data *) id;
-  void **slot = pointer_map_contains (nid->root->var_map, decl);
+  tree *slot = nid->root->var_map->get (decl);
 
   if (slot)
     return (tree) *slot;
@@ -2542,15 +2534,14 @@  contains_remapped_vars (tree *tp, int *walk_subtrees, void *data)
 {
   struct nesting_info *root = (struct nesting_info *) data;
   tree t = *tp;
-  void **slot;
 
   if (DECL_P (t))
     {
       *walk_subtrees = 0;
-      slot = pointer_map_contains (root->var_map, t);
+      tree *slot = root->var_map->get (t);
 
       if (slot)
-	return (tree) *slot;
+	return *slot;
     }
   return NULL;
 }
@@ -2580,7 +2571,7 @@  remap_vla_decls (tree block, struct nesting_info *root)
 	      && variably_modified_type_p (type, NULL)))
 	  continue;
 
-	if (pointer_map_contains (root->var_map, TREE_OPERAND (val, 0))
+	if (root->var_map->get (TREE_OPERAND (val, 0))
 	    || walk_tree (&type, contains_remapped_vars, root, NULL))
 	  break;
       }
@@ -2590,7 +2581,7 @@  remap_vla_decls (tree block, struct nesting_info *root)
 
   memset (&id, 0, sizeof (id));
   id.cb.copy_decl = nesting_copy_decl;
-  id.cb.decl_map = pointer_map_create ();
+  id.cb.decl_map = new hash_map<tree, tree>;
   id.root = root;
 
   for (; var; var = DECL_CHAIN (var))
@@ -2598,7 +2589,6 @@  remap_vla_decls (tree block, struct nesting_info *root)
       {
 	struct nesting_info *i;
 	tree newt, context;
-	void **slot;
 
 	val = DECL_VALUE_EXPR (var);
 	type = TREE_TYPE (var);
@@ -2608,7 +2598,7 @@  remap_vla_decls (tree block, struct nesting_info *root)
 	      && variably_modified_type_p (type, NULL)))
 	  continue;
 
-	slot = pointer_map_contains (root->var_map, TREE_OPERAND (val, 0));
+	tree *slot = root->var_map->get (TREE_OPERAND (val, 0));
 	if (!slot && !walk_tree (&type, contains_remapped_vars, root, NULL))
 	  continue;
 
@@ -2651,7 +2641,7 @@  remap_vla_decls (tree block, struct nesting_info *root)
 	  SET_DECL_VALUE_EXPR (var, val);
       }
 
-  pointer_map_destroy (id.cb.decl_map);
+  delete id.cb.decl_map;
 }
 
 /* Fold the MEM_REF *E.  */
@@ -2830,7 +2820,7 @@  finalize_nesting_tree_1 (struct nesting_info *root)
 
 	  memset (&id, 0, sizeof (id));
 	  id.cb.copy_decl = nesting_copy_decl;
-	  id.cb.decl_map = pointer_map_create ();
+	  id.cb.decl_map = new hash_map<tree, tree>;
 	  id.root = root;
 
 	  for (; debug_var; debug_var = DECL_CHAIN (debug_var))
@@ -2865,7 +2855,7 @@  finalize_nesting_tree_1 (struct nesting_info *root)
 		  TYPE_NAME (newt) = remap_decl (TYPE_NAME (newt), &id.cb);
 	      }
 
-	  pointer_map_destroy (id.cb.decl_map);
+	  delete id.cb.decl_map;
 	}
 
       scope = gimple_seq_first_stmt (gimple_body (root->context));
@@ -2931,8 +2921,8 @@  free_nesting_tree (struct nesting_info *root)
   do
     {
       next = iter_nestinfo_next (node);
-      pointer_map_destroy (node->var_map);
-      pointer_map_destroy (node->field_map);
+      delete node->var_map;
+      delete node->field_map;
       delete node->mem_refs;
       free (node);
       node = next;
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index f9d39ac..2231314 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -74,11 +74,11 @@  along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "hash-map.h"
 #include "hash-table.h"
 #include "alloc-pool.h"
 #include "tm.h"
 #include "tree.h"
-#include "pointer-set.h"
 #include "basic-block.h"
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
@@ -290,7 +290,7 @@  struct assign_link
 static alloc_pool link_pool;
 
 /* Base (tree) -> Vector (vec<access_p> *) map.  */
-static struct pointer_map_t *base_access_vec;
+static hash_map<tree, auto_vec<access_p> > *base_access_vec;
 
 /* Candidate hash table helpers.  */
 
@@ -518,13 +518,7 @@  access_has_replacements_p (struct access *acc)
 static vec<access_p> *
 get_base_access_vector (tree base)
 {
-  void **slot;
-
-  slot = pointer_map_contains (base_access_vec, base);
-  if (!slot)
-    return NULL;
-  else
-    return *(vec<access_p> **) slot;
+  return base_access_vec->get (base);
 }
 
 /* Find an access with required OFFSET and SIZE in a subtree of accesses rooted
@@ -667,24 +661,13 @@  sra_initialize (void)
   gcc_obstack_init (&name_obstack);
   access_pool = create_alloc_pool ("SRA accesses", sizeof (struct access), 16);
   link_pool = create_alloc_pool ("SRA links", sizeof (struct assign_link), 16);
-  base_access_vec = pointer_map_create ();
+  base_access_vec = new hash_map<tree, auto_vec<access_p> >;
   memset (&sra_stats, 0, sizeof (sra_stats));
   encountered_apply_args = false;
   encountered_recursive_call = false;
   encountered_unchangable_recursive_call = false;
 }
 
-/* Hook fed to pointer_map_traverse, deallocate stored vectors.  */
-
-static bool
-delete_base_accesses (const void *key ATTRIBUTE_UNUSED, void **value,
-		     void *data ATTRIBUTE_UNUSED)
-{
-  vec<access_p> *access_vec = (vec<access_p> *) *value;
-  vec_free (access_vec);
-  return true;
-}
-
 /* Deallocate all general structures.  */
 
 static void
@@ -699,8 +682,7 @@  sra_deinitialize (void)
   free_alloc_pool (link_pool);
   obstack_free (&name_obstack, NULL);
 
-  pointer_map_traverse (base_access_vec, delete_base_accesses, NULL);
-  pointer_map_destroy (base_access_vec);
+  delete base_access_vec;
 }
 
 /* Remove DECL from candidates for SRA and write REASON to the dump file if
@@ -849,9 +831,7 @@  mark_parm_dereference (tree base, HOST_WIDE_INT dist, gimple stmt)
 static struct access *
 create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
 {
-  vec<access_p> *v;
   struct access *access;
-  void **slot;
 
   access = (struct access *) pool_alloc (access_pool);
   memset (access, 0, sizeof (struct access));
@@ -859,16 +839,7 @@  create_access_1 (tree base, HOST_WIDE_INT offset, HOST_WIDE_INT size)
   access->offset = offset;
   access->size = size;
 
-  slot = pointer_map_contains (base_access_vec, base);
-  if (slot)
-    v = (vec<access_p> *) *slot;
-  else
-    vec_alloc (v, 32);
-
-  v->safe_push (access);
-
-  *((vec<access_p> **)
-	pointer_map_insert (base_access_vec, base)) = v;
+  base_access_vec->get_or_insert (base).safe_push (access);
 
   return access;
 }
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index c614978..0cbb3ae 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -26,6 +26,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "basic-block.h"
 #include "gimple-pretty-print.h"
 #include "pointer-set.h"
+#include "hash-map.h"
 #include "hash-table.h"
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
@@ -103,7 +104,7 @@  struct lim_aux_data
 
 /* Maps statements to their lim_aux_data.  */
 
-static struct pointer_map_t *lim_aux_data_map;
+static hash_map<gimple, lim_aux_data *> *lim_aux_data_map;
 
 /* Description of a memory reference location.  */
 
@@ -225,20 +226,20 @@  static bool ref_indep_loop_p (struct loop *, mem_ref_p);
 static struct lim_aux_data *
 init_lim_data (gimple stmt)
 {
-  void **p = pointer_map_insert (lim_aux_data_map, stmt);
+  lim_aux_data *p = XCNEW (struct lim_aux_data);
+  lim_aux_data_map->put (stmt, p);
 
-  *p = XCNEW (struct lim_aux_data);
-  return (struct lim_aux_data *) *p;
+  return p;
 }
 
 static struct lim_aux_data *
 get_lim_data (gimple stmt)
 {
-  void **p = pointer_map_contains (lim_aux_data_map, stmt);
+  lim_aux_data **p = lim_aux_data_map->get (stmt);
   if (!p)
     return NULL;
 
-  return (struct lim_aux_data *) *p;
+  return *p;
 }
 
 /* Releases the memory occupied by DATA.  */
@@ -253,11 +254,11 @@  free_lim_aux_data (struct lim_aux_data *data)
 static void
 clear_lim_data (gimple stmt)
 {
-  void **p = pointer_map_contains (lim_aux_data_map, stmt);
+  lim_aux_data **p = lim_aux_data_map->get (stmt);
   if (!p)
     return;
 
-  free_lim_aux_data ((struct lim_aux_data *) *p);
+  free_lim_aux_data (*p);
   *p = NULL;
 }
 
@@ -2429,7 +2430,7 @@  tree_ssa_lim_initialize (void)
 
   bitmap_obstack_initialize (&lim_bitmap_obstack);
   gcc_obstack_init (&mem_ref_obstack);
-  lim_aux_data_map = pointer_map_create ();
+  lim_aux_data_map = new hash_map<gimple, lim_aux_data *>;
 
   if (flag_tm)
     compute_transaction_bits ();
@@ -2484,7 +2485,7 @@  tree_ssa_lim_finalize (void)
     SET_ALWAYS_EXECUTED_IN (bb, NULL);
 
   bitmap_obstack_release (&lim_bitmap_obstack);
-  pointer_map_destroy (lim_aux_data_map);
+  delete lim_aux_data_map;
 
   delete memory_accesses.refs;
   memory_accesses.refs = NULL;
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 3b4a6cd..158a081 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -70,7 +70,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "tm_p.h"
 #include "basic-block.h"
 #include "gimple-pretty-print.h"
-#include "pointer-set.h"
+#include "hash-map.h"
 #include "hash-table.h"
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
@@ -293,7 +293,7 @@  struct ivopts_data
   struct loop *current_loop;
 
   /* Numbers of iterations for all exits of the current loop.  */
-  struct pointer_map_t *niters;
+  hash_map<edge, tree_niter_desc *> *niters;
 
   /* Number of registers used in it.  */
   unsigned regs_used;
@@ -814,15 +814,15 @@  static struct tree_niter_desc *
 niter_for_exit (struct ivopts_data *data, edge exit)
 {
   struct tree_niter_desc *desc;
-  void **slot;
+  tree_niter_desc **slot;
 
   if (!data->niters)
     {
-      data->niters = pointer_map_create ();
+      data->niters = new hash_map<edge, tree_niter_desc *>;
       slot = NULL;
     }
   else
-    slot = pointer_map_contains (data->niters, exit);
+    slot = data->niters->get (exit);
 
   if (!slot)
     {
@@ -837,11 +837,10 @@  niter_for_exit (struct ivopts_data *data, edge exit)
 	  XDELETE (desc);
 	  desc = NULL;
 	}
-      slot = pointer_map_insert (data->niters, exit);
-      *slot = desc;
+      data->niters->put (exit, desc);
     }
   else
-    desc = (struct tree_niter_desc *) *slot;
+    desc = *slot;
 
   return desc;
 }
@@ -6704,15 +6703,12 @@  remove_unused_ivs (struct ivopts_data *data)
 }
 
 /* Frees memory occupied by struct tree_niter_desc in *VALUE. Callback
-   for pointer_map_traverse.  */
+   for hash_map::traverse.  */
 
-static bool
-free_tree_niter_desc (const void *key ATTRIBUTE_UNUSED, void **value,
-                      void *data ATTRIBUTE_UNUSED)
+bool
+free_tree_niter_desc (edge const &, tree_niter_desc *const &value, void *)
 {
-  struct tree_niter_desc *const niter = (struct tree_niter_desc *) *value;
-
-  free (niter);
+  free (value);
   return true;
 }
 
@@ -6727,8 +6723,8 @@  free_loop_data (struct ivopts_data *data)
 
   if (data->niters)
     {
-      pointer_map_traverse (data->niters, free_tree_niter_desc, NULL);
-      pointer_map_destroy (data->niters);
+      data->niters->traverse<void *, free_tree_niter_desc> (NULL);
+      delete data->niters;
       data->niters = NULL;
     }
 
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index f9bd9a4..2e8337c 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -30,7 +30,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "basic-block.h"
 #include "gimple-pretty-print.h"
 #include "tree-inline.h"
-#include "pointer-set.h"
+#include "hash-map.h"
 #include "tree-ssa-alias.h"
 #include "internal-fn.h"
 #include "gimple-fold.h"
@@ -216,7 +216,7 @@  static int next_operand_entry_id;
 static long *bb_rank;
 
 /* Operand->rank hashtable.  */
-static struct pointer_map_t *operand_rank;
+static hash_map<tree, long> *operand_rank;
 
 /* Forward decls.  */
 static long get_rank (tree);
@@ -362,8 +362,8 @@  propagate_rank (long rank, tree op)
 static inline long
 find_operand_rank (tree e)
 {
-  void **slot = pointer_map_contains (operand_rank, e);
-  return slot ? (long) (intptr_t) *slot : -1;
+  long *slot = operand_rank->get (e);
+  return slot ? *slot : -1;
 }
 
 /* Insert {E,RANK} into the operand rank hashtable.  */
@@ -371,11 +371,8 @@  find_operand_rank (tree e)
 static inline void
 insert_operand_rank (tree e, long rank)
 {
-  void **slot;
   gcc_assert (rank > 0);
-  slot = pointer_map_insert (operand_rank, e);
-  gcc_assert (!*slot);
-  *slot = (void *) (intptr_t) rank;
+  gcc_assert (!operand_rank->put (e, rank));
 }
 
 /* Given an expression E, return the rank of the expression.  */
@@ -4635,7 +4632,7 @@  init_reassoc (void)
      deeper loops come later.  */
   pre_and_rev_post_order_compute (NULL, bbs, false);
   bb_rank = XCNEWVEC (long, last_basic_block_for_fn (cfun));
-  operand_rank = pointer_map_create ();
+  operand_rank = new hash_map<tree, long>;
 
   /* Give each default definition a distinct rank.  This includes
      parameters and the static chain.  Walk backwards over all
@@ -4676,7 +4673,7 @@  fini_reassoc (void)
   statistics_counter_event (cfun, "Built-in powi calls created",
 			    reassociate_stats.pows_created);
 
-  pointer_map_destroy (operand_rank);
+  delete operand_rank;
   free_alloc_pool (operand_entry_pool);
   free (bb_rank);
   plus_negates.release ();
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index 1879fc0..08e384b 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -319,7 +319,7 @@  static inline bool type_can_have_subvars (const_tree);
 static alloc_pool variable_info_pool;
 
 /* Map varinfo to final pt_solution.  */
-static pointer_map_t *final_solutions;
+static hash_map<varinfo_t, pt_solution *> *final_solutions;
 struct obstack final_solutions_obstack;
 
 /* Table of variable info structures for constraint variables.
@@ -393,19 +393,19 @@  new_var_info (tree t, const char *name)
 
 /* A map mapping call statements to per-stmt variables for uses
    and clobbers specific to the call.  */
-static struct pointer_map_t *call_stmt_vars;
+static hash_map<gimple, varinfo_t> *call_stmt_vars;
 
 /* Lookup or create the variable for the call statement CALL.  */
 
 static varinfo_t
 get_call_vi (gimple call)
 {
-  void **slot_p;
   varinfo_t vi, vi2;
 
-  slot_p = pointer_map_insert (call_stmt_vars, call);
-  if (*slot_p)
-    return (varinfo_t) *slot_p;
+  bool existed;
+  varinfo_t *slot_p = &call_stmt_vars->get_or_insert (call, &existed);
+  if (existed)
+    return *slot_p;
 
   vi = new_var_info (NULL_TREE, "CALLUSED");
   vi->offset = 0;
@@ -421,7 +421,7 @@  get_call_vi (gimple call)
 
   vi->next = vi2->id;
 
-  *slot_p = (void *) vi;
+  *slot_p = vi;
   return vi;
 }
 
@@ -431,11 +431,9 @@  get_call_vi (gimple call)
 static varinfo_t
 lookup_call_use_vi (gimple call)
 {
-  void **slot_p;
-
-  slot_p = pointer_map_contains (call_stmt_vars, call);
+  varinfo_t *slot_p = call_stmt_vars->get (call);
   if (slot_p)
-    return (varinfo_t) *slot_p;
+    return *slot_p;
 
   return NULL;
 }
@@ -2794,7 +2792,7 @@  solve_graph (constraint_graph_t graph)
 }
 
 /* Map from trees to variable infos.  */
-static struct pointer_map_t *vi_for_tree;
+static hash_map<tree, varinfo_t> *vi_for_tree;
 
 
 /* Insert ID as the variable id for tree T in the vi_for_tree map.  */
@@ -2802,10 +2800,8 @@  static struct pointer_map_t *vi_for_tree;
 static void
 insert_vi_for_tree (tree t, varinfo_t vi)
 {
-  void **slot = pointer_map_insert (vi_for_tree, t);
   gcc_assert (vi);
-  gcc_assert (*slot == NULL);
-  *slot = vi;
+  gcc_assert (!vi_for_tree->put (t, vi));
 }
 
 /* Find the variable info for tree T in VI_FOR_TREE.  If T does not
@@ -2814,11 +2810,11 @@  insert_vi_for_tree (tree t, varinfo_t vi)
 static varinfo_t
 lookup_vi_for_tree (tree t)
 {
-  void **slot = pointer_map_contains (vi_for_tree, t);
+  varinfo_t *slot = vi_for_tree->get (t);
   if (slot == NULL)
     return NULL;
 
-  return (varinfo_t) *slot;
+  return *slot;
 }
 
 /* Return a printable name for DECL  */
@@ -2876,11 +2872,11 @@  alias_get_name (tree decl)
 static varinfo_t
 get_vi_for_tree (tree t)
 {
-  void **slot = pointer_map_contains (vi_for_tree, t);
+  varinfo_t *slot = vi_for_tree->get (t);
   if (slot == NULL)
     return get_varinfo (create_variable_info_for (t, alias_get_name (t)));
 
-  return (varinfo_t) *slot;
+  return *slot;
 }
 
 /* Get a scalar constraint expression for a new temporary variable.  */
@@ -6075,7 +6071,6 @@  find_what_var_points_to (varinfo_t orig_vi)
   bitmap finished_solution;
   bitmap result;
   varinfo_t vi;
-  void **slot;
   struct pt_solution *pt;
 
   /* This variable may have been collapsed, let's get the real
@@ -6083,9 +6078,9 @@  find_what_var_points_to (varinfo_t orig_vi)
   vi = get_varinfo (find (orig_vi->id));
 
   /* See if we have already computed the solution and return it.  */
-  slot = pointer_map_insert (final_solutions, vi);
+  pt_solution **slot = &final_solutions->get_or_insert (vi);
   if (*slot != NULL)
-    return *(struct pt_solution *)*slot;
+    return **slot;
 
   *slot = pt = XOBNEW (&final_solutions_obstack, struct pt_solution);
   memset (pt, 0, sizeof (struct pt_solution));
@@ -6685,8 +6680,8 @@  init_alias_vars (void)
 					  sizeof (struct variable_info), 30);
   constraints.create (8);
   varmap.create (8);
-  vi_for_tree = pointer_map_create ();
-  call_stmt_vars = pointer_map_create ();
+  vi_for_tree = new hash_map<tree, varinfo_t>;
+  call_stmt_vars = new hash_map<gimple, varinfo_t>;
 
   memset (&stats, 0, sizeof (stats));
   shared_bitmap_table = new hash_table<shared_bitmap_hasher> (511);
@@ -6694,7 +6689,7 @@  init_alias_vars (void)
 
   gcc_obstack_init (&fake_var_decl_obstack);
 
-  final_solutions = pointer_map_create ();
+  final_solutions = new hash_map<varinfo_t, pt_solution *>;
   gcc_obstack_init (&final_solutions_obstack);
 }
 
@@ -6943,8 +6938,8 @@  delete_points_to_sets (void)
     fprintf (dump_file, "Points to sets created:%d\n",
 	     stats.points_to_sets_created);
 
-  pointer_map_destroy (vi_for_tree);
-  pointer_map_destroy (call_stmt_vars);
+  delete vi_for_tree;
+  delete call_stmt_vars;
   bitmap_obstack_release (&pta_obstack);
   constraints.release ();
 
@@ -6965,7 +6960,7 @@  delete_points_to_sets (void)
 
   obstack_free (&fake_var_decl_obstack, NULL);
 
-  pointer_map_destroy (final_solutions);
+  delete final_solutions;
   obstack_free (&final_solutions_obstack, NULL);
 }
 
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 73a4d1c..217b9fc 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -49,6 +49,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "tree-into-ssa.h"
 #include "tree-ssa.h"
 #include "tree-inline.h"
+#include "hash-map.h"
 #include "hashtab.h"
 #include "tree-pass.h"
 #include "diagnostic-core.h"
@@ -56,7 +57,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "cfgexpand.h"
 
 /* Pointer map of variable mappings, keyed by edge.  */
-static struct pointer_map_t *edge_var_maps;
+static hash_map<edge, auto_vec<edge_var_map> > *edge_var_maps;
 
 
 /* Add a mapping with PHI RESULT and PHI DEF associated with edge E.  */
@@ -64,23 +65,17 @@  static struct pointer_map_t *edge_var_maps;
 void
 redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
 {
-  void **slot;
-  edge_var_map_vector *head;
   edge_var_map new_node;
 
   if (edge_var_maps == NULL)
-    edge_var_maps = pointer_map_create ();
+    edge_var_maps = new hash_map<edge, auto_vec<edge_var_map> >;
 
-  slot = pointer_map_insert (edge_var_maps, e);
-  head = (edge_var_map_vector *) *slot;
-  if (!head)
-    vec_safe_reserve (head, 5);
+  auto_vec<edge_var_map> &slot = edge_var_maps->get_or_insert (e);
   new_node.def = def;
   new_node.result = result;
   new_node.locus = locus;
 
-  vec_safe_push (head, new_node);
-  *slot = head;
+  slot.safe_push (new_node);
 }
 
 
@@ -89,82 +84,51 @@  redirect_edge_var_map_add (edge e, tree result, tree def, source_location locus)
 void
 redirect_edge_var_map_clear (edge e)
 {
-  void **slot;
-  edge_var_map_vector *head;
-
   if (!edge_var_maps)
     return;
 
-  slot = pointer_map_contains (edge_var_maps, e);
+  auto_vec<edge_var_map> *head = edge_var_maps->get (e);
 
-  if (slot)
-    {
-      head = (edge_var_map_vector *) *slot;
-      vec_free (head);
-      *slot = NULL;
-    }
+  if (head)
+    head->release ();
 }
 
 
 /* Duplicate the redirected var mappings in OLDE in NEWE.
 
-   Since we can't remove a mapping, let's just duplicate it.  This assumes a
-   pointer_map can have multiple edges mapping to the same var_map (many to
-   one mapping), since we don't remove the previous mappings.  */
+   This assumes a hash_map can have multiple edges mapping to the same
+   var_map (many to one mapping), since we don't remove the previous mappings.
+   */
 
 void
 redirect_edge_var_map_dup (edge newe, edge olde)
 {
-  void **new_slot, **old_slot;
-  edge_var_map_vector *head;
-
   if (!edge_var_maps)
     return;
 
-  new_slot = pointer_map_insert (edge_var_maps, newe);
-  old_slot = pointer_map_contains (edge_var_maps, olde);
-  if (!old_slot)
+  auto_vec<edge_var_map> *head = edge_var_maps->get (olde);
+  if (!head)
     return;
-  head = (edge_var_map_vector *) *old_slot;
 
-  edge_var_map_vector *new_head = NULL;
-  if (head)
-    new_head = vec_safe_copy (head);
-  else
-    vec_safe_reserve (new_head, 5);
-  *new_slot = new_head;
+  edge_var_maps->get_or_insert (newe).safe_splice (*head);
 }
 
 
 /* Return the variable mappings for a given edge.  If there is none, return
    NULL.  */
 
-edge_var_map_vector *
+vec<edge_var_map> *
 redirect_edge_var_map_vector (edge e)
 {
-  void **slot;
-
   /* Hey, what kind of idiot would... you'd be surprised.  */
   if (!edge_var_maps)
     return NULL;
 
-  slot = pointer_map_contains (edge_var_maps, e);
+  auto_vec<edge_var_map> *slot = edge_var_maps->get (e);
   if (!slot)
     return NULL;
 
-  return (edge_var_map_vector *) *slot;
-}
-
-/* Used by redirect_edge_var_map_destroy to free all memory.  */
-
-static bool
-free_var_map_entry (const void *key ATTRIBUTE_UNUSED,
-		    void **value,
-		    void *data ATTRIBUTE_UNUSED)
-{
-  edge_var_map_vector *head = (edge_var_map_vector *) *value;
-  vec_free (head);
-  return true;
+  return slot;
 }
 
 /* Clear the edge variable mappings.  */
@@ -172,12 +136,8 @@  free_var_map_entry (const void *key ATTRIBUTE_UNUSED,
 void
 redirect_edge_var_map_destroy (void)
 {
-  if (edge_var_maps)
-    {
-      pointer_map_traverse (edge_var_maps, free_var_map_entry, NULL);
-      pointer_map_destroy (edge_var_maps);
-      edge_var_maps = NULL;
-    }
+  delete edge_var_maps;
+  edge_var_maps = NULL;
 }
 
 
@@ -223,12 +183,11 @@  void
 flush_pending_stmts (edge e)
 {
   gimple phi;
-  edge_var_map_vector *v;
   edge_var_map *vm;
   int i;
   gimple_stmt_iterator gsi;
 
-  v = redirect_edge_var_map_vector (e);
+  vec<edge_var_map> *v = redirect_edge_var_map_vector (e);
   if (!v)
     return;
 
diff --git a/gcc/tree-ssa.h b/gcc/tree-ssa.h
index c866206..835686c 100644
--- a/gcc/tree-ssa.h
+++ b/gcc/tree-ssa.h
@@ -35,7 +35,7 @@  typedef vec<edge_var_map, va_heap, vl_embed> edge_var_map_vector;
 extern void redirect_edge_var_map_add (edge, tree, tree, source_location);
 extern void redirect_edge_var_map_clear (edge);
 extern void redirect_edge_var_map_dup (edge, edge);
-extern edge_var_map_vector *redirect_edge_var_map_vector (edge);
+extern vec<edge_var_map> *redirect_edge_var_map_vector (edge);
 extern void redirect_edge_var_map_destroy (void);
 extern edge ssa_redirect_edge (edge, basic_block);
 extern void flush_pending_stmts (edge);
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 00810b9..3b72fce 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -94,6 +94,7 @@ 
 #include "varasm.h"
 #include "stor-layout.h"
 #include "pointer-set.h"
+#include "hash-map.h"
 #include "hash-table.h"
 #include "basic-block.h"
 #include "tm_p.h"
@@ -2019,12 +2020,12 @@  vt_get_canonicalize_base (rtx loc)
 
 /* This caches canonicalized addresses for VALUEs, computed using
    information in the global cselib table.  */
-static struct pointer_map_t *global_get_addr_cache;
+static hash_map<rtx, rtx> *global_get_addr_cache;
 
 /* This caches canonicalized addresses for VALUEs, computed using
    information from the global cache and information pertaining to a
    basic block being analyzed.  */
-static struct pointer_map_t *local_get_addr_cache;
+static hash_map<rtx, rtx> *local_get_addr_cache;
 
 static rtx vt_canonicalize_addr (dataflow_set *, rtx);
 
@@ -2036,13 +2037,13 @@  static rtx
 get_addr_from_global_cache (rtx const loc)
 {
   rtx x;
-  void **slot;
 
   gcc_checking_assert (GET_CODE (loc) == VALUE);
   
-  slot = pointer_map_insert (global_get_addr_cache, loc);
-  if (*slot)
-    return (rtx)*slot;
+  bool existed;
+  rtx *slot = &global_get_addr_cache->get_or_insert (loc, &existed);
+  if (existed)
+    return *slot;
 
   x = canon_rtx (get_addr (loc));
 
@@ -2056,8 +2057,7 @@  get_addr_from_global_cache (rtx const loc)
 	{
 	  /* The table may have moved during recursion, recompute
 	     SLOT.  */
-	  slot = pointer_map_contains (global_get_addr_cache, loc);
-	  *slot = x = nx;
+	  *global_get_addr_cache->get (loc) = x = nx;
 	}
     }
 
@@ -2072,16 +2072,16 @@  static rtx
 get_addr_from_local_cache (dataflow_set *set, rtx const loc)
 {
   rtx x;
-  void **slot;
   decl_or_value dv;
   variable var;
   location_chain l;
 
   gcc_checking_assert (GET_CODE (loc) == VALUE);
   
-  slot = pointer_map_insert (local_get_addr_cache, loc);
-  if (*slot)
-    return (rtx)*slot;
+  bool existed;
+  rtx *slot = &local_get_addr_cache->get_or_insert (loc, &existed);
+  if (existed)
+    return *slot;
 
   x = get_addr_from_global_cache (loc);
   
@@ -2095,7 +2095,7 @@  get_addr_from_local_cache (dataflow_set *set, rtx const loc)
       rtx nx = vt_canonicalize_addr (set, x);
       if (nx != x)
 	{
-	  slot = pointer_map_contains (local_get_addr_cache, loc);
+	  slot = local_get_addr_cache->get (loc);
 	  *slot = x = nx;
 	}
       return x;
@@ -2116,7 +2116,7 @@  get_addr_from_local_cache (dataflow_set *set, rtx const loc)
 	  rtx nx = vt_canonicalize_addr (set, l->loc);
 	  if (x != nx)
 	    {
-	      slot = pointer_map_contains (local_get_addr_cache, loc);
+	      slot = local_get_addr_cache->get (loc);
 	      *slot = x = nx;
 	    }
 	  break;
@@ -2503,11 +2503,10 @@  val_store (dataflow_set *set, rtx val, rtx loc, rtx insn, bool modified)
 
 /* Clear (canonical address) slots that reference X.  */
 
-static bool
-local_get_addr_clear_given_value (const void *v ATTRIBUTE_UNUSED,
-				  void **slot, void *x)
+bool
+local_get_addr_clear_given_value (rtx const &, rtx *slot, rtx x)
 {
-  if (vt_get_canonicalize_base ((rtx)*slot) == x)
+  if (vt_get_canonicalize_base (*slot) == x)
     *slot = NULL;
   return true;
 }
@@ -2530,11 +2529,10 @@  val_reset (dataflow_set *set, decl_or_value dv)
   if (var->onepart == ONEPART_VALUE)
     {
       rtx x = dv_as_value (dv);
-      void **slot;
       
       /* Relationships in the global cache don't change, so reset the
 	 local cache entry only.  */
-      slot = pointer_map_contains (local_get_addr_cache, x);
+      rtx *slot = local_get_addr_cache->get (x);
       if (slot)
 	{
 	  /* If the value resolved back to itself, odds are that other
@@ -2543,8 +2541,8 @@  val_reset (dataflow_set *set, decl_or_value dv)
 	     old X but resolved to something else remain ok as long as
 	     that something else isn't also reset.  */
 	  if (*slot == x)
-	    pointer_map_traverse (local_get_addr_cache,
-				  local_get_addr_clear_given_value, x);
+	    local_get_addr_cache
+	      ->traverse<rtx, local_get_addr_clear_given_value> (x);
 	  *slot = NULL;
 	}
     }
@@ -6660,7 +6658,7 @@  compute_bb_dataflow (basic_block bb)
   dataflow_set_copy (out, in);
 
   if (MAY_HAVE_DEBUG_INSNS)
-    local_get_addr_cache = pointer_map_create ();
+    local_get_addr_cache = new hash_map<rtx, rtx>;
 
   FOR_EACH_VEC_ELT (VTI (bb)->mos, i, mo)
     {
@@ -6943,7 +6941,7 @@  compute_bb_dataflow (basic_block bb)
 
   if (MAY_HAVE_DEBUG_INSNS)
     {
-      pointer_map_destroy (local_get_addr_cache);
+      delete local_get_addr_cache;
       local_get_addr_cache = NULL;
 
       dataflow_set_equiv_regs (out);
@@ -9477,13 +9475,13 @@  vt_emit_notes (void)
       emit_notes_for_differences (BB_HEAD (bb), &cur, &VTI (bb)->in);
 
       if (MAY_HAVE_DEBUG_INSNS)
-	local_get_addr_cache = pointer_map_create ();
+	local_get_addr_cache = new hash_map<rtx, rtx>;
 
       /* Emit the notes for the changes in the basic block itself.  */
       emit_notes_in_bb (bb, &cur);
 
       if (MAY_HAVE_DEBUG_INSNS)
-	pointer_map_destroy (local_get_addr_cache);
+	delete local_get_addr_cache;
       local_get_addr_cache = NULL;
 
       /* Free memory occupied by the in hash table, we won't need it
@@ -9916,7 +9914,7 @@  vt_initialize (void)
       valvar_pool = create_alloc_pool ("small variable_def pool",
 				       sizeof (struct variable_def), 256);
       preserved_values.create (256);
-      global_get_addr_cache = pointer_map_create ();
+      global_get_addr_cache = new hash_map<rtx, rtx>;
     }
   else
     {
@@ -10263,7 +10261,7 @@  vt_finalize (void)
   if (MAY_HAVE_DEBUG_INSNS)
     {
       if (global_get_addr_cache)
-	pointer_map_destroy (global_get_addr_cache);
+	delete global_get_addr_cache;
       global_get_addr_cache = NULL;
       if (loc_exp_dep_pool)
 	free_alloc_pool (loc_exp_dep_pool);