[prev in list] [next in list] [prev in thread] [next in thread]
List: cfe-commits
Subject: Re: r180739 - Emit the TLS intialization functions into a list.
From: Richard Smith <richard () metafoo ! co ! uk>
Date: 2013-04-30 21:35:39
Message-ID: CAOfiQqnp=U1Umh=ufoZnna-dm1MS3juSyrJuzpa8L2iSfrkTeQ () mail ! gmail ! com
[Download RAW message or body]
[Attachment #2 (multipart/alternative)]
I've reverted this patch in r180809. This broke thread_local on Linux; the
backend asserted as follows:
clang-3.2: include/llvm/MC/MCStreamer.h:233: void
llvm::MCStreamer::SwitchSection(const llvm::MCSection *, const llvm::MCExpr
*): Assertion `Section && "Cannot switch to a null section!"' failed.
Testcase:
echo 'int f(); thread_local int n = f();' | ./build/bin/clang -x c++
-std=c++11 - -S -o -
On Mon, Apr 29, 2013 at 5:44 PM, Richard Smith <richard@metafoo.co.uk>wrote:
> On Mon, Apr 29, 2013 at 5:29 PM, John McCall <rjmccall@apple.com> wrote:
>
>> On Apr 29, 2013, at 5:18 PM, Richard Smith <richard@metafoo.co.uk> wrote:
>>
>> On Mon, Apr 29, 2013 at 5:13 PM, Bill Wendling <isanbard@gmail.com>wrote:
>>
>>> On Apr 29, 2013, at 5:09 PM, Richard Smith <richard@metafoo.co.uk>
>>> wrote:
>>>
>>> > On Mon, Apr 29, 2013 at 3:27 PM, Bill Wendling <isanbard@gmail.com>
>>> wrote:
>>> > Author: void
>>> > Date: Mon Apr 29 17:27:16 2013
>>> > New Revision: 180739
>>> >
>>> > URL: http://llvm.org/viewvc/llvm-project?rev=180739&view=rev
>>> > Log:
>>> > Emit the TLS intialization functions into a list.
>>> >
>>> > Add the TLS initialization functions to a list of initialization
>>> functions. The
>>> > back-end takes this list and places the function pointers into the
>>> correct
>>> > section. This way they're called before `main().'
>>> >
>>> > Why?
>>>
>>> "Why" what? Just as the description says, we place the function pointers
>>> into the correct section and, at least on Darwin, the TLS variables are
>>> initialized via calls to the those function pointers. Just like global
>>> c'tors.
>>
>>
>> OK, but why are we switching to eagerly initializing them rather than
>> doing it lazily? That's going to be extremely expensive for applications
>> which start lots of threads (say, by using std::async) and have
>> thread_local variables with non-trivial construction or destruction -- and
>> we still emit the dynamic initialization on every odr-use, so it doesn't
>> seem to save us anything.
>>
>>
>> This should be a Darwin-specific change.
>>
>> The Darwin TLS model is that thread-local variables are lazily allocated
>> and initialized, but only at the granularity of a single linkage unit.
>> That is, as soon as one thread-local variable is touched, every other
>> thread-local variable in that linkage unit is initialized at the same time.
>> The linker implicitly synthesizes the access functions and, to do so, must
>> receive a list of constructor functions to run, which is what this change
>> collects. I'm not sure I can fully defend this design, but it's what we've
>> got right now.
>>
>
> Thanks, that makes sense. This presumably should be handled in the
> CGCXXABI layer, and should definitely be done instead of generating and
> using the Itanium _ZTH / _ZTW functions, rather than in addition to them --
> you'll get no benefit from this the current way. (This is also not
> ABI-compatible with the Itanium proposal for thread_local, but I assume you
> are fine with that.)
>
> Also, you'll need ensure that the first time each thread_local variable is
> odr-used, it is "touched" enough to trigger initialization -- you can't
> optimize an odr-use away or you'll change the meaning of the code. For
> instance:
>
> thread_local int n = puts("hello world");
> void puts_once() { n; } // guarantees the 'puts' is issued
>
[Attachment #5 (text/html)]
<div dir="ltr">I've reverted this patch in r180809. This broke thread_local on \
Linux; the backend asserted as follows:<br><div><br></div><div>clang-3.2: \
include/llvm/MC/MCStreamer.h:233: void llvm::MCStreamer::SwitchSection(const \
llvm::MCSection *, const llvm::MCExpr *): Assertion `Section && "Cannot \
switch to a null section!"' failed.<br> </div><div><br></div><div \
style>Testcase:</div><div style><br></div><div style>echo 'int f(); thread_local \
int n = f();' | ./build/bin/clang -x c++ -std=c++11 - -S -o -<br></div></div><div \
class="gmail_extra"><br> <br><div class="gmail_quote">On Mon, Apr 29, 2013 at 5:44 \
PM, Richard Smith <span dir="ltr"><<a href="mailto:richard@metafoo.co.uk" \
target="_blank">richard@metafoo.co.uk</a>></span> wrote:<br><blockquote \
class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"> <div dir="ltr"><div><div class="h5">On Mon, Apr 29, 2013 at \
5:29 PM, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" \
target="_blank">rjmccall@apple.com</a>></span> wrote:<br></div></div><div \
class="gmail_extra"> <div class="gmail_quote"><div><div class="h5">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><div>On Apr 29, \
2013, at 5:18 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk" \
target="_blank">richard@metafoo.co.uk</a>> wrote:</div>
<blockquote type="cite"><div dir="ltr">On Mon, Apr 29, 2013 at 5:13 PM, Bill Wendling \
<span dir="ltr"><<a href="mailto:isanbard@gmail.com" \
target="_blank">isanbard@gmail.com</a>></span> wrote:<br><div class="gmail_extra">
<div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc \
solid;padding-left:1ex"><div>On Apr 29, 2013, at 5:09 PM, Richard Smith <<a \
href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> \
wrote:<br>
<br>
> On Mon, Apr 29, 2013 at 3:27 PM, Bill Wendling <<a \
href="mailto:isanbard@gmail.com" target="_blank">isanbard@gmail.com</a>> \
wrote:<br> > Author: void<br>
> Date: Mon Apr 29 17:27:16 2013<br>
> New Revision: 180739<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=180739&view=rev" \
target="_blank">http://llvm.org/viewvc/llvm-project?rev=180739&view=rev</a><br> \
> Log:<br> > Emit the TLS intialization functions into a list.<br>
><br>
> Add the TLS initialization functions to a list of initialization functions. \
The<br> > back-end takes this list and places the function pointers into the \
correct<br> > section. This way they're called before `main().'<br>
><br>
> Why?<br>
<br>
</div>"Why" what? Just as the description says, we place the function \
pointers into the correct section and, at least on Darwin, the TLS variables are \
initialized via calls to the those function pointers. Just like global \
c'tors.</blockquote>
<div><br></div><div>OK, but why are we switching to eagerly initializing them rather \
than doing it lazily? That's going to be extremely expensive for applications \
which start lots of threads (say, by using std::async) and have thread_local \
variables with non-trivial construction or destruction -- and we still emit the \
dynamic initialization on every odr-use, so it doesn't seem to save us \
anything.</div>
</div></div></div></blockquote><div><br></div></div><div>This should be a \
Darwin-specific change.</div><div><br></div><div>The Darwin TLS model is that \
thread-local variables are lazily allocated and initialized, but only at the \
granularity of a single linkage unit. That is, as soon as one thread-local variable \
is touched, every other thread-local variable in that linkage unit is initialized at \
the same time. The linker implicitly synthesizes the access functions and, to do so, \
must receive a list of constructor functions to run, which is what this change \
collects. I'm not sure I can fully defend this design, but it's what \
we've got right now.</div>
</div></div></blockquote><div><br></div></div></div><div>Thanks, that makes sense. \
This presumably should be handled in the CGCXXABI layer, and should definitely be \
done instead of generating and using the Itanium _ZTH / _ZTW functions, rather than \
in addition to them -- you'll get no benefit from this the current way. (This is \
also not ABI-compatible with the Itanium proposal for thread_local, but I assume you \
are fine with that.)</div>
<div><br></div><div>Also, you'll need ensure that the first time each \
thread_local variable is odr-used, it is "touched" enough to trigger \
initialization -- you can't optimize an odr-use away or you'll change the \
meaning of the code. For instance:</div>
<div><br></div><div>thread_local int n = puts("hello \
world");</div><div>void puts_once() { n; } // guarantees the 'puts' is \
issued</div></div></div></div> </blockquote></div><br></div>
_______________________________________________
cfe-commits mailing list
cfe-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic