On Fri, 23 Jun 2023, Jason Merrill wrote: > On 6/21/23 13:19, Patrick Palka wrote: > > When stepping through the variable/alias template specialization code > > paths, I noticed we perform template argument coercion twice: first from > > instantiate_alias_template / finish_template_variable and again from > > tsubst_decl (during instantiate_template). It should suffice to perform > > coercion once. > > > > To that end patch elides this second coercion from tsubst_decl when > > possible. We can't get rid of it completely because we don't always > > specialize a variable template from finish_template_variable: we could > > also be doing so directly from instantiate_template during variable > > template partial specialization selection, in which case the coercion > > from tsubst_decl would be the first and only coercion. > > Perhaps we should be coercing in lookup_template_variable rather than > finish_template_variable?
Ah yes, there's a patch for that at https://gcc.gnu.org/pipermail/gcc-patches/2023-May/617377.html :) > It looks like we currently get to > most_specialized_partial_spec with args that haven't yet been coerced to match > the primary template. The call to most_specialized_partial_spec from instantiate_template? I believe the arguments should already have been coerced by the caller, which is presumably always finish_template_variable. So in that patch I also made instantiate_template use build2 (TEMPLATE_ID_EXPR, ...) directly instead of calling lookup_template_variable, to avoid an unnecessary double coercion. > > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for > > trunk? This reduces memory usage of range-v3's zip.cpp by ~0.5%. > > > > gcc/cp/ChangeLog: > > > > * pt.cc (tsubst_decl) <case TYPE_/VAR_DECL>: Call > > coercion_template_parms only if DECL_TEMPLATE_SPECIALIZATION > > is set. > > --- > > gcc/cp/pt.cc | 15 +++++++++++---- > > 1 file changed, 11 insertions(+), 4 deletions(-) > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > index be86051abad..dd10409ce18 100644 > > --- a/gcc/cp/pt.cc > > +++ b/gcc/cp/pt.cc > > @@ -15232,10 +15232,17 @@ tsubst_decl (tree t, tree args, tsubst_flags_t > > complain) > > argvec = tsubst (DECL_TI_ARGS (t), args, complain, in_decl); > > if (argvec != error_mark_node > > && PRIMARY_TEMPLATE_P (gen_tmpl) > > - && TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (argvec)) > > - /* We're fully specializing a template declaration, so > > - we need to coerce the innermost arguments corresponding > > to > > - the template. */ > > + && TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (argvec) > > + && DECL_TEMPLATE_SPECIALIZATION (t)) > > + /* We're fully specializing an alias or variable template, > > so > > + coerce the innermost arguments if necessary. We expect > > + instantiate_alias_template and finish_template_variable > > to > > + already have done this relative to the primary template, > > in > > + which case this coercion is unnecessary, but we can also > > + get here when substituting a partial variable template > > + specialization (directly from instantiate_template), in > > + which case DECL_TEMPLATE_SPECIALIZATION is set and > > coercion > > + is necessary. */ > > argvec = (coerce_template_parms > > (DECL_TEMPLATE_PARMS (gen_tmpl), > > argvec, tmpl, complain)); > >