diff mbox series

[C++] Fix concepts vs. PCH (PR c++/92458, take 2)

Message ID 20191122140848.GA2466@tucnak
State New
Headers show
Series [C++] Fix concepts vs. PCH (PR c++/92458, take 2) | expand

Commit Message

Jakub Jelinek Nov. 22, 2019, 2:08 p.m. UTC
On Wed, Nov 20, 2019 at 07:46:13PM -0500, Jason Merrill wrote:
> > If decl_tree_cache_map will be needed in more than one spot, I'll probably
> > need to move it to some generic header.
> 
> Most of them probably need it, for code that uses the relevant features.
> Except debug_type_map, which probably needs to use TYPE_UID.
> 
> Or we might make default_hash_traits<tree> use DECL_UID for decls and
> TYPE_UID for types even if it doesn't do the more complex analysis of
> tree_operand_hash.

Finding out what is a type and what is decl (and what to do with rest?)
at runtime would be more costly than necessary.

The following updated patch moves the decl_tree_cache_map to tree.h and
adds there type_tree_cache_map too and uses it in all the tree_cache_map
spots in the C++ FE.
tree-hash-traits.h can't be included from tree.h, because operand_equal_p is
declared elsewhere, so instead this patch moves some of the
tree-hash-traits.h traits from that header to tree.h.  I could move there
just tree_decl_hash if moving the other two doesn't look right to you.

Bootstrapped/regtested on x86_64-linux and i686-linux, additionally tested
by compiling stdc++.h as PCH with -std=c++2a and using it.  Ok for trunk?

2019-11-22  Jakub Jelinek  <jakub@redhat.com>

	PR c++/92458
	* tree-hash-traits.h (tree_decl_hash, tree_ssa_name_hash,
	tree_hash): Move to ...
	* tree.h (tree_decl_hash, tree_ssa_name_hash, tree_hash): ... here.
	(struct decl_tree_cache_traits, struct type_tree_cache_traits): New
	types.
	(decl_tree_cache_map, tree_tree_cache_map): New typedefs.

	* init.c (nsdmi_inst): Change type to
	decl_tree_cache_map * from tree_cache_map *.
	* constraint.cc (decl_constraints): Likewise.
	* decl.c (get_tuple_decomp_init): Likewise.
	* pt.c (defarg_inst, explicit_specifier_map): Likewise.
	(tsubst_default_argument, store_explicit_specifier): Use
	decl_tree_cache_map::create_ggc rather than
	tree_cache_map::create_ggc.
	* cp-objcp-common.c (debug_type_map): Change type to
	type_tree_cache_map * from tree_cache_map *.

	* g++.dg/pch/pr92458.C: New test.
	* g++.dg/pch/pr92458.Hs: New test.



	Jakub

Comments

Jason Merrill Nov. 22, 2019, 7:43 p.m. UTC | #1
On 11/22/19 2:08 PM, Jakub Jelinek wrote:
> On Wed, Nov 20, 2019 at 07:46:13PM -0500, Jason Merrill wrote:
>>> If decl_tree_cache_map will be needed in more than one spot, I'll probably
>>> need to move it to some generic header.
>>
>> Most of them probably need it, for code that uses the relevant features.
>> Except debug_type_map, which probably needs to use TYPE_UID.
>>
>> Or we might make default_hash_traits<tree> use DECL_UID for decls and
>> TYPE_UID for types even if it doesn't do the more complex analysis of
>> tree_operand_hash.
> 
> Finding out what is a type and what is decl (and what to do with rest?)
> at runtime would be more costly than necessary.
> 
> The following updated patch moves the decl_tree_cache_map to tree.h and
> adds there type_tree_cache_map too and uses it in all the tree_cache_map
> spots in the C++ FE.
> tree-hash-traits.h can't be included from tree.h, because operand_equal_p is
> declared elsewhere, so instead this patch moves some of the
> tree-hash-traits.h traits from that header to tree.h.  I could move there
> just tree_decl_hash if moving the other two doesn't look right to you.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, additionally tested
> by compiling stdc++.h as PCH with -std=c++2a and using it.  Ok for trunk?

> 2019-11-22  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR c++/92458
> 	* tree-hash-traits.h (tree_decl_hash, tree_ssa_name_hash,
> 	tree_hash): Move to ...
> 	* tree.h (tree_decl_hash, tree_ssa_name_hash, tree_hash): ... here.
> 	(struct decl_tree_cache_traits, struct type_tree_cache_traits): New
> 	types.
> 	(decl_tree_cache_map, tree_tree_cache_map): New typedefs.
> 
> 	* init.c (nsdmi_inst): Change type to
> 	decl_tree_cache_map * from tree_cache_map *.
> 	* constraint.cc (decl_constraints): Likewise.
> 	* decl.c (get_tuple_decomp_init): Likewise.
> 	* pt.c (defarg_inst, explicit_specifier_map): Likewise.
> 	(tsubst_default_argument, store_explicit_specifier): Use
> 	decl_tree_cache_map::create_ggc rather than
> 	tree_cache_map::create_ggc.
> 	* cp-objcp-common.c (debug_type_map): Change type to
> 	type_tree_cache_map * from tree_cache_map *.
> 
> 	* g++.dg/pch/pr92458.C: New test.
> 	* g++.dg/pch/pr92458.Hs: New test.
> 
> --- gcc/tree-hash-traits.h.jj	2019-01-01 12:37:16.902979134 +0100
> +++ gcc/tree-hash-traits.h	2019-11-22 12:00:01.538725844 +0100
> @@ -41,44 +41,4 @@ tree_operand_hash::equal (const value_ty
>     return operand_equal_p (t1, t2, 0);
>   }
>   
> -/* Hasher for tree decls.  Pointer equality is enough here, but the DECL_UID
> -   is a better hash than the pointer value and gives a predictable traversal
> -   order.  */
> -struct tree_decl_hash : ggc_ptr_hash <tree_node>
> -{
> -  static inline hashval_t hash (tree);
> -};
> -
> -inline hashval_t
> -tree_decl_hash::hash (tree t)
> -{
> -  return DECL_UID (t);
> -}
> -
> -/* Hash for SSA_NAMEs in the same function.  Pointer equality is enough
> -   here, but the SSA_NAME_VERSION is a better hash than the pointer
> -   value and gives a predictable traversal order.  */
> -struct tree_ssa_name_hash : ggc_ptr_hash <tree_node>
> -{
> -  static inline hashval_t hash (tree);
> -};
> -
> -inline hashval_t
> -tree_ssa_name_hash::hash (tree t)
> -{
> -  return SSA_NAME_VERSION (t);
> -}
> -
> -/* Hasher for general trees, based on their TREE_HASH.  */
> -struct tree_hash : ggc_ptr_hash <tree_node>
> -{
> -  static hashval_t hash (tree);
> -};
> -
> -inline hashval_t
> -tree_hash::hash (tree t)
> -{
> -  return TREE_HASH (t);
> -}
> -
>   #endif
> --- gcc/tree.h.jj	2019-11-15 00:37:26.293070143 +0100
> +++ gcc/tree.h	2019-11-22 12:00:17.479478830 +0100
> @@ -5351,6 +5351,58 @@ struct tree_decl_map_cache_hasher : ggc_
>   #define tree_vec_map_hash tree_decl_map_hash
>   #define tree_vec_map_marked_p tree_map_base_marked_p
>   
> +/* Hasher for tree decls.  Pointer equality is enough here, but the DECL_UID
> +   is a better hash than the pointer value and gives a predictable traversal
> +   order.  Additionally it can be used across PCH save/restore.  */
> +struct tree_decl_hash : ggc_ptr_hash <tree_node>
> +{
> +  static inline hashval_t hash (tree);
> +};
> +
> +inline hashval_t
> +tree_decl_hash::hash (tree t)
> +{
> +  return DECL_UID (t);
> +}
> +
> +/* Similarly for types.  Uses TYPE_UID as hash function.  */
> +struct tree_type_hash : ggc_ptr_hash <tree_node>
> +{
> +  static inline hashval_t hash (tree);
> +};
> +
> +inline hashval_t
> +tree_type_hash::hash (tree t)
> +{
> +  return TYPE_UID (t);
> +}
> +
> +/* Hash for SSA_NAMEs in the same function.  Pointer equality is enough
> +   here, but the SSA_NAME_VERSION is a better hash than the pointer
> +   value and gives a predictable traversal order.  */
> +struct tree_ssa_name_hash : ggc_ptr_hash <tree_node>
> +{
> +  static inline hashval_t hash (tree);
> +};
> +
> +inline hashval_t
> +tree_ssa_name_hash::hash (tree t)
> +{
> +  return SSA_NAME_VERSION (t);
> +}
> +
> +/* Hasher for general trees, based on their TREE_HASH.  */
> +struct tree_hash : ggc_ptr_hash <tree_node>
> +{
> +  static hashval_t hash (tree);
> +};
> +
> +inline hashval_t
> +tree_hash::hash (tree t)
> +{
> +  return TREE_HASH (t);
> +}
> +
>   /* A hash_map of two trees for use with GTY((cache)).  Garbage collection for
>      such a map will not mark keys, and will mark values if the key is already
>      marked.  */
> @@ -5358,6 +5410,18 @@ struct tree_cache_traits
>     : simple_cache_map_traits<default_hash_traits<tree>, tree> { };

We should probably use tree_hash instead of default_hash_traits here. 
OK with or without that change.

>   typedef hash_map<tree,tree,tree_cache_traits> tree_cache_map;
>   
> +/* Similarly, but use DECL_UID as hash function rather than pointer hashing.
> +   This is for hash_maps from decls to trees that need to work across PCH.  */
> +struct decl_tree_cache_traits
> +  : simple_cache_map_traits<tree_decl_hash, tree> { };
> +typedef hash_map<tree,tree,decl_tree_cache_traits> decl_tree_cache_map;
> +
> +/* Similarly, but use TYPE_UID as hash function rather than pointer hashing.
> +   This is for hash_maps from types to trees that need to work across PCH.  */
> +struct type_tree_cache_traits
> +  : simple_cache_map_traits<tree_type_hash, tree> { };
> +typedef hash_map<tree,tree,type_tree_cache_traits> type_tree_cache_map;
> +
>   /* Initialize the abstract argument list iterator object ITER with the
>      arguments from CALL_EXPR node EXP.  */
>   static inline void
> --- gcc/cp/init.c.jj	2019-11-08 00:22:12.042424097 +0100
> +++ gcc/cp/init.c	2019-11-22 11:50:11.285872353 +0100
> @@ -548,7 +548,7 @@ perform_target_ctor (tree init)
>   
>   /* Return the non-static data initializer for FIELD_DECL MEMBER.  */
>   
> -static GTY((cache)) tree_cache_map *nsdmi_inst;
> +static GTY((cache)) decl_tree_cache_map *nsdmi_inst;
>   
>   tree
>   get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
> --- gcc/cp/constraint.cc.jj	2019-11-11 21:04:02.104306246 +0100
> +++ gcc/cp/constraint.cc	2019-11-22 11:47:05.621749384 +0100
> @@ -1113,7 +1113,7 @@ build_constraints (tree tr, tree dr)
>   
>   /* A mapping from declarations to constraint information.  */
>   
> -static GTY ((cache)) tree_cache_map *decl_constraints;
> +static GTY ((cache)) decl_tree_cache_map *decl_constraints;
>   
>   /* Returns the template constraints of declaration T. If T is not
>      constrained, return NULL_TREE. Note that T must be non-null. */
> --- gcc/cp/decl.c.jj	2019-11-19 22:26:46.289293903 +0100
> +++ gcc/cp/decl.c	2019-11-22 11:49:01.954946691 +0100
> @@ -7998,7 +7998,7 @@ get_tuple_decomp_init (tree decl, unsign
>   /* It's impossible to recover the decltype of a tuple decomposition variable
>      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 GTY((cache)) decl_tree_cache_map *decomp_type_table;
>   
>   tree
>   lookup_decomp_type (tree v)
> --- gcc/cp/pt.c.jj	2019-11-19 22:27:00.737077646 +0100
> +++ gcc/cp/pt.c	2019-11-22 11:52:37.590605226 +0100
> @@ -13272,7 +13272,7 @@ tsubst_aggr_type (tree t,
>       }
>   }
>   
> -static GTY((cache)) tree_cache_map *defarg_inst;
> +static GTY((cache)) decl_tree_cache_map *defarg_inst;
>   
>   /* Substitute into the default argument ARG (a default argument for
>      FN), which has the indicated TYPE.  */
> @@ -13346,7 +13346,7 @@ tsubst_default_argument (tree fn, int pa
>     if (arg != error_mark_node && !cp_unevaluated_operand)
>       {
>         if (!defarg_inst)
> -	defarg_inst = tree_cache_map::create_ggc (37);
> +	defarg_inst = decl_tree_cache_map::create_ggc (37);
>         defarg_inst->put (parm, arg);
>       }
>   
> @@ -13383,7 +13383,7 @@ tsubst_default_arguments (tree fn, tsubs
>   }
>   
>   /* Hash table mapping a FUNCTION_DECL to its dependent explicit-specifier.  */
> -static GTY((cache)) tree_cache_map *explicit_specifier_map;
> +static GTY((cache)) decl_tree_cache_map *explicit_specifier_map;
>   
>   /* Store a pair to EXPLICIT_SPECIFIER_MAP.  */
>   
> @@ -13391,7 +13391,7 @@ void
>   store_explicit_specifier (tree v, tree t)
>   {
>     if (!explicit_specifier_map)
> -    explicit_specifier_map = tree_cache_map::create_ggc (37);
> +    explicit_specifier_map = decl_tree_cache_map::create_ggc (37);
>     DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (v) = true;
>     explicit_specifier_map->put (v, t);
>   }
> --- gcc/cp/cp-objcp-common.c.jj	2019-11-06 08:58:38.189471399 +0100
> +++ gcc/cp/cp-objcp-common.c	2019-11-22 11:51:28.090682190 +0100
> @@ -123,7 +123,7 @@ cxx_types_compatible_p (tree x, tree y)
>     return same_type_ignoring_top_level_qualifiers_p (x, y);
>   }
>   
> -static GTY((cache)) tree_cache_map *debug_type_map;
> +static GTY((cache)) type_tree_cache_map *debug_type_map;
>   
>   /* Return a type to use in the debug info instead of TYPE, or NULL_TREE to
>      keep TYPE.  */
> --- gcc/testsuite/g++.dg/pch/pr92458.C.jj	2019-11-22 11:46:31.465278668 +0100
> +++ gcc/testsuite/g++.dg/pch/pr92458.C	2019-11-22 11:46:31.465278668 +0100
> @@ -0,0 +1,5 @@
> +// PR c++/92458
> +// { dg-options "-std=c++2a" }
> +
> +#include "pr92458.H"
> +S<int> s;
> --- gcc/testsuite/g++.dg/pch/pr92458.Hs.jj	2019-11-22 11:46:31.466278653 +0100
> +++ gcc/testsuite/g++.dg/pch/pr92458.Hs	2019-11-22 11:46:31.466278653 +0100
> @@ -0,0 +1,7 @@
> +// PR c++/92458
> +// { dg-options "-std=c++2a" }
> +
> +template<typename T> concept C = sizeof(T) > 1;
> +template<typename T> struct S { };
> +template<typename T> requires C<T> struct S<T> { };
> +template<typename T> requires (!C<T>) struct S<T> { };
> 
> 
> 	Jakub
>
Jakub Jelinek Nov. 22, 2019, 8:08 p.m. UTC | #2
On Fri, Nov 22, 2019 at 02:43:25PM -0500, Jason Merrill wrote:
> > @@ -5358,6 +5410,18 @@ struct tree_cache_traits
> >     : simple_cache_map_traits<default_hash_traits<tree>, tree> { };
> 
> We should probably use tree_hash instead of default_hash_traits here. OK
> with or without that change.

Dunno, I'd say pointer_hash <Type>::hash which is
  return (hashval_t) ((intptr_t)candidate >> 3);
might be actually better hash function than
#define TREE_HASH(NODE) ((size_t) (NODE) & 0777777)
at least on 64-bit hosts, because union tree_node is 8-byte aligned there,
so the low 3 bits are all zero and we use all of the 32 bits above that.
For 32-bit hosts, it might be better to just use candidate without shifting
I guess, there aren't any extra bits we get in from above.
TREE_HASH to me unnecessarily uses the low 3 bits known to be zero and masks
with 0x3ffff, so throws away also 14 bits that could hold useful info,
leaving for 64-bit hosts only 15 bits.

	Jakub
Jason Merrill Nov. 24, 2019, 6:42 p.m. UTC | #3
On 11/22/19 3:08 PM, Jakub Jelinek wrote:
> On Fri, Nov 22, 2019 at 02:43:25PM -0500, Jason Merrill wrote:
>>> @@ -5358,6 +5410,18 @@ struct tree_cache_traits
>>>      : simple_cache_map_traits<default_hash_traits<tree>, tree> { };
>>
>> We should probably use tree_hash instead of default_hash_traits here. OK
>> with or without that change.
> 
> Dunno, I'd say pointer_hash <Type>::hash which is
>    return (hashval_t) ((intptr_t)candidate >> 3);
> might be actually better hash function than
> #define TREE_HASH(NODE) ((size_t) (NODE) & 0777777)
> at least on 64-bit hosts, because union tree_node is 8-byte aligned there,
> so the low 3 bits are all zero and we use all of the 32 bits above that.
> For 32-bit hosts, it might be better to just use candidate without shifting
> I guess, there aren't any extra bits we get in from above.
> TREE_HASH to me unnecessarily uses the low 3 bits known to be zero and masks
> with 0x3ffff, so throws away also 14 bits that could hold useful info,
> leaving for 64-bit hosts only 15 bits.

True, but that suggests that TREE_HASH should change.

Jason
diff mbox series

Patch

--- gcc/tree-hash-traits.h.jj	2019-01-01 12:37:16.902979134 +0100
+++ gcc/tree-hash-traits.h	2019-11-22 12:00:01.538725844 +0100
@@ -41,44 +41,4 @@  tree_operand_hash::equal (const value_ty
   return operand_equal_p (t1, t2, 0);
 }
 
-/* Hasher for tree decls.  Pointer equality is enough here, but the DECL_UID
-   is a better hash than the pointer value and gives a predictable traversal
-   order.  */
-struct tree_decl_hash : ggc_ptr_hash <tree_node>
-{
-  static inline hashval_t hash (tree);
-};
-
-inline hashval_t
-tree_decl_hash::hash (tree t)
-{
-  return DECL_UID (t);
-}
-
-/* Hash for SSA_NAMEs in the same function.  Pointer equality is enough
-   here, but the SSA_NAME_VERSION is a better hash than the pointer
-   value and gives a predictable traversal order.  */
-struct tree_ssa_name_hash : ggc_ptr_hash <tree_node>
-{
-  static inline hashval_t hash (tree);
-};
-
-inline hashval_t
-tree_ssa_name_hash::hash (tree t)
-{
-  return SSA_NAME_VERSION (t);
-}
-
-/* Hasher for general trees, based on their TREE_HASH.  */
-struct tree_hash : ggc_ptr_hash <tree_node>
-{
-  static hashval_t hash (tree);
-};
-
-inline hashval_t
-tree_hash::hash (tree t)
-{
-  return TREE_HASH (t);
-}
-
 #endif
--- gcc/tree.h.jj	2019-11-15 00:37:26.293070143 +0100
+++ gcc/tree.h	2019-11-22 12:00:17.479478830 +0100
@@ -5351,6 +5351,58 @@  struct tree_decl_map_cache_hasher : ggc_
 #define tree_vec_map_hash tree_decl_map_hash
 #define tree_vec_map_marked_p tree_map_base_marked_p
 
+/* Hasher for tree decls.  Pointer equality is enough here, but the DECL_UID
+   is a better hash than the pointer value and gives a predictable traversal
+   order.  Additionally it can be used across PCH save/restore.  */
+struct tree_decl_hash : ggc_ptr_hash <tree_node>
+{
+  static inline hashval_t hash (tree);
+};
+
+inline hashval_t
+tree_decl_hash::hash (tree t)
+{
+  return DECL_UID (t);
+}
+
+/* Similarly for types.  Uses TYPE_UID as hash function.  */
+struct tree_type_hash : ggc_ptr_hash <tree_node>
+{
+  static inline hashval_t hash (tree);
+};
+
+inline hashval_t
+tree_type_hash::hash (tree t)
+{
+  return TYPE_UID (t);
+}
+
+/* Hash for SSA_NAMEs in the same function.  Pointer equality is enough
+   here, but the SSA_NAME_VERSION is a better hash than the pointer
+   value and gives a predictable traversal order.  */
+struct tree_ssa_name_hash : ggc_ptr_hash <tree_node>
+{
+  static inline hashval_t hash (tree);
+};
+
+inline hashval_t
+tree_ssa_name_hash::hash (tree t)
+{
+  return SSA_NAME_VERSION (t);
+}
+
+/* Hasher for general trees, based on their TREE_HASH.  */
+struct tree_hash : ggc_ptr_hash <tree_node>
+{
+  static hashval_t hash (tree);
+};
+
+inline hashval_t
+tree_hash::hash (tree t)
+{
+  return TREE_HASH (t);
+}
+
 /* A hash_map of two trees for use with GTY((cache)).  Garbage collection for
    such a map will not mark keys, and will mark values if the key is already
    marked.  */
@@ -5358,6 +5410,18 @@  struct tree_cache_traits
   : simple_cache_map_traits<default_hash_traits<tree>, tree> { };
 typedef hash_map<tree,tree,tree_cache_traits> tree_cache_map;
 
+/* Similarly, but use DECL_UID as hash function rather than pointer hashing.
+   This is for hash_maps from decls to trees that need to work across PCH.  */
+struct decl_tree_cache_traits
+  : simple_cache_map_traits<tree_decl_hash, tree> { };
+typedef hash_map<tree,tree,decl_tree_cache_traits> decl_tree_cache_map;
+
+/* Similarly, but use TYPE_UID as hash function rather than pointer hashing.
+   This is for hash_maps from types to trees that need to work across PCH.  */
+struct type_tree_cache_traits
+  : simple_cache_map_traits<tree_type_hash, tree> { };
+typedef hash_map<tree,tree,type_tree_cache_traits> type_tree_cache_map;
+
 /* Initialize the abstract argument list iterator object ITER with the
    arguments from CALL_EXPR node EXP.  */
 static inline void
--- gcc/cp/init.c.jj	2019-11-08 00:22:12.042424097 +0100
+++ gcc/cp/init.c	2019-11-22 11:50:11.285872353 +0100
@@ -548,7 +548,7 @@  perform_target_ctor (tree init)
 
 /* Return the non-static data initializer for FIELD_DECL MEMBER.  */
 
-static GTY((cache)) tree_cache_map *nsdmi_inst;
+static GTY((cache)) decl_tree_cache_map *nsdmi_inst;
 
 tree
 get_nsdmi (tree member, bool in_ctor, tsubst_flags_t complain)
--- gcc/cp/constraint.cc.jj	2019-11-11 21:04:02.104306246 +0100
+++ gcc/cp/constraint.cc	2019-11-22 11:47:05.621749384 +0100
@@ -1113,7 +1113,7 @@  build_constraints (tree tr, tree dr)
 
 /* A mapping from declarations to constraint information.  */
 
-static GTY ((cache)) tree_cache_map *decl_constraints;
+static GTY ((cache)) decl_tree_cache_map *decl_constraints;
 
 /* Returns the template constraints of declaration T. If T is not
    constrained, return NULL_TREE. Note that T must be non-null. */
--- gcc/cp/decl.c.jj	2019-11-19 22:26:46.289293903 +0100
+++ gcc/cp/decl.c	2019-11-22 11:49:01.954946691 +0100
@@ -7998,7 +7998,7 @@  get_tuple_decomp_init (tree decl, unsign
 /* It's impossible to recover the decltype of a tuple decomposition variable
    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 GTY((cache)) decl_tree_cache_map *decomp_type_table;
 
 tree
 lookup_decomp_type (tree v)
--- gcc/cp/pt.c.jj	2019-11-19 22:27:00.737077646 +0100
+++ gcc/cp/pt.c	2019-11-22 11:52:37.590605226 +0100
@@ -13272,7 +13272,7 @@  tsubst_aggr_type (tree t,
     }
 }
 
-static GTY((cache)) tree_cache_map *defarg_inst;
+static GTY((cache)) decl_tree_cache_map *defarg_inst;
 
 /* Substitute into the default argument ARG (a default argument for
    FN), which has the indicated TYPE.  */
@@ -13346,7 +13346,7 @@  tsubst_default_argument (tree fn, int pa
   if (arg != error_mark_node && !cp_unevaluated_operand)
     {
       if (!defarg_inst)
-	defarg_inst = tree_cache_map::create_ggc (37);
+	defarg_inst = decl_tree_cache_map::create_ggc (37);
       defarg_inst->put (parm, arg);
     }
 
@@ -13383,7 +13383,7 @@  tsubst_default_arguments (tree fn, tsubs
 }
 
 /* Hash table mapping a FUNCTION_DECL to its dependent explicit-specifier.  */
-static GTY((cache)) tree_cache_map *explicit_specifier_map;
+static GTY((cache)) decl_tree_cache_map *explicit_specifier_map;
 
 /* Store a pair to EXPLICIT_SPECIFIER_MAP.  */
 
@@ -13391,7 +13391,7 @@  void
 store_explicit_specifier (tree v, tree t)
 {
   if (!explicit_specifier_map)
-    explicit_specifier_map = tree_cache_map::create_ggc (37);
+    explicit_specifier_map = decl_tree_cache_map::create_ggc (37);
   DECL_HAS_DEPENDENT_EXPLICIT_SPEC_P (v) = true;
   explicit_specifier_map->put (v, t);
 }
--- gcc/cp/cp-objcp-common.c.jj	2019-11-06 08:58:38.189471399 +0100
+++ gcc/cp/cp-objcp-common.c	2019-11-22 11:51:28.090682190 +0100
@@ -123,7 +123,7 @@  cxx_types_compatible_p (tree x, tree y)
   return same_type_ignoring_top_level_qualifiers_p (x, y);
 }
 
-static GTY((cache)) tree_cache_map *debug_type_map;
+static GTY((cache)) type_tree_cache_map *debug_type_map;
 
 /* Return a type to use in the debug info instead of TYPE, or NULL_TREE to
    keep TYPE.  */
--- gcc/testsuite/g++.dg/pch/pr92458.C.jj	2019-11-22 11:46:31.465278668 +0100
+++ gcc/testsuite/g++.dg/pch/pr92458.C	2019-11-22 11:46:31.465278668 +0100
@@ -0,0 +1,5 @@ 
+// PR c++/92458
+// { dg-options "-std=c++2a" }
+
+#include "pr92458.H"
+S<int> s;
--- gcc/testsuite/g++.dg/pch/pr92458.Hs.jj	2019-11-22 11:46:31.466278653 +0100
+++ gcc/testsuite/g++.dg/pch/pr92458.Hs	2019-11-22 11:46:31.466278653 +0100
@@ -0,0 +1,7 @@ 
+// PR c++/92458
+// { dg-options "-std=c++2a" }
+
+template<typename T> concept C = sizeof(T) > 1;
+template<typename T> struct S { };
+template<typename T> requires C<T> struct S<T> { };
+template<typename T> requires (!C<T>) struct S<T> { };