aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/constraint.cc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-11-09 18:12:47 -0500
committerPatrick Palka <ppalka@redhat.com>2020-11-09 18:12:47 -0500
commit2096ebd393a5a25921c85de1209b38c715924e22 (patch)
tree3e41d28c28f581e254a7d0065e729c452b282039 /gcc/cp/constraint.cc
parent71a8040716c1342547a19c25bd0203ac29258ef3 (diff)
downloadgcc-2096ebd393a5a25921c85de1209b38c715924e22.zip
gcc-2096ebd393a5a25921c85de1209b38c715924e22.tar.gz
gcc-2096ebd393a5a25921c85de1209b38c715924e22.tar.bz2
c++: Reuse identical ATOMIC_CONSTRs during normalization
Profiling revealed that sat_hasher::equal accounts for nearly 40% of compile time in some cmcstl2 tests. This patch eliminates this bottleneck by caching the ATOMIC_CONSTRs returned by normalize_atom. This in turn allows us to replace the expensive atomic_constraints_identical_p check in sat_hasher::equal with cheap pointer equality, with no loss in cache hit rate. With this patch, compile time for the cmcstl2 test test/algorithm/set_symmetric_difference4.cpp drops from 19s to 11s with an --enable-checking=release compiler. gcc/cp/ChangeLog: * constraint.cc (atom_cache): Define this deletable hash_table. (normalize_atom): Use it to cache ATOMIC_CONSTRs when not generating diagnostics. (sat_hasher::hash): Use htab_hash_pointer instead of hash_atomic_constraint. (sat_hasher::equal): Test for pointer equality instead of atomic_constraints_identical_p. * cp-tree.h (struct atom_hasher): Moved and renamed from ... * logic.cc (struct constraint_hash): ... here. (clause::m_set): Adjust accordingly.
Diffstat (limited to 'gcc/cp/constraint.cc')
-rw-r--r--gcc/cp/constraint.cc27
1 files changed, 24 insertions, 3 deletions
diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc
index c871a8a..613ced2 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);
}