[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