On Wed, Jun 19, 2019 at 2:47 PM Nathan Sidwell <nat...@acm.org> wrote:
>
> 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 ...

This simple (untested) patch doesn't avoid creating the unnecessary
as-base types, but it should avoid using them in a way that causes
them to be streamed, and should let them be discarded by GC.
Thoughts?
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index de37e43d04c..e0df9ef2b20 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -6453,6 +6453,12 @@ layout_class_type (tree t, tree *virtuals_p)
   /* Let the back end lay out the type.  */
   finish_record_layout (rli, /*free_p=*/true);
 
+  /* If we didn't end up needing an as-base type, don't use it.  */
+  if (CLASSTYPE_AS_BASE (t) != t
+      && tree_int_cst_equal (TYPE_SIZE (t),
+                            TYPE_SIZE (CLASSTYPE_AS_BASE (t))))
+    CLASSTYPE_AS_BASE (t) = t;
+
   if (TYPE_SIZE_UNIT (t)
       && TREE_CODE (TYPE_SIZE_UNIT (t)) == INTEGER_CST
       && !TREE_OVERFLOW (TYPE_SIZE_UNIT (t))

Reply via email to