diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc index c871a8ab86a807420a8f0a6c48662cfaf16440dc..613ced26e2b2dd55db169e1dbfa0f1a8c7d0cd65 100644 --- a/gcc/cp/constraint.cc +++ b/gcc/cp/constraint.cc @@ -710,6 +710,10 @@ normalize_concept_check (tree check, tree args, norm_info info) return normalize_expression (def, subst, info); } +/* Used by normalize_atom to cache ATOMIC_CONSTRs. */ + +static GTY((deletable)) hash_table<atom_hasher> *atom_cache; + /* The normal form of an atom depends on the expression. The normal form of a function call to a function concept is a check constraint for that concept. The normal form of a reference to a variable @@ -729,7 +733,19 @@ normalize_atom (tree t, tree args, norm_info info) /* Build a new info object for the atom. */ tree ci = build_tree_list (t, info.context); - return build1 (ATOMIC_CONSTR, ci, map); + tree atom = build1 (ATOMIC_CONSTR, ci, map); + if (!info.generate_diagnostics ()) + { + /* Cache the ATOMIC_CONSTRs that we return, so that sat_hasher::equal + later can cheaply compare two atoms using just pointer equality. */ + if (!atom_cache) + atom_cache = hash_table<atom_hasher>::create_ggc (31); + tree *slot = atom_cache->find_slot (atom, INSERT); + if (*slot) + return *slot; + *slot = atom; + } + return atom; } /* Returns the normal form of an expression. */ @@ -2294,13 +2310,18 @@ struct sat_hasher : ggc_ptr_hash<sat_entry> { static hashval_t hash (sat_entry *e) { - hashval_t value = hash_atomic_constraint (e->constr); + /* Since normalize_atom caches the ATOMIC_CONSTRs it returns, + we can assume pointer-based identity for fast hashing and + comparison. Even if this assumption is violated, that's + okay, we'll just get a cache miss. */ + hashval_t value = htab_hash_pointer (e->constr); return iterative_hash_template_arg (e->args, value); } static bool equal (sat_entry *e1, sat_entry *e2) { - if (!atomic_constraints_identical_p (e1->constr, e2->constr)) + /* As in sat_hasher::hash. */ + if (e1->constr != e2->constr) return false; return template_args_equal (e1->args, e2->args); } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 081373076b99ebbe777cd59c99181029b43c0058..c7e25dfec8d46335f8f0c09b415e23acd32d97b9 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -7839,6 +7839,21 @@ extern hashval_t iterative_hash_constraint (tree, hashval_t); extern hashval_t hash_atomic_constraint (tree); extern void diagnose_constraints (location_t, tree, tree); +/* A structural hasher for ATOMIC_CONSTRs. */ + +struct atom_hasher : default_hash_traits<tree> +{ + static hashval_t hash (tree t) + { + return hash_atomic_constraint (t); + } + + static bool equal (tree t1, tree t2) + { + return atomic_constraints_identical_p (t1, t2); + } +}; + /* in logic.cc */ extern bool subsumes (tree, tree); diff --git a/gcc/cp/logic.cc b/gcc/cp/logic.cc index 194b743192d478a3323bbc27f08f44f635d080f9..6701488bc1cce9af2957b6c15e0a0d6f065f54cd 100644 --- a/gcc/cp/logic.cc +++ b/gcc/cp/logic.cc @@ -47,21 +47,6 @@ along with GCC; see the file COPYING3. If not see #include "toplev.h" #include "type-utils.h" -/* Hash functions for atomic constrains. */ - -struct constraint_hash : default_hash_traits<tree> -{ - static hashval_t hash (tree t) - { - return hash_atomic_constraint (t); - } - - static bool equal (tree t1, tree t2) - { - return atomic_constraints_identical_p (t1, t2); - } -}; - /* A conjunctive or disjunctive clause. Each clause maintains an iterator that refers to the current @@ -219,7 +204,7 @@ struct clause } std::list<tree> m_terms; /* The list of terms. */ - hash_set<tree, false, constraint_hash> m_set; /* The set of atomic constraints. */ + hash_set<tree, false, atom_hasher> m_set; /* The set of atomic constraints. */ iterator m_current; /* The current term. */ };