On Mon, 7 Oct 2024, Jason Merrill wrote: > On 10/7/24 10:26 AM, Patrick Palka wrote: > > On Mon, 7 Oct 2024, Jason Merrill wrote: > > > > > On 10/7/24 9:58 AM, Patrick Palka wrote: > > > > On Sat, 5 Oct 2024, Jason Merrill wrote: > > > > > > > > > On 10/4/24 11:00 AM, Patrick Palka wrote: > > > > > > On Thu, 3 Oct 2024, Jason Merrill wrote: > > > > > > > > > > > > > On 10/3/24 12:38 PM, Jason Merrill wrote: > > > > > > > > On 10/2/24 7:50 AM, Richard Biener wrote: > > > > > > > > > This reduces peak memory usage by 20% for a specific testcase. > > > > > > > > > > > > > > > > > > Bootstrapped and tested on x86_64-unknown-linux-gnu. > > > > > > > > > > > > > > > > > > It's very ugly so I'd appreciate suggestions on how to handle > > > > > > > > > such > > > > > > > > > situations better? > > > > > > > > > > > > > > > > I'm pushing this alternative patch, tested x86_64-pc-linux-gnu. > > > > > > > > > > > > > > OK, apparently that was both too clever and not clever enough. > > > > > > > Replacing > > > > > > > it > > > > > > > with this one that's much closer to yours. > > > > > > > > > > > > > > Jason > > > > > > > > > > > > > From: Jason Merrill <ja...@redhat.com> > > > > > > > Date: Thu, 3 Oct 2024 16:31:00 -0400 > > > > > > > Subject: [PATCH] c++: free garbage vec in coerce_template_parms > > > > > > > To: gcc-patches@gcc.gnu.org > > > > > > > > > > > > > > coerce_template_parms can create two different vecs for the inner > > > > > > > template > > > > > > > arguments, new_inner_args and (potentially) the result of > > > > > > > expand_template_argument_pack. One or the other, or possibly > > > > > > > both, > > > > > > > end up > > > > > > > being garbage: in the typical case, the expanded vec is garbage > > > > > > > because > > > > > > > it's > > > > > > > only used as the source for convert_template_argument. In some > > > > > > > dependent > > > > > > > cases, the new vec is garbage because we decide to return the > > > > > > > original > > > > > > > args > > > > > > > instead. In these cases, ggc_free the garbage vec to reduce the > > > > > > > memory > > > > > > > overhead of overload resolution. > > > > > > > > > > > > > > gcc/cp/ChangeLog: > > > > > > > > > > > > > > * pt.cc (coerce_template_parms): Free garbage vecs. > > > > > > > > > > > > > > Co-authored-by: Richard Biener <rguent...@suse.de> > > > > > > > --- > > > > > > > gcc/cp/pt.cc | 10 +++++++++- > > > > > > > 1 file changed, 9 insertions(+), 1 deletion(-) > > > > > > > > > > > > > > diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc > > > > > > > index 20affcd65a2..4ceae1d38de 100644 > > > > > > > --- a/gcc/cp/pt.cc > > > > > > > +++ b/gcc/cp/pt.cc > > > > > > > @@ -9275,6 +9275,7 @@ coerce_template_parms (tree parms, > > > > > > > { > > > > > > > /* We don't know how many args we have yet, just > > > > > > > use the > > > > > > > unconverted (and still packed) ones for now. > > > > > > > */ > > > > > > > + ggc_free (new_inner_args); > > > > > > > new_inner_args = orig_inner_args; > > > > > > > arg_idx = nargs; > > > > > > > break; > > > > > > > @@ -9329,7 +9330,8 @@ coerce_template_parms (tree parms, > > > > > > > = make_pack_expansion (conv, complain); > > > > > > > /* We don't know how many args we have yet, > > > > > > > just > > > > > > > - use the unconverted ones for now. */ > > > > > > > + use the unconverted (but unpacked) ones for now. */ > > > > > > > + ggc_free (new_inner_args); > > > > > > > > > > > > I'm a bit worried about these ggc_frees. If an earlier template > > > > > > parameter is a constrained auto NTTP then new_inner_args/new_args > > > > > > could > > > > > > have been captured by the satisfaction cache during coercion for > > > > > > that > > > > > > argument, and so we'd be freeing a vector that's still live? > > > > > > > > > > It seems like for e.g. > > > > > > > > > > template <class T> concept NotInt = !__is_same (T, int); > > > > > template <NotInt auto NI, class U> struct A { }; > > > > > template <class...Ts> using B = A<'x', Ts...>; > > > > > > > > > > we don't check satisfaction until after we're done coercing, because > > > > > of > > > > > > > > > > if (processing_template_decl && context == adc_unify) > > > > > /* Constraints will be checked after deduction. */; > > > > > > > > > > in do_auto_deduction. > > > > > > > > Ah, I wonder why we pass/use adc_unify from both unify and > > > > convert_template_argument.. That early exit makes sense for unify > > > > but not for convert_template_argument since it prevents us from > > > > checking constrained auto NTTPs during ahead of time coercion: > > > > > > > > template<class T> > > > > concept C = T::value; > > > > > > > > template<C auto> > > > > struct A { }; > > > > > > > > template<class T> > > > > void f() { > > > > A<0> a; // no constraint error > > > > } > > > > > > > > A<0> a; // constraint error > > > > > > > > I guess we'd ideally want to fix/implement this? At which point the > > > > ggc_free's of new_inner_args would be unsafe I think.. > > > > > > I don't think that would be an improvement; the C constraint is an > > > associated > > > constraint of A (https://eel.is/c++draft/temp#constr.decl-3.3.1). > > > > I thought C in 'template<C X>' is an associated constraint but not in > > 'template<C auto X>'? At least that's how GCC currently behaves. > > I think that's wrong: https://eel.is/c++draft/temp#param-11
Interesting, I can try fixing that at some point. > > > > Why don't we check satisfaction of A<0> when parsing f? > > > > We do but it's considered to have no associated constraints since C is > > 'attached' to the auto rather than to A currently. > > Ah, yes, I think I've run into trouble from that before. > > Jason > >