On 4/20/23 11:44, Patrick Palka wrote:
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:
OK.
-- >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: