[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&#39;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 &amp;&amp; &quot;Cannot \
switch to a null section!&quot;&#39; failed.<br> </div><div><br></div><div \
style>Testcase:</div><div style><br></div><div style>echo &#39;int f(); thread_local \
int n = f();&#39; | ./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">&lt;<a href="mailto:richard@metafoo.co.uk" \
target="_blank">richard@metafoo.co.uk</a>&gt;</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">&lt;<a href="mailto:rjmccall@apple.com" \
target="_blank">rjmccall@apple.com</a>&gt;</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 &lt;<a href="mailto:richard@metafoo.co.uk" \
target="_blank">richard@metafoo.co.uk</a>&gt; wrote:</div>

<blockquote type="cite"><div dir="ltr">On Mon, Apr 29, 2013 at 5:13 PM, Bill Wendling \
<span dir="ltr">&lt;<a href="mailto:isanbard@gmail.com" \
target="_blank">isanbard@gmail.com</a>&gt;</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 &lt;<a \
href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>&gt; \
wrote:<br>



<br>
&gt; On Mon, Apr 29, 2013 at 3:27 PM, Bill Wendling &lt;<a \
href="mailto:isanbard@gmail.com" target="_blank">isanbard@gmail.com</a>&gt; \
wrote:<br> &gt; Author: void<br>
&gt; Date: Mon Apr 29 17:27:16 2013<br>
&gt; New Revision: 180739<br>
&gt;<br>
&gt; URL: <a href="http://llvm.org/viewvc/llvm-project?rev=180739&amp;view=rev" \
target="_blank">http://llvm.org/viewvc/llvm-project?rev=180739&amp;view=rev</a><br> \
&gt; Log:<br> &gt; Emit the TLS intialization functions into a list.<br>
&gt;<br>
&gt; Add the TLS initialization functions to a list of initialization functions. \
The<br> &gt; back-end takes this list and places the function pointers into the \
correct<br> &gt; section. This way they&#39;re called before `main().&#39;<br>
&gt;<br>
&gt; Why?<br>
<br>
</div>&quot;Why&quot; 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&#39;tors.</blockquote>


<div><br></div><div>OK, but why are we switching to eagerly initializing them rather \
than doing it lazily? That&#39;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&#39;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&#39;m not sure I can fully defend this design, but it&#39;s what \
we&#39;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&#39;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&#39;ll need ensure that the first time each \
thread_local variable is odr-used, it is &quot;touched&quot; enough to trigger \
initialization -- you can&#39;t optimize an odr-use away or you&#39;ll change the \
meaning of the code. For instance:</div>

<div><br></div><div>thread_local int n = puts(&quot;hello \
world&quot;);</div><div>void puts_once() { n; } // guarantees the &#39;puts&#39; 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