public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Jason Merrill <jason@redhat.com>
To: Patrick Palka <ppalka@redhat.com>
Cc: gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] c++: redundant targ coercion for var/alias tmpls
Date: Fri, 14 Jul 2023 17:17:05 -0400	[thread overview]
Message-ID: <5502feae-d5ef-092e-3f29-2b4fa9f38224@redhat.com> (raw)
In-Reply-To: <9e51de65-9910-445b-1ec7-8a3cd47114fc@idea>

On 7/14/23 14:07, Patrick Palka wrote:
> On Thu, 13 Jul 2023, Jason Merrill wrote:
> 
>> On 7/13/23 11:48, Patrick Palka wrote:
>>> On Wed, 28 Jun 2023, Patrick Palka wrote:
>>>
>>>> On Wed, Jun 28, 2023 at 11:50 AM Jason Merrill <jason@redhat.com> wrote:
>>>>>
>>>>> On 6/23/23 12:23, Patrick Palka wrote:
>>>>>> 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 :)
>>>>>
>>>>> So after that patch, can we get rid of the second coercion completely?
>>>>
>>>> On second thought it should be possible to get rid of it, if we
>>>> rearrange things to always pass the primary arguments to tsubst_decl,
>>>> and perform partial specialization selection from there instead of
>>>> instantiate_template.  Let me try...
>>>
>>> Like so?  Bootstrapped and regtested on x86_64-pc-linux-gnu.
>>>
>>> -- >8 --
>>>
>>> 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'd be good to avoid this
>>> redundant coercion.
>>>
>>> It turns out that this coercion could be safely elided whenever
>>> specializing a primary variable/alias template, because we can rely on
>>> lookup_template_variable and instantiate_alias_template to already have
>>> coerced the arguments.
>>>
>>> The other situation to consider is when fully specializing a partial
>>> variable template specialization (from instantiate_template), in which
>>> case the passed 'args' are the (already coerced) arguments relative to
>>> the partial template and 'argvec', the result of substitution into
>>> DECL_TI_ARGS, are the (uncoerced) arguments relative to the primary
>>> template, so coercion is still necessary.  We can still avoid this
>>> coercion however if we always pass the primary variable template to
>>> tsubst_decl from instantiate_template, and instead perform partial
>>> specialization selection directly from tsubst_decl.  This patch
>>> implements this approach.
>>
>> The relationship between instantiate_template and tsubst_decl is pretty
>> tangled.  We use the former to substitute (often deduced) template arguments
>> into a template, and the latter to substitute template arguments into a use of
>> a template...and also to implement the former.
>>
>> For substitution of uses of a template, we expect to need to coerce the
>> arguments after substitution.  But we avoid this issue for variable templates
>> by keeping them as TEMPLATE_ID_EXPR until substitution time, so if we see a
>> VAR_DECL in tsubst_decl it's either a non-template variable or under
>> instantiate_template.
> 
> FWIW it seems we could also be in tsubst_decl for a VAR_DECL if
> 
>    * we're partially instantiating a class-scope variable template
>      during instantiation of the class

Hmm, why don't partial instantiations stay as TEMPLATE_ID_EXPR?

>    * we're substituting a use of an already non-dependent variable
>      template specialization

Sure.

>> So it seems like the current coercion for variable templates is only needed in
>> this case to support the redundant hash table lookup that we just did in
>> instantiate_template.  Perhaps instead of doing coercion here or moving the
>> partial spec lookup, we could skip the hash table lookup for the case of a
>> variable template?
> 
> It seems we'd then also have to make instantiate_template responsible
> for registering the variable template specialization since tsubst_decl
> no longer necessarily has the arguments relative to the primary template
> ('args' could be relative to the partial template).
> 
> Like so?  The following makes us perform all the specialization table
> manipulation in instantiate_template instead of tsubst_decl for variable
> template specializations.

Looks good.

> I wonder if we might want to do this for alias template specializations too?

That would make sense.

> @@ -15222,20 +15230,21 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
>   	      {
>   		tmpl = DECL_TI_TEMPLATE (t);
>   		gen_tmpl = most_general_template (tmpl);
> -		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.  */
> -		  argvec = (coerce_template_parms
> -			    (DECL_TEMPLATE_PARMS (gen_tmpl),
> -			     argvec, tmpl, complain));
> -		if (argvec == error_mark_node)
> -		  RETURN (error_mark_node);
> -		hash = spec_hasher::hash (gen_tmpl, argvec);
> -		spec = retrieve_specialization (gen_tmpl, argvec, hash);
> +		if (variable_template_p (tmpl)
> +		    && (TMPL_ARGS_DEPTH (args)
> +			>= TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (gen_tmpl))))

Do we still need to compare depths?  If not, we could also skip 
computing gen_tmpl in this case.

Jason


  reply	other threads:[~2023-07-14 21:17 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-21 17:19 Patrick Palka
2023-06-23 15:11 ` Jason Merrill
2023-06-23 16:23   ` Patrick Palka
2023-06-28 15:50     ` Jason Merrill
2023-06-28 20:14       ` Patrick Palka
2023-07-13 15:48         ` Patrick Palka
2023-07-13 20:44           ` Jason Merrill
2023-07-14 18:07             ` Patrick Palka
2023-07-14 21:17               ` Jason Merrill [this message]
2023-07-17 21:29                 ` Patrick Palka
2023-07-18 16:52                   ` Jason Merrill

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5502feae-d5ef-092e-3f29-2b4fa9f38224@redhat.com \
    --to=jason@redhat.com \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=ppalka@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).