On Thu, 20 Apr 2023, Patrick Palka wrote:

> 1. Now that we no longer substitute the constraints of an auto, we can
>    get rid of the infinite recursion loop breaker during level lowering
>    of a constrained auto and we can also use the TEMPLATE_PARM_DESCENDANTS
>    cache in this case.
> 2. Don't bother recursing when level lowering a cv-qualified type template
>    parameter.
> 3. Use TEMPLATE_PARM_DESCENDANTS when level lowering a non-type template
>    parameter too.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
> trunk?
> 
> gcc/cp/ChangeLog:
> 
>       * pt.cc (tsubst) <case TEMPLATE_TYPE_PARM>: Remove infinite
>       recursion loop breaker in the level lowering case for
>       constrained autos.  Use the TEMPLATE_PARM_DESCENDANTS cache in
>       this case as well.
>       <case TEMPLATE_PARM_INDEX>: Use the TEMPLATE_PARM_INDEX cache
>       when level lowering a non-type template parameter.
> ---
>  gcc/cp/pt.cc | 42 ++++++++++++++++++++----------------------
>  1 file changed, 20 insertions(+), 22 deletions(-)
> 
> diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
> index f65f2d58b28..07e9736cdce 100644
> --- a/gcc/cp/pt.cc
> +++ b/gcc/cp/pt.cc
> @@ -16228,33 +16228,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
> tree in_decl)
>       /* If we get here, we must have been looking at a parm for a
>          more deeply nested template.  Make a new version of this
>          template parameter, but with a lower level.  */
> +     int quals;
>       switch (code)
>         {
>         case TEMPLATE_TYPE_PARM:
>         case TEMPLATE_TEMPLATE_PARM:
> -         if (cp_type_quals (t))
> +         quals = cp_type_quals (t);
> +         if (quals)
>             {
> -             r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
> -             r = cp_build_qualified_type
> -               (r, cp_type_quals (t),
> -                complain | (code == TEMPLATE_TYPE_PARM
> -                            ? tf_ignore_bad_quals : 0));
> +             gcc_checking_assert (code == TEMPLATE_TYPE_PARM);
> +             t = TYPE_MAIN_VARIANT (t);
>             }
> -         else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
> -                  && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t)
> -                  && (r = (TEMPLATE_PARM_DESCENDANTS
> -                           (TEMPLATE_TYPE_PARM_INDEX (t))))
> -                  && (r = TREE_TYPE (r))
> -                  && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (r))
> -           /* Break infinite recursion when substituting the constraints
> -              of a constrained placeholder.  */;
> -         else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
> -                  && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t)
> -                  && (arg = TEMPLATE_TYPE_PARM_INDEX (t),
> -                      r = TEMPLATE_PARM_DESCENDANTS (arg))
> -                  && (TEMPLATE_PARM_LEVEL (r)
> -                      == TEMPLATE_PARM_LEVEL (arg) - levels))
> -             /* Cache the simple case of lowering a type parameter.  */
> +         if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
> +             && (arg = TEMPLATE_TYPE_PARM_INDEX (t),
> +                 r = TEMPLATE_PARM_DESCENDANTS (arg))
> +             && (TEMPLATE_PARM_LEVEL (r)
> +                 == TEMPLATE_PARM_LEVEL (arg) - levels))
> +           /* Cache the simple case of lowering a type parameter.  */
>             r = TREE_TYPE (r);
>           else
>             {
> @@ -16278,6 +16268,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
> tree in_decl)
>               else
>                 TYPE_CANONICAL (r) = canonical_type_parameter (r);
>             }
> +         if (quals)
> +           r = cp_build_qualified_type (r, quals,
> +                                        complain | tf_ignore_bad_quals);
>           break;
>  
>         case BOUND_TEMPLATE_TEMPLATE_PARM:
> @@ -16307,7 +16300,12 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
> tree in_decl)
>           type = tsubst (type, args, complain, in_decl);
>           if (type == error_mark_node)
>             return error_mark_node;
> -         r = reduce_template_parm_level (t, type, levels, args, complain);
> +         if ((r = TEMPLATE_PARM_DESCENDANTS (t))
> +             && (TEMPLATE_PARM_LEVEL (r) == TEMPLATE_PARM_LEVEL (t) - levels)
> +             && TREE_TYPE (r) == type)
> +           /* Cache the simple case of lowering a non-type parameter.  */;
> +         else
> +           r = reduce_template_parm_level (t, type, levels, args, complain);

D'oh, this hunk is totally redundant since reduce_template_parm_level
already checks TEMPLATE_PARM_DESCENDANTS, and so we've been caching
level-lowering of non-type template parameters this whole time.

Please consider this patch instead, which removes this hunk and
therefore only changes TEMPLATE_TYPE_PARM level lowering:

-- >8 --

Subject: [PATCH] c++: improve TEMPLATE_TYPE_PARM level lowering

1. Don't bother recursing when level lowering a cv-qualified type template
   parameter.
2. Get rid of the infinite recursion loop breaker during level lowering of
   a constrained auto and use the TEMPLATE_PARM_DESCENDANTS cache in this
   case too, now that we no longer substitute its constraints.

gcc/cp/ChangeLog:

        * pt.cc (tsubst) <case TEMPLATE_TYPE_PARM>: Don't recurse when
        level lowering a cv-qualified type template parameter.  Remove
        infinite recursion loop breaker in the level lowering case for
        constrained autos.  Use the TEMPLATE_PARM_DESCENDANTS cache in
        this case as well.
---
 gcc/cp/pt.cc | 35 ++++++++++++++---------------------
 1 file changed, 14 insertions(+), 21 deletions(-)

diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index f65f2d58b28..ed038b9ca24 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -16228,33 +16228,23 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
tree in_decl)
        /* If we get here, we must have been looking at a parm for a
           more deeply nested template.  Make a new version of this
           template parameter, but with a lower level.  */
+       int quals;
        switch (code)
          {
          case TEMPLATE_TYPE_PARM:
          case TEMPLATE_TEMPLATE_PARM:
-           if (cp_type_quals (t))
+           quals = cp_type_quals (t);
+           if (quals)
              {
-               r = tsubst (TYPE_MAIN_VARIANT (t), args, complain, in_decl);
-               r = cp_build_qualified_type
-                 (r, cp_type_quals (t),
-                  complain | (code == TEMPLATE_TYPE_PARM
-                              ? tf_ignore_bad_quals : 0));
+               gcc_checking_assert (code == TEMPLATE_TYPE_PARM);
+               t = TYPE_MAIN_VARIANT (t);
              }
-           else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
-                    && PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t)
-                    && (r = (TEMPLATE_PARM_DESCENDANTS
-                             (TEMPLATE_TYPE_PARM_INDEX (t))))
-                    && (r = TREE_TYPE (r))
-                    && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (r))
-             /* Break infinite recursion when substituting the constraints
-                of a constrained placeholder.  */;
-           else if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
-                    && !PLACEHOLDER_TYPE_CONSTRAINTS_INFO (t)
-                    && (arg = TEMPLATE_TYPE_PARM_INDEX (t),
-                        r = TEMPLATE_PARM_DESCENDANTS (arg))
-                    && (TEMPLATE_PARM_LEVEL (r)
-                        == TEMPLATE_PARM_LEVEL (arg) - levels))
-               /* Cache the simple case of lowering a type parameter.  */
+           if (TREE_CODE (t) == TEMPLATE_TYPE_PARM
+               && (arg = TEMPLATE_TYPE_PARM_INDEX (t),
+                   r = TEMPLATE_PARM_DESCENDANTS (arg))
+               && (TEMPLATE_PARM_LEVEL (r)
+                   == TEMPLATE_PARM_LEVEL (arg) - levels))
+             /* Cache the simple case of lowering a type parameter.  */
              r = TREE_TYPE (r);
            else
              {
@@ -16278,6 +16268,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, 
tree in_decl)
                else
                  TYPE_CANONICAL (r) = canonical_type_parameter (r);
              }
+           if (quals)
+             r = cp_build_qualified_type (r, quals,
+                                          complain | tf_ignore_bad_quals);
            break;
 
          case BOUND_TEMPLATE_TEMPLATE_PARM:
-- 
2.40.0.352.g667fcf4e15

Reply via email to