[PATCH][C++] C++ bitfield memory model for as-base classes
Richard Biener
rguenther@suse.de
Thu Jul 21 07:17:00 GMT 2016
On Wed, 20 Jul 2016, Jeff Law wrote:
> On 06/29/2016 05:54 AM, Richard Biener wrote:
> >
> > Currently as-base classes lack DECL_BIT_FIELD_REPRESENTATIVEs which
> > means RTL expansion doesn't honor the C++ memory model for bitfields
> > in them thus for the following testcase
> >
> > struct B {
> > B() {}
> > int x;
> > int a : 6;
> > int b : 6;
> > int c : 6;
> > };
> >
> > struct C : B {
> > char d;
> > };
> >
> > C c;
> >
> > int main()
> > {
> > c.c = 1;
> > c.d = 2;
> > }
> >
> > on x86 we happily store to c.c in a way creating a store data race with
> > c.d:
> >
> > main:
> > .LFB6:
> > .cfi_startproc
> > movl c+4(%rip), %eax
> > andl $-258049, %eax
> > orb $16, %ah
> > movl %eax, c+4(%rip)
> > movb $2, c+7(%rip)
> > xorl %eax, %eax
> > ret
> >
> > Fixing the lack of DECL_BIT_FIELD_REPRESENTATIVEs in as-base
> > classes doesn't help though as the C++ FE builds access trees
> > for c.c using the non-as-base class FIELD_DECLs which is because
> > of layout_class_type doing
> >
> > /* Now that we're done with layout, give the base fields the real types.
> > */
> > for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
> > if (DECL_ARTIFICIAL (field) && IS_FAKE_BASE_TYPE (TREE_TYPE (field)))
> > TREE_TYPE (field) = TYPE_CONTEXT (TREE_TYPE (field));
> >
> > this would basically require us to always treat tail-padding in a
> > struct conservatively in finish_bitfield_representative (according
> > to the doubt by the ??? comment I patch out below).
> >
> > Simply commenting out the above makes fixing build_simple_base_path
> > necessary but even after that it then complains in the verifier
> > later ("type mismatch in component reference" - as-base to class
> > assignment).
> >
> > But it still somehow ends up using the wrong FIELD_DECL in the end.
> >
> > Now I think we need to fix the wrong-code issue somehow and
> > doing so in stor-layout.c by conservatively treating tail-padding
> > is a possibility. But that will pessimize PODs and other languages
> > unless we have a way to know whether a RECORD_TYPE possibly can
> > have its tail-padding re-used (I'd hate to put a lang_hooks.name
> > check there and even that would pessimize C++ PODs).
> >
> > Any guidance here?
> Note that if we change tail-padding re-use properties, then we effectively
> have an ABI change. Given that, the only path forward is to use smaller
> memory operations.
Yes, we can't change the ABI. It seems the most straigt-forward solution
is to add a langhook we can query from stor-layout that says whether
tail padding of an aggregate might be re-used.
> Do any other compilers gets this right (LLVM?)
clang++ 3.6.1 gives me
movzbl c+6(%rip), %eax
shll $16, %eax
movzwl c+4(%rip), %ecx
orl %eax, %ecx
andl $16519167, %ecx # imm = 0xFC0FFF
leal 4096(%rcx), %eax
shrl $16, %ecx
movb %cl, c+6(%rip)
movw %ax, c+4(%rip)
movb $2, c+7(%rip)
xorl %eax, %eax
retq
so it avoids the store data race (it even avoids load data races).
Not sure if it does because of the C++ memory model or lack of
optimization.
Richard.
> jeff
>
>
>
--
Richard Biener <rguenther@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nuernberg)
More information about the Gcc-patches
mailing list