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.  ]

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.

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

Reply via email to