For a specific testcase a lot of compile-time is spent in re-hashing
hashtable elements upon expansion.  The following records the hash
in the hash element.  This speeds up compilation by 20%.

There's probably module-related uses that need to be adjusted.

Bootstrap failed (guess I was expecting this), but still I think this
is a good idea - maybe somebody can pick it up.  Possibly instead
of having a single global hash table having one per ID would be
better.  The hashtable also keeps things GC-live ('args' for example).

gcc/cp/
        * cp-tree.h (spec_entry::hash): New member.
        * pt.cc (spec_hasher::hash): Return the elements recorded hash.
        (lookup_template_class): Record the hash in the element.
---
 gcc/cp/cp-tree.h | 1 +
 gcc/cp/pt.cc     | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index c5d02567cb4..56345214d8f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -5843,6 +5843,7 @@ 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.  */
+  hashval_t hash;
 };
 
 /* in class.cc */
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 2c8b0d8609d..11f84133fa7 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -1739,7 +1739,7 @@ spec_hasher::hash (tree tmpl, tree args)
 hashval_t
 spec_hasher::hash (spec_entry *e)
 {
-  return spec_hasher::hash (e->tmpl, e->args);
+  return e->hash;
 }
 
 /* Recursively calculate a hash value for a template argument ARG, for use
@@ -10234,7 +10234,7 @@ lookup_template_class (tree d1, tree arglist, tree 
in_decl, tree context,
       elt.tmpl = gen_tmpl;
       elt.args = arglist;
       elt.spec = NULL_TREE;
-      hash = spec_hasher::hash (&elt);
+      hash = elt.hash = spec_hasher::hash (gen_tmpl, arglist);
       entry = type_specializations->find_with_hash (&elt, hash);
 
       if (entry)
@@ -10519,7 +10519,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);
+             hash = elt.hash = spec_hasher::hash (found, arglist);
            }
        }
 
-- 
2.43.0

Reply via email to