> On 6/19/19 1:53 PM, Jan Hubicka wrote: > > > > > - ctype = CLASSTYPE_AS_BASE (ctype); > > > > > + { > > > > > + if (!tree_int_cst_equal (TYPE_SIZE (ctype), > > > > > + TYPE_SIZE (CLASSTYPE_AS_BASE (ctype)))) > > > > > + ctype = CLASSTYPE_AS_BASE (ctype); > > > > > + } > > > > > tree clobber = build_clobber (ctype); > > > > > > I have noticed we build a distinct as-base type in rather more cases than > > > strictly necessary. For instance when there's a member of reference type > > > or > > > we have a non-trivial dtor. (CLASSTYPE_NON_LAYOUT_POD_P gets set by a > > > bunch > > > of things that don't affect ABI layout) > > > > Avoiding the extra copies at first place would be great. In my > > understanding the types differ by virtual bases and also by their size > > since the fake types are not padded to multiply of their alignment. > > I guess this can be tested ahead of producing the copy and saving some > > memory... > > > > I am not sure if my C++ FE abilities are on par to implement this tough. > > I don't think it's simple to fix there, just unfortunate. your > understanding is correct, and I think your workaround will work. However, > remember it's possible for T == CLASSTYPE_AS_BASE (T), so might be worth > checking that before doing the size comparison? > > It'd be great to comment on why you're not just using classtype_as_base > there. I suppose I'm serializing this stuff too, with the same > inefficiencies ...
Hi, here is updated patch. Bootstrapped/regtested x86_64-linux, OK? It would be still nice to avoid copies at least in the commmon cases - it is easy to generate many types via templates and having basically every type twice is not very nice (we also copy all the fields, so overall memory use can be large). * decl.c (build_clobber_this): Do not use CLASSTYPE_AS_BASE when possible. Index: decl.c =================================================================== --- decl.c (revision 272506) +++ decl.c (working copy) @@ -15229,7 +15229,20 @@ build_clobber_this () tree ctype = current_class_type; if (!vbases) - ctype = CLASSTYPE_AS_BASE (ctype); + { + /* When clobbering base type, we need to be careful to not clobber + extra padding at the end of structure or virtual bases, which are + not considered part of the base by the C++ ABI. + + However try to avoid using CLASSTYPE_AS_BASE when possible because + typically this is the only use in the final intermediate language + where this type is needed. Doing so avoids need to stream many + duplciate type copies to LTO. */ + if (ctype != CLASSTYPE_AS_BASE (ctype) + && !tree_int_cst_equal (TYPE_SIZE (ctype), + TYPE_SIZE (CLASSTYPE_AS_BASE (ctype)))) + ctype = CLASSTYPE_AS_BASE (ctype); + } tree clobber = build_clobber (ctype);