This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [C++ PATCH] RFC: implement P0386R2 - C++17 inline variables


On Tue, Oct 11, 2016 at 9:39 AM, Jakub Jelinek <jakub@redhat.com> wrote:
> Here is an attempt to implement C++17 inline variables.
> Bootstrapped/regtested on x86_64-linux and i686-linux.
>
> The main question is if the inline variables, which are vague linkage,
> should be !DECL_EXTERNAL or DECL_EXTERNAL DECL_NOT_REALLY_EXTERN while
> in the FE.  In the patch, they are !DECL_EXTERNAL, except for inline
> static data members in instantiated templates.  As the inline-var3.C
> testcase shows, even if they are !DECL_EXTERNAL (except for the instantiated
> static data members), even at -O0 we do not actually emit them unless
> odr-used, so to some extent I don't see the point in forcing them to
> be DECL_EXTERNAL DECL_NOT_REALLY_EXTERN.

Yeah, I ended up agreeing with you.  There's no need to work hard to
make them work with an obsolete system.  So I've checked in the patch
with a few minor tweaks, attached.

> Another thing is I've noticed (with Jonathan's help to look it up) that
> we aren't implementing DR1511, I'm willing to try to implement that, but
> as it will need to touch the same spots as the patch, I think it should be
> resolved incrementally.

Sounds good.

> Yet another thing are thread_local inline vars.  E.g. on:
> struct S { S (); ~S (); };
> struct T { ~T (); };
> int foo ();
> thread_local inline S s;
> inline thread_local T t;
> inline thread_local int u = foo ();
> it seems both clang++ (~2 months old) and g++ with the patch emits:
> 8 byte TLS _ZGV1{stu] variables
> 1 byte TLS __tls_guard variable
> and _ZTH1[stu] being aliases to __tls_init, which does essentially:
>   if (__tls_guard) return;
>   __tls_guard = 1;
>   if (*(char *)&_ZGV1s == 0) {
>     *(char *)&_ZGV1s = 1;
>     S::S (&s);
>     __cxa_thread_atexit (S::~S, &s, &__dso_handle);
>   }
>   if (*(char *)&_ZGV1t == 0) {
>     *(char *)&_ZGV1t = 1;
>     __cxa_thread_atexit (T::~T, &t, &__dso_handle);
>   }
>   if (*(char *)&_ZGV1u == 0) {
>     *(char *)&_ZGV1u = 1;
>     u = foo ();
>   }
> Is that what we want to emit?  At first I doubted this could work properly,
> now thinking about it more, perhaps it can.

I think so; I don't see a reason for inline vars to work differently
from templates here.

> And, do we really want all the
> _ZGV* vars for the TLS inline vars (and other TLS comdats) to be 8 byte,
> even when we are using just a single byte?  Or is it too late to change (ABI
> break)?

Right, the ABI specifies that the guard variable is 8 bytes.  A
comment says, "The intent of specifying an 8-byte structure for the
guard variable, but only describing one byte of its contents, is to
allow flexibility in the implementation of the API above. On systems
with good small lock support, the second word might be used for a
mutex lock. On others, it might identify (as a pointer or index) a
more complex lock structure to use."  This seems unnecessary for
systems with byte atomic instructions, and we might be able to get
away with changing it without breaking any actual usage, but it would
indeed be an ABI change.

> And, as mentioned in the DWARF mailing list, I think we should emit
> DW_AT_inline on the inline vars (both explicit and implicit - static
> constexpr data members in C++17 mode).  I hope that can be done as a
> follow-up.

Makes sense.

Attachment: inline-tweaks.diff
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]