[PATCH] c++: Don't purge the satisfaction caches
Patrick Palka
ppalka@redhat.com
Mon Nov 2 19:13:44 GMT 2020
On Mon, Nov 2, 2020 at 10:11 AM Jason Merrill <jason@redhat.com> wrote:
>
> On 11/2/20 9:03 AM, Patrick Palka wrote:
> > 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?
>
> OK. It would be nice to warn when a (now remembered) satisfaction value
> is determined by a class being incomplete. Maybe by checking whether
> we're in the middle of satisfaction when complete_type fails? Maybe
> only warn by defaul if the type is complete at EOF.
Thanks, committed as r11-4624. A warning like that sounds handy; I'll
look into implementing it for stage 1.
>
> >>
> >> 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
> >>
> >>
> >
>
More information about the Gcc-patches
mailing list