diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c5d02567cb4b07b3423416e4d47a1af1c0b8265b..dc153a97dc46171c9f9922f20dab20668e2f954c 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5840,9 +5840,14 @@ public: /* Entry in the specialization hash table. */ struct GTY((for_user)) spec_entry { - tree tmpl; /* The general template this is a specialization of. */ - tree args; /* The args for this (maybe-partial) specialization. */ - tree spec; /* The specialization itself. */ + /* The general template this is a specialization of. */ + tree tmpl; + /* The args for this (maybe-partial) specialization. */ + tree args; + /* The specialization itself. */ + tree spec = NULL_TREE; + /* The cached result of hash_tmpl_and_args (tmpl, args). */ + hashval_t hash = 0; }; /* in class.cc */ diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc index 4ceae1d38de1be7fb9ffcf017400b4a4091ce83d..03a1144765b22d38f3f9098b0edce9f4b1e860c8 100644 --- a/gcc/cp/pt.cc +++ b/gcc/cp/pt.cc @@ -1161,6 +1161,7 @@ maybe_process_partial_specialization (tree type) elt.tmpl = tmpl; CLASSTYPE_TI_ARGS (inst) = elt.args = INNERMOST_TEMPLATE_ARGS (elt.args); + elt.hash = 0; /* Recalculate after changing tmpl/args. */ spec_entry **slot = type_specializations->find_slot (&elt, INSERT); @@ -1282,7 +1283,7 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash) spec_entry elt; elt.tmpl = tmpl; elt.args = args; - elt.spec = NULL_TREE; + elt.hash = hash; spec_hash_table *specializations; if (DECL_CLASS_TEMPLATE_P (tmpl)) @@ -1290,9 +1291,7 @@ retrieve_specialization (tree tmpl, tree args, hashval_t hash) else specializations = decl_specializations; - if (hash == 0) - hash = spec_hasher::hash (&elt); - if (spec_entry *found = specializations->find_with_hash (&elt, hash)) + if (spec_entry *found = specializations->find (&elt)) return found->spec; return NULL_TREE; @@ -1551,7 +1550,7 @@ register_specialization (tree spec, tree tmpl, tree args, bool is_friend, if (hash == 0) hash = spec_hasher::hash (&elt); - spec_entry **slot = decl_specializations->find_slot_with_hash (&elt, hash, INSERT); + spec_entry **slot = decl_specializations->find_slot (&elt, INSERT); if (*slot) fn = (*slot)->spec; else @@ -1739,7 +1738,9 @@ spec_hasher::hash (tree tmpl, tree args) hashval_t spec_hasher::hash (spec_entry *e) { - return spec_hasher::hash (e->tmpl, e->args); + if (e->hash == 0) + e->hash = hash (e->tmpl, e->args); + return e->hash; } /* Recursively calculate a hash value for a template argument ARG, for use @@ -1973,7 +1974,6 @@ reregister_specialization (tree spec, tree tinfo, tree new_spec) elt.tmpl = most_general_template (TI_TEMPLATE (tinfo)); elt.args = TI_ARGS (tinfo); - elt.spec = NULL_TREE; entry = decl_specializations->find (&elt); if (entry != NULL) @@ -10019,8 +10019,6 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, tree t; spec_entry **slot; spec_entry *entry; - spec_entry elt; - hashval_t hash; if (identifier_p (d1)) { @@ -10236,11 +10234,10 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, } /* If we already have this specialization, return it. */ + spec_entry elt; elt.tmpl = gen_tmpl; elt.args = arglist; - elt.spec = NULL_TREE; - hash = spec_hasher::hash (&elt); - entry = type_specializations->find_with_hash (&elt, hash); + entry = type_specializations->find (&elt); if (entry) return entry->spec; @@ -10303,7 +10300,7 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, { /* Completion could have caused us to register the desired specialization already, so check the table again. */ - entry = type_specializations->find_with_hash (&elt, hash); + entry = type_specializations->find (&elt); if (entry) return entry->spec; } @@ -10524,7 +10521,7 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, use it for hash table lookup. */ elt.tmpl = found; elt.args = arglist = INNERMOST_TEMPLATE_ARGS (arglist); - hash = spec_hasher::hash (&elt); + elt.hash = 0; /* Recalculate after changing tmpl/args. */ } } @@ -10532,7 +10529,7 @@ lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, SET_TYPE_TEMPLATE_INFO (t, build_template_info (found, arglist)); elt.spec = t; - slot = type_specializations->find_slot_with_hash (&elt, hash, INSERT); + slot = type_specializations->find_slot (&elt, INSERT); gcc_checking_assert (*slot == NULL); entry = ggc_alloc<spec_entry> (); *entry = elt; @@ -31654,8 +31651,7 @@ match_mergeable_specialization (bool decl_p, spec_entry *elt) { hash_table<spec_hasher> *specializations = decl_p ? decl_specializations : type_specializations; - hashval_t hash = spec_hasher::hash (elt); - auto *slot = specializations->find_slot_with_hash (elt, hash, NO_INSERT); + auto *slot = specializations->find_slot (elt, NO_INSERT); if (slot) return (*slot)->spec; @@ -31703,10 +31699,9 @@ void add_mergeable_specialization (bool decl_p, spec_entry *elt, tree decl, unsigned flags) { - hashval_t hash = spec_hasher::hash (elt); if (decl_p) { - auto *slot = decl_specializations->find_slot_with_hash (elt, hash, INSERT); + auto *slot = decl_specializations->find_slot (elt, INSERT); gcc_checking_assert (!*slot); auto entry = ggc_alloc<spec_entry> (); @@ -31715,7 +31710,7 @@ add_mergeable_specialization (bool decl_p, spec_entry *elt, tree decl, } else { - auto *slot = type_specializations->find_slot_with_hash (elt, hash, INSERT); + auto *slot = type_specializations->find_slot (elt, INSERT); /* We don't distinguish different constrained partial type specializations, so there could be duplicates. Everything else