On Tue, 27 Oct 2020, Patrick Palka wrote: > The adoption of P2104 means we can memoize the result of satisfaction > indefinitely and no longer have to clear the satisfaction caches on > various events that would affect satisfaction. To that end, this patch > removes clear_satisfaction_cache and adjusts its callers appropriately. > > This provides a massive reduction in compile time and memory use in some > cases. For example, on the libstdc++ test std/ranges/adaptor/join.cc, > compile time and memory usage drops nearly 75%, from 7.5s/770MB to > 2s/230MB, with a --enable-checking=release compiler. > > [ This patch depends on > > c++: Check constraints only for candidate conversion functions. > > Without it, many of the libstdc++ range adaptor tests fail due to > us now indefinitely memoizing a bogus satisfaction result caused by > checking the constraints of a conversion function when we weren't > supposed to, which led to a "use of foo_view::end() before deduction > of auto" SFINAE error. This went unnoticed without this patch because > by the time we needed this satisfaction result again, we had cleared > the satisfaction cache and finished deducing the return type of > foo_view::end(), so on subsequent tries we computed the correct > satisfaction result. ]
With the library-side workaround r11-4584 for the range adaptor test failures now committed, the mentioned frontend patch about candidate conversion functions is no longer a prerequisite (and was not we want anyway). > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > trunk (pending approval of the prerequisite patch)? Also tested on > cmcstl2 and range-v3. Now successfully bootstrapped and regtested on top of r11-4584, and also tested on cmcstl2 and range-v3. Does this look OK for trunk? > > gcc/cp/ChangeLog: > > * class.c (finish_struct_1): Don't call clear_satisfaction_cache. > * constexpr.c (clear_cv_and_fold_caches): Likewise. Remove bool > parameter. > * constraint.cc (clear_satisfaction_cache): Remove definition. > * cp-tree.h (clear_satisfaction_cache): Remove declaration. > (clear_cv_and_fold_caches): Remove bool parameter. > * typeck2.c (store_init_value): Remove argument to > clear_cv_and_fold_caches. > > gcc/testsuite/ChangeLog: > > * g++.dg/cpp2a/concept-complete1.C: Delete ill-formed test. > --- > gcc/cp/class.c | 3 --- > gcc/cp/constexpr.c | 6 ++---- > gcc/cp/constraint.cc | 9 --------- > gcc/cp/cp-tree.h | 3 +-- > gcc/cp/typeck2.c | 2 +- > gcc/testsuite/g++.dg/cpp2a/concepts-complete1.C | 11 ----------- > 6 files changed, 4 insertions(+), 30 deletions(-) > delete mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts-complete1.C > > diff --git a/gcc/cp/class.c b/gcc/cp/class.c > index 26f996b7f4b..6c21682a3e5 100644 > --- a/gcc/cp/class.c > +++ b/gcc/cp/class.c > @@ -7472,9 +7472,6 @@ finish_struct_1 (tree t) > /* Finish debugging output for this type. */ > rest_of_type_compilation (t, ! LOCAL_CLASS_P (t)); > > - /* Recalculate satisfaction that might depend on completeness. */ > - clear_satisfaction_cache (); > - > if (TYPE_TRANSPARENT_AGGR (t)) > { > tree field = first_field (t); > diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c > index 7ebdd308dcd..ec60db4a44b 100644 > --- a/gcc/cp/constexpr.c > +++ b/gcc/cp/constexpr.c > @@ -7085,15 +7085,13 @@ clear_cv_cache (void) > cv_cache->empty (); > } > > -/* Dispose of the whole CV_CACHE, FOLD_CACHE, and satisfaction caches. */ > +/* Dispose of the whole CV_CACHE and FOLD_CACHE. */ > > void > -clear_cv_and_fold_caches (bool sat /*= true*/) > +clear_cv_and_fold_caches () > { > clear_cv_cache (); > clear_fold_cache (); > - if (sat) > - clear_satisfaction_cache (); > } > > /* Internal function handling expressions in templates for > diff --git a/gcc/cp/constraint.cc b/gcc/cp/constraint.cc > index 75457a2dd60..8c0111a6409 100644 > --- a/gcc/cp/constraint.cc > +++ b/gcc/cp/constraint.cc > @@ -2354,15 +2354,6 @@ save_satisfaction (tree constr, tree args, tree result) > *slot = entry; > } > > -void > -clear_satisfaction_cache () > -{ > - if (sat_cache) > - sat_cache->empty (); > - if (decl_satisfied_cache) > - decl_satisfied_cache->empty (); > -} > - > /* A tool to help manage satisfaction caching in satisfy_constraint_r. > Note the cache is only used when not diagnosing errors. */ > > diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h > index 1ce20989e13..7a6efca6121 100644 > --- a/gcc/cp/cp-tree.h > +++ b/gcc/cp/cp-tree.h > @@ -7834,7 +7834,6 @@ extern tree evaluate_concept_check (tree, > tsubst_flags_t); > extern tree satisfy_constraint_expression (tree); > extern bool constraints_satisfied_p (tree); > extern bool constraints_satisfied_p (tree, tree); > -extern void clear_satisfaction_cache (); > extern bool* lookup_subsumption_result (tree, tree); > extern bool save_subsumption_result (tree, tree, bool); > extern tree find_template_parameters (tree, tree); > @@ -7904,7 +7903,7 @@ extern bool var_in_maybe_constexpr_fn (tree); > extern void explain_invalid_constexpr_fn (tree); > extern vec<tree> cx_error_context (void); > extern tree fold_sizeof_expr (tree); > -extern void clear_cv_and_fold_caches (bool = true); > +extern void clear_cv_and_fold_caches (void); > extern tree unshare_constructor (tree > CXX_MEM_STAT_INFO); > > /* An RAII sentinel used to restrict constexpr evaluation so that it > diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c > index e259a4201be..445e2a211c8 100644 > --- a/gcc/cp/typeck2.c > +++ b/gcc/cp/typeck2.c > @@ -954,7 +954,7 @@ store_init_value (tree decl, tree init, vec<tree, > va_gc>** cleanups, int flags) > return split_nonconstant_init (decl, value); > > /* DECL may change value; purge caches. */ > - clear_cv_and_fold_caches (TREE_STATIC (decl)); > + clear_cv_and_fold_caches (); > > /* If the value is a constant, just put it in DECL_INITIAL. If DECL > is an automatic variable, the middle end will turn this into a > diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts-complete1.C > b/gcc/testsuite/g++.dg/cpp2a/concepts-complete1.C > deleted file mode 100644 > index 63f36965f00..00000000000 > --- a/gcc/testsuite/g++.dg/cpp2a/concepts-complete1.C > +++ /dev/null > @@ -1,11 +0,0 @@ > -// { dg-do compile { target c++20 } } > - > -template <class T> concept has_mem_type = requires { typename T::type; }; > - > -template <has_mem_type T> int f () { return 0; } > -template <class T> char f() { return 0; } > - > -struct A; > -static_assert (sizeof (f<A>()) == 1); > -struct A { typedef int type; }; > -static_assert (sizeof (f<A>()) > 1); > -- > 2.29.0.rc0 > >