<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>