Re: [PATCH] Add some hash_map_safe_* functions like vec_safe_*.

2019-10-02 Thread Jason Merrill

On 10/2/19 4:28 AM, Richard Biener wrote:

On Tue, Oct 1, 2019 at 8:50 PM Jason Merrill  wrote:


On 10/1/19 3:34 AM, Richard Biener wrote:

On Mon, Sep 30, 2019 at 8:33 PM Jason Merrill  wrote:


My comments accidentally got lost.

Several places in the front-end (and elsewhere) use the same lazy
allocation pattern for hash_maps, and this patch replaces them with
hash_map_safe_* functions like vec_safe_*.  They don't provide a way
to specify an initial size, but I don't think that's a significant
issue.

Tested x86_64-pc-linux-gnu.  OK for trunk?


You are using create_ggc but the new functions do not indicate that ggc
allocation is done.
It's then also incomplete with not having a non-ggc variant
of them?  Maybe I'm missing something.


Ah, I had been thinking that this lazy pattern would only be used with
ggc, but I see that I was wrong.  How's this?

Incidentally, now I see another C++11 feature I'd like to be able to
use: default template arguments for function templates.


I presume

template
inline bool
hash_map_safe_put (hash_map *&h, const K& k, const V& v, size_t
size = default_hash_map_size)
{
   return hash_map_maybe_create (h, size)->put (k, v);
}

was deemed to ugly?  IMHO instantiating the templates for different sizes
is unwanted compile-time overhead (plus not being able to use
a default value makes non-default values creep into the code-base?).

I'd have OKed a variant like above, so - would that work for you
(change hash_map_maybe_create as well then, of course).


Sure.  Applying this version:

commit 136fbc96abe0cbb9458721fb919aacdd799e3ba8
Author: Jason Merrill 
Date:   Mon Sep 30 13:17:27 2019 -0400

Add some hash_map_safe_* functions like vec_safe_*.

gcc/
* hash-map.h (default_hash_map_size): New variable.
(create_ggc): Use it as default argument.
(hash_map_maybe_create, hash_map_safe_get)
(hash_map_safe_get_or_insert, hash_map_safe_put): New fns.
gcc/cp/
* constexpr.c (maybe_initialize_fundef_copies_table): Remove.
(get_fundef_copy): Use hash_map_safe_get_or_insert.
* cp-objcp-common.c (cp_get_debug_type): Use hash_map_safe_*.
* decl.c (store_decomp_type): Remove.
(cp_finish_decomp): Use hash_map_safe_put.
* init.c (get_nsdmi): Use hash_map_safe_*.
* pt.c (store_defaulted_ttp, lookup_defaulted_ttp): Remove.
(add_defaults_to_ttp): Use hash_map_safe_*.

diff --git a/gcc/hash-map.h b/gcc/hash-map.h
index ba20fe79f23..73ce6a1dc66 100644
--- a/gcc/hash-map.h
+++ b/gcc/hash-map.h
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
removed.  Objects of hash_map type are copy-constructible but not
assignable.  */
 
+const size_t default_hash_map_size = 13;
 template,
 			Value> */>
@@ -129,7 +130,7 @@ class GTY((user)) hash_map
   };
 
 public:
-  explicit hash_map (size_t n = 13, bool ggc = false,
+  explicit hash_map (size_t n = default_hash_map_size, bool ggc = false,
 		 bool sanitize_eq_and_hash = true,
 		 bool gather_mem_stats = GATHER_STATISTICS
 		 CXX_MEM_STAT_INFO)
@@ -146,7 +147,7 @@ public:
 	   HASH_MAP_ORIGIN PASS_MEM_STAT) {}
 
   /* Create a hash_map in ggc memory.  */
-  static hash_map *create_ggc (size_t size,
+  static hash_map *create_ggc (size_t size = default_hash_map_size,
 			   bool gather_mem_stats = GATHER_STATISTICS
 			   CXX_MEM_STAT_INFO)
 {
@@ -326,4 +327,46 @@ gt_pch_nx (hash_map *h, gt_pointer_operator op, void *cookie)
   op (&h->m_table.m_entries, cookie);
 }
 
+enum hm_alloc { hm_heap = false, hm_ggc = true };
+template
+inline hash_map *
+hash_map_maybe_create (hash_map *&h,
+		   size_t size = default_hash_map_size)
+{
+  if (!h)
+{
+  if (ggc)
+	h = hash_map::create_ggc (size);
+  else
+	h = new hash_map (size);
+}
+  return h;
+}
+
+/* Like h->get, but handles null h.  */
+template
+inline V*
+hash_map_safe_get (hash_map *h, const K& k)
+{
+  return h ? h->get (k) : NULL;
+}
+
+/* Like h->get, but handles null h.  */
+template
+inline V&
+hash_map_safe_get_or_insert (hash_map *&h, const K& k, bool *e = NULL,
+			 size_t size = default_hash_map_size)
+{
+  return hash_map_maybe_create (h, size)->get_or_insert (k, e);
+}
+
+/* Like h->put, but handles null h.  */
+template
+inline bool
+hash_map_safe_put (hash_map *&h, const K& k, const V& v,
+		   size_t size = default_hash_map_size)
+{
+  return hash_map_maybe_create (h, size)->put (k, v);
+}
+
 #endif
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index cb5484f4b72..06672a2c3b2 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1098,15 +1098,6 @@ maybe_initialize_constexpr_call_table (void)
 
 static GTY(()) hash_map *fundef_copies_table;
 
-/* Initialize FUNDEF_COPIES_TABLE if it's not initialized.  */
-
-static void
-maybe_initialize_fundef_copies_table ()
-{
-  if (fundef_copies_table == NULL)
-fundef_co

Re: [PATCH] Add some hash_map_safe_* functions like vec_safe_*.

2019-10-02 Thread Richard Biener
On Tue, Oct 1, 2019 at 8:50 PM Jason Merrill  wrote:
>
> On 10/1/19 3:34 AM, Richard Biener wrote:
> > On Mon, Sep 30, 2019 at 8:33 PM Jason Merrill  wrote:
> >>
> >> My comments accidentally got lost.
> >>
> >> Several places in the front-end (and elsewhere) use the same lazy
> >> allocation pattern for hash_maps, and this patch replaces them with
> >> hash_map_safe_* functions like vec_safe_*.  They don't provide a way
> >> to specify an initial size, but I don't think that's a significant
> >> issue.
> >>
> >> Tested x86_64-pc-linux-gnu.  OK for trunk?
> >
> > You are using create_ggc but the new functions do not indicate that ggc
> > allocation is done.
> > It's then also incomplete with not having a non-ggc variant
> > of them?  Maybe I'm missing something.
>
> Ah, I had been thinking that this lazy pattern would only be used with
> ggc, but I see that I was wrong.  How's this?
>
> Incidentally, now I see another C++11 feature I'd like to be able to
> use: default template arguments for function templates.

I presume

template
inline bool
hash_map_safe_put (hash_map *&h, const K& k, const V& v, size_t
size = default_hash_map_size)
{
  return hash_map_maybe_create (h, size)->put (k, v);
}

was deemed to ugly?  IMHO instantiating the templates for different sizes
is unwanted compile-time overhead (plus not being able to use
a default value makes non-default values creep into the code-base?).

I'd have OKed a variant like above, so - would that work for you
(change hash_map_maybe_create as well then, of course).

Thanks,
Richard.


Re: [PATCH] Add some hash_map_safe_* functions like vec_safe_*.

2019-10-01 Thread Jason Merrill

On 10/1/19 3:34 AM, Richard Biener wrote:

On Mon, Sep 30, 2019 at 8:33 PM Jason Merrill  wrote:


My comments accidentally got lost.

Several places in the front-end (and elsewhere) use the same lazy
allocation pattern for hash_maps, and this patch replaces them with
hash_map_safe_* functions like vec_safe_*.  They don't provide a way
to specify an initial size, but I don't think that's a significant
issue.

Tested x86_64-pc-linux-gnu.  OK for trunk?


You are using create_ggc but the new functions do not indicate that ggc
allocation is done.
It's then also incomplete with not having a non-ggc variant
of them?  Maybe I'm missing something.


Ah, I had been thinking that this lazy pattern would only be used with 
ggc, but I see that I was wrong.  How's this?


Incidentally, now I see another C++11 feature I'd like to be able to 
use: default template arguments for function templates.


commit c091a74dc7b1550d7dd633dbde7ed7931cd4b025
Author: Jason Merrill 
Date:   Mon Sep 30 13:17:27 2019 -0400

Add some hash_map_safe_* functions like vec_safe_*.

gcc/
* hash-map.h (default_hash_map_size): New variable.
(create_ggc): Use it as default argument.
(hash_map_maybe_create, hash_map_safe_get)
(hash_map_safe_get_or_insert, hash_map_safe_put): New fns.
gcc/cp/
* constexpr.c (maybe_initialize_fundef_copies_table): Remove.
(get_fundef_copy): Use hash_map_safe_get_or_insert.
* cp-objcp-common.c (cp_get_debug_type): Use hash_map_safe_*.
* decl.c (store_decomp_type): Remove.
(cp_finish_decomp): Use hash_map_safe_put.
* init.c (get_nsdmi): Use hash_map_safe_*.
* pt.c (store_defaulted_ttp, lookup_defaulted_ttp): Remove.
(add_defaults_to_ttp): Use hash_map_safe_*.

diff --git a/gcc/hash-map.h b/gcc/hash-map.h
index ba20fe79f23..ce98d3431c3 100644
--- a/gcc/hash-map.h
+++ b/gcc/hash-map.h
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
removed.  Objects of hash_map type are copy-constructible but not
assignable.  */
 
+const size_t default_hash_map_size = 13;
 template,
 			Value> */>
@@ -129,7 +130,7 @@ class GTY((user)) hash_map
   };
 
 public:
-  explicit hash_map (size_t n = 13, bool ggc = false,
+  explicit hash_map (size_t n = default_hash_map_size, bool ggc = false,
 		 bool sanitize_eq_and_hash = true,
 		 bool gather_mem_stats = GATHER_STATISTICS
 		 CXX_MEM_STAT_INFO)
@@ -146,7 +147,7 @@ public:
 	   HASH_MAP_ORIGIN PASS_MEM_STAT) {}
 
   /* Create a hash_map in ggc memory.  */
-  static hash_map *create_ggc (size_t size,
+  static hash_map *create_ggc (size_t size = default_hash_map_size,
 			   bool gather_mem_stats = GATHER_STATISTICS
 			   CXX_MEM_STAT_INFO)
 {
@@ -326,4 +327,43 @@ gt_pch_nx (hash_map *h, gt_pointer_operator op, void *cookie)
   op (&h->m_table.m_entries, cookie);
 }
 
+enum hm_alloc { hm_heap = false, hm_ggc = true };
+template
+inline hash_map *
+hash_map_maybe_create (hash_map *&h)
+{
+  if (!h)
+{
+  if (ggc)
+	h = hash_map::create_ggc (size);
+  else
+	h = new hash_map (size);
+}
+  return h;
+}
+
+/* Like h->get, but handles null h.  */
+template
+inline V*
+hash_map_safe_get (hash_map *h, const K& k)
+{
+  return h ? h->get (k) : NULL;
+}
+
+/* Like h->get, but handles null h.  */
+template
+inline V&
+hash_map_safe_get_or_insert (hash_map *&h, const K& k, bool *e = NULL)
+{
+  return hash_map_maybe_create (h)->get_or_insert (k, e);
+}
+
+/* Like h->put, but handles null h.  */
+template
+inline bool
+hash_map_safe_put (hash_map *&h, const K& k, const V& v)
+{
+  return hash_map_maybe_create (h)->put (k, v);
+}
+
 #endif
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index cb5484f4b72..6366872695a 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1098,15 +1098,6 @@ maybe_initialize_constexpr_call_table (void)
 
 static GTY(()) hash_map *fundef_copies_table;
 
-/* Initialize FUNDEF_COPIES_TABLE if it's not initialized.  */
-
-static void
-maybe_initialize_fundef_copies_table ()
-{
-  if (fundef_copies_table == NULL)
-fundef_copies_table = hash_map::create_ggc (101);
-}
-
 /* Reuse a copy or create a new unshared copy of the function FUN.
Return this copy.  We use a TREE_LIST whose PURPOSE is body, VALUE
is parms, TYPE is result.  */
@@ -1114,11 +1105,10 @@ maybe_initialize_fundef_copies_table ()
 static tree
 get_fundef_copy (constexpr_fundef *fundef)
 {
-  maybe_initialize_fundef_copies_table ();
-
   tree copy;
   bool existed;
-  tree *slot = &fundef_copies_table->get_or_insert (fundef->decl, &existed);
+  tree *slot = &(hash_map_safe_get_or_insert
+		 (fundef_copies_table, fundef->decl, &existed));
 
   if (!existed)
 {
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 4369a5b5570..990e3f04db9 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@

Re: [PATCH] Add some hash_map_safe_* functions like vec_safe_*.

2019-10-01 Thread Richard Biener
On Mon, Sep 30, 2019 at 8:33 PM Jason Merrill  wrote:
>
> My comments accidentally got lost.
>
> Several places in the front-end (and elsewhere) use the same lazy
> allocation pattern for hash_maps, and this patch replaces them with
> hash_map_safe_* functions like vec_safe_*.  They don't provide a way
> to specify an initial size, but I don't think that's a significant
> issue.
>
> Tested x86_64-pc-linux-gnu.  OK for trunk?

You are using create_ggc but the new functions do not indicate that ggc
allocation is done.  It's then also incomplete with not having a non-ggc variant
of them?  Maybe I'm missing something.

Thanks,
Richard.

> On Mon, Sep 30, 2019 at 2:30 PM Jason Merrill  wrote:
> >
> > gcc/
> > * hash-map.h (default_size): Put in member variable.
> > (create_ggc): Use it as default argument.
> > (hash_map_maybe_create, hash_map_safe_get)
> > (hash_map_safe_get_or_insert, hash_map_safe_put): New fns.
> > gcc/cp/
> > * constexpr.c (maybe_initialize_fundef_copies_table): Remove.
> > (get_fundef_copy): Use hash_map_safe_get_or_insert.
> > * cp-objcp-common.c (cp_get_debug_type): Use hash_map_safe_*.
> > * decl.c (store_decomp_type): Remove.
> > (cp_finish_decomp): Use hash_map_safe_put.
> > * init.c (get_nsdmi): Use hash_map_safe_*.
> > * pt.c (store_defaulted_ttp, lookup_defaulted_ttp): Remove.
> > (add_defaults_to_ttp): Use hash_map_safe_*.
> > ---
> >  gcc/hash-map.h   | 38 --
> >  gcc/cp/constexpr.c   | 14 ++
> >  gcc/cp/cp-objcp-common.c |  6 ++
> >  gcc/cp/decl.c|  9 +
> >  gcc/cp/init.c|  9 ++---
> >  gcc/cp/pt.c  | 21 +++--
> >  gcc/hash-table.c |  2 +-
> >  7 files changed, 47 insertions(+), 52 deletions(-)
> >
> > diff --git a/gcc/hash-map.h b/gcc/hash-map.h
> > index ba20fe79f23..e638f761465 100644
> > --- a/gcc/hash-map.h
> > +++ b/gcc/hash-map.h
> > @@ -128,8 +128,9 @@ class GTY((user)) hash_map
> > }
> >};
> >
> > +  static const size_t default_size = 13;
> >  public:
> > -  explicit hash_map (size_t n = 13, bool ggc = false,
> > +  explicit hash_map (size_t n = default_size, bool ggc = false,
> >  bool sanitize_eq_and_hash = true,
> >  bool gather_mem_stats = GATHER_STATISTICS
> >  CXX_MEM_STAT_INFO)
> > @@ -146,7 +147,7 @@ public:
> >HASH_MAP_ORIGIN PASS_MEM_STAT) {}
> >
> >/* Create a hash_map in ggc memory.  */
> > -  static hash_map *create_ggc (size_t size,
> > +  static hash_map *create_ggc (size_t size = default_size,
> >bool gather_mem_stats = GATHER_STATISTICS
> >CXX_MEM_STAT_INFO)
> >  {
> > @@ -326,4 +327,37 @@ gt_pch_nx (hash_map *h, gt_pointer_operator 
> > op, void *cookie)
> >op (&h->m_table.m_entries, cookie);
> >  }
> >
> > +template
> > +inline hash_map *
> > +hash_map_maybe_create (hash_map *&h)
> > +{
> > +  if (!h)
> > +h = h->create_ggc ();
> > +  return h;
> > +}
> > +
> > +/* Like h->get, but handles null h.  */
> > +template
> > +inline V*
> > +hash_map_safe_get (hash_map *h, const K& k)
> > +{
> > +  return h ? h->get (k) : NULL;
> > +}
> > +
> > +/* Like h->get, but handles null h.  */
> > +template
> > +inline V&
> > +hash_map_safe_get_or_insert (hash_map *&h, const K& k, bool *e = 
> > NULL)
> > +{
> > +  return hash_map_maybe_create (h)->get_or_insert (k, e);
> > +}
> > +
> > +/* Like h->put, but handles null h.  */
> > +template
> > +inline bool
> > +hash_map_safe_put (hash_map *&h, const K& k, const V& v)
> > +{
> > +  return hash_map_maybe_create (h)->put (k, v);
> > +}
> > +
> >  #endif
> > diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
> > index cb5484f4b72..904b70a9c99 100644
> > --- a/gcc/cp/constexpr.c
> > +++ b/gcc/cp/constexpr.c
> > @@ -1098,15 +1098,6 @@ maybe_initialize_constexpr_call_table (void)
> >
> >  static GTY(()) hash_map *fundef_copies_table;
> >
> > -/* Initialize FUNDEF_COPIES_TABLE if it's not initialized.  */
> > -
> > -static void
> > -maybe_initialize_fundef_copies_table ()
> > -{
> > -  if (fundef_copies_table == NULL)
> > -fundef_copies_table = hash_map::create_ggc (101);
> > -}
> > -
> >  /* Reuse a copy or create a new unshared copy of the function FUN.
> > Return this copy.  We use a TREE_LIST whose PURPOSE is body, VALUE
> > is parms, TYPE is result.  */
> > @@ -1114,11 +1105,10 @@ maybe_initialize_fundef_copies_table ()
> >  static tree
> >  get_fundef_copy (constexpr_fundef *fundef)
> >  {
> > -  maybe_initialize_fundef_copies_table ();
> > -
> >tree copy;
> >bool existed;
> > -  tree *slot = &fundef_copies_table->get_or_insert (fundef->decl, 
> > &existed);
> > +  tree *slot = &hash_map_safe_get_or_insert (fundef_copies_table,
> > +fundef->decl, &existed);
> >

Re: [PATCH] Add some hash_map_safe_* functions like vec_safe_*.

2019-09-30 Thread Jason Merrill
My comments accidentally got lost.

Several places in the front-end (and elsewhere) use the same lazy
allocation pattern for hash_maps, and this patch replaces them with
hash_map_safe_* functions like vec_safe_*.  They don't provide a way
to specify an initial size, but I don't think that's a significant
issue.

Tested x86_64-pc-linux-gnu.  OK for trunk?

On Mon, Sep 30, 2019 at 2:30 PM Jason Merrill  wrote:
>
> gcc/
> * hash-map.h (default_size): Put in member variable.
> (create_ggc): Use it as default argument.
> (hash_map_maybe_create, hash_map_safe_get)
> (hash_map_safe_get_or_insert, hash_map_safe_put): New fns.
> gcc/cp/
> * constexpr.c (maybe_initialize_fundef_copies_table): Remove.
> (get_fundef_copy): Use hash_map_safe_get_or_insert.
> * cp-objcp-common.c (cp_get_debug_type): Use hash_map_safe_*.
> * decl.c (store_decomp_type): Remove.
> (cp_finish_decomp): Use hash_map_safe_put.
> * init.c (get_nsdmi): Use hash_map_safe_*.
> * pt.c (store_defaulted_ttp, lookup_defaulted_ttp): Remove.
> (add_defaults_to_ttp): Use hash_map_safe_*.
> ---
>  gcc/hash-map.h   | 38 --
>  gcc/cp/constexpr.c   | 14 ++
>  gcc/cp/cp-objcp-common.c |  6 ++
>  gcc/cp/decl.c|  9 +
>  gcc/cp/init.c|  9 ++---
>  gcc/cp/pt.c  | 21 +++--
>  gcc/hash-table.c |  2 +-
>  7 files changed, 47 insertions(+), 52 deletions(-)
>
> diff --git a/gcc/hash-map.h b/gcc/hash-map.h
> index ba20fe79f23..e638f761465 100644
> --- a/gcc/hash-map.h
> +++ b/gcc/hash-map.h
> @@ -128,8 +128,9 @@ class GTY((user)) hash_map
> }
>};
>
> +  static const size_t default_size = 13;
>  public:
> -  explicit hash_map (size_t n = 13, bool ggc = false,
> +  explicit hash_map (size_t n = default_size, bool ggc = false,
>  bool sanitize_eq_and_hash = true,
>  bool gather_mem_stats = GATHER_STATISTICS
>  CXX_MEM_STAT_INFO)
> @@ -146,7 +147,7 @@ public:
>HASH_MAP_ORIGIN PASS_MEM_STAT) {}
>
>/* Create a hash_map in ggc memory.  */
> -  static hash_map *create_ggc (size_t size,
> +  static hash_map *create_ggc (size_t size = default_size,
>bool gather_mem_stats = GATHER_STATISTICS
>CXX_MEM_STAT_INFO)
>  {
> @@ -326,4 +327,37 @@ gt_pch_nx (hash_map *h, gt_pointer_operator op, 
> void *cookie)
>op (&h->m_table.m_entries, cookie);
>  }
>
> +template
> +inline hash_map *
> +hash_map_maybe_create (hash_map *&h)
> +{
> +  if (!h)
> +h = h->create_ggc ();
> +  return h;
> +}
> +
> +/* Like h->get, but handles null h.  */
> +template
> +inline V*
> +hash_map_safe_get (hash_map *h, const K& k)
> +{
> +  return h ? h->get (k) : NULL;
> +}
> +
> +/* Like h->get, but handles null h.  */
> +template
> +inline V&
> +hash_map_safe_get_or_insert (hash_map *&h, const K& k, bool *e = NULL)
> +{
> +  return hash_map_maybe_create (h)->get_or_insert (k, e);
> +}
> +
> +/* Like h->put, but handles null h.  */
> +template
> +inline bool
> +hash_map_safe_put (hash_map *&h, const K& k, const V& v)
> +{
> +  return hash_map_maybe_create (h)->put (k, v);
> +}
> +
>  #endif
> diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
> index cb5484f4b72..904b70a9c99 100644
> --- a/gcc/cp/constexpr.c
> +++ b/gcc/cp/constexpr.c
> @@ -1098,15 +1098,6 @@ maybe_initialize_constexpr_call_table (void)
>
>  static GTY(()) hash_map *fundef_copies_table;
>
> -/* Initialize FUNDEF_COPIES_TABLE if it's not initialized.  */
> -
> -static void
> -maybe_initialize_fundef_copies_table ()
> -{
> -  if (fundef_copies_table == NULL)
> -fundef_copies_table = hash_map::create_ggc (101);
> -}
> -
>  /* Reuse a copy or create a new unshared copy of the function FUN.
> Return this copy.  We use a TREE_LIST whose PURPOSE is body, VALUE
> is parms, TYPE is result.  */
> @@ -1114,11 +1105,10 @@ maybe_initialize_fundef_copies_table ()
>  static tree
>  get_fundef_copy (constexpr_fundef *fundef)
>  {
> -  maybe_initialize_fundef_copies_table ();
> -
>tree copy;
>bool existed;
> -  tree *slot = &fundef_copies_table->get_or_insert (fundef->decl, &existed);
> +  tree *slot = &hash_map_safe_get_or_insert (fundef_copies_table,
> +fundef->decl, &existed);
>
>if (!existed)
>  {
> diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
> index 4369a5b5570..652b94230ad 100644
> --- a/gcc/cp/cp-objcp-common.c
> +++ b/gcc/cp/cp-objcp-common.c
> @@ -145,11 +145,9 @@ cp_get_debug_type (const_tree type)
>if (dtype)
>  {
>tree ktype = CONST_CAST_TREE (type);
> -  if (debug_type_map == NULL)
> -   debug_type_map = tree_cache_map::create_ggc (512);
> -  else if (tree *slot = debug_type_map->get (ktype))
> +  if (tree *slot = hash_map_safe_get (

[PATCH] Add some hash_map_safe_* functions like vec_safe_*.

2019-09-30 Thread Jason Merrill
gcc/
* hash-map.h (default_size): Put in member variable.
(create_ggc): Use it as default argument.
(hash_map_maybe_create, hash_map_safe_get)
(hash_map_safe_get_or_insert, hash_map_safe_put): New fns.
gcc/cp/
* constexpr.c (maybe_initialize_fundef_copies_table): Remove.
(get_fundef_copy): Use hash_map_safe_get_or_insert.
* cp-objcp-common.c (cp_get_debug_type): Use hash_map_safe_*.
* decl.c (store_decomp_type): Remove.
(cp_finish_decomp): Use hash_map_safe_put.
* init.c (get_nsdmi): Use hash_map_safe_*.
* pt.c (store_defaulted_ttp, lookup_defaulted_ttp): Remove.
(add_defaults_to_ttp): Use hash_map_safe_*.
---
 gcc/hash-map.h   | 38 --
 gcc/cp/constexpr.c   | 14 ++
 gcc/cp/cp-objcp-common.c |  6 ++
 gcc/cp/decl.c|  9 +
 gcc/cp/init.c|  9 ++---
 gcc/cp/pt.c  | 21 +++--
 gcc/hash-table.c |  2 +-
 7 files changed, 47 insertions(+), 52 deletions(-)

diff --git a/gcc/hash-map.h b/gcc/hash-map.h
index ba20fe79f23..e638f761465 100644
--- a/gcc/hash-map.h
+++ b/gcc/hash-map.h
@@ -128,8 +128,9 @@ class GTY((user)) hash_map
}
   };
 
+  static const size_t default_size = 13;
 public:
-  explicit hash_map (size_t n = 13, bool ggc = false,
+  explicit hash_map (size_t n = default_size, bool ggc = false,
 bool sanitize_eq_and_hash = true,
 bool gather_mem_stats = GATHER_STATISTICS
 CXX_MEM_STAT_INFO)
@@ -146,7 +147,7 @@ public:
   HASH_MAP_ORIGIN PASS_MEM_STAT) {}
 
   /* Create a hash_map in ggc memory.  */
-  static hash_map *create_ggc (size_t size,
+  static hash_map *create_ggc (size_t size = default_size,
   bool gather_mem_stats = GATHER_STATISTICS
   CXX_MEM_STAT_INFO)
 {
@@ -326,4 +327,37 @@ gt_pch_nx (hash_map *h, gt_pointer_operator op, 
void *cookie)
   op (&h->m_table.m_entries, cookie);
 }
 
+template
+inline hash_map *
+hash_map_maybe_create (hash_map *&h)
+{
+  if (!h)
+h = h->create_ggc ();
+  return h;
+}
+
+/* Like h->get, but handles null h.  */
+template
+inline V*
+hash_map_safe_get (hash_map *h, const K& k)
+{
+  return h ? h->get (k) : NULL;
+}
+
+/* Like h->get, but handles null h.  */
+template
+inline V&
+hash_map_safe_get_or_insert (hash_map *&h, const K& k, bool *e = NULL)
+{
+  return hash_map_maybe_create (h)->get_or_insert (k, e);
+}
+
+/* Like h->put, but handles null h.  */
+template
+inline bool
+hash_map_safe_put (hash_map *&h, const K& k, const V& v)
+{
+  return hash_map_maybe_create (h)->put (k, v);
+}
+
 #endif
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index cb5484f4b72..904b70a9c99 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1098,15 +1098,6 @@ maybe_initialize_constexpr_call_table (void)
 
 static GTY(()) hash_map *fundef_copies_table;
 
-/* Initialize FUNDEF_COPIES_TABLE if it's not initialized.  */
-
-static void
-maybe_initialize_fundef_copies_table ()
-{
-  if (fundef_copies_table == NULL)
-fundef_copies_table = hash_map::create_ggc (101);
-}
-
 /* Reuse a copy or create a new unshared copy of the function FUN.
Return this copy.  We use a TREE_LIST whose PURPOSE is body, VALUE
is parms, TYPE is result.  */
@@ -1114,11 +1105,10 @@ maybe_initialize_fundef_copies_table ()
 static tree
 get_fundef_copy (constexpr_fundef *fundef)
 {
-  maybe_initialize_fundef_copies_table ();
-
   tree copy;
   bool existed;
-  tree *slot = &fundef_copies_table->get_or_insert (fundef->decl, &existed);
+  tree *slot = &hash_map_safe_get_or_insert (fundef_copies_table,
+fundef->decl, &existed);
 
   if (!existed)
 {
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 4369a5b5570..652b94230ad 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -145,11 +145,9 @@ cp_get_debug_type (const_tree type)
   if (dtype)
 {
   tree ktype = CONST_CAST_TREE (type);
-  if (debug_type_map == NULL)
-   debug_type_map = tree_cache_map::create_ggc (512);
-  else if (tree *slot = debug_type_map->get (ktype))
+  if (tree *slot = hash_map_safe_get (debug_type_map, ktype))
return *slot;
-  debug_type_map->put (ktype, dtype);
+  hash_map_safe_put (debug_type_map, ktype, dtype);
 }
 
   return dtype;
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 67c4521e98c..562fe10bd96 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -7704,13 +7704,6 @@ get_tuple_decomp_init (tree decl, unsigned i)
based on the actual type of the variable, so store it in a hash table.  */
 
 static GTY((cache)) tree_cache_map *decomp_type_table;
-static void
-store_decomp_type (tree v, tree t)
-{
-  if (!decomp_type_table)
-decomp_type_table = tree_cache_map::create_ggc (13);
-  decomp_type_table->put (v, t