The semantics of the 'first' reference of the TLS variable has changed, and this change is introduced by the implementation. It is no longer safe to do DCE as
thread_local int x = ..; int foo() { x; ... } but should be safe to do DSE as int foo() { x = ...; // Dead x = ...; .. } as well as CSE, PRE, PDE etc. The bigger problems are 1) As mentioned in this thread -- when the wrapper is inlined, the pure attribute will be lost. It will give compiler hard time to optimize away the guard code 2) The runtime overhead of the guard code -- if the guard variable is also tls. Speaking of 1), given two inline instances of the wrapper, if (!init_guard) { init_guard = 1; do_init(); } ... some code if (!init_guard) { init_guard =1 ; do_init(); } If the compiler is taught that init_guard can not be clobbered by anything other than the owner TLS variable's wrapper function, then VRP should should be able to provide init_guard is not zero before the second check thus can completely eliminate the if-block. Inter-procedural elimination requires more work though. so perhaps the solution is just to mark wrapper function always inline? It will punish the code size for O0 build though as the init block can not be optimized away. thanks, David On Fri, Oct 5, 2012 at 10:24 AM, Jason Merrill <ja...@redhat.com> wrote: > On 10/05/2012 04:46 AM, Richard Guenther wrote: >> >> Ok, so then let me make another example to try breaking a valid program >> with the thread_local wrapper being pure: > > > There is also my example earlier in the thread. > > >> i; >> if (init_count != 1) >> __builtin_abort (); >> >> is that valid? > > > I believe so; that is an odr-use of i, so it needs to be initialized. > > >> Thus my question is - is a valid program allowed to access side-effects >> of the dynamic TLS initializer by not going through the TLS variable? > > > I think so. > > >> Preventing DCE but not CSE for const/pure functions can be for >> example done by using the looping-const-or-pure flag (but that >> also tells the compiler that this function may not return, so it is >> very specific about the kind of possible side-effect to be preserved). >> The very specific nature of thread_local TLS init semantics >> ('somewhen before') is hard to make use of, so if we want to >> change looping-const-or-pure to something like >> const-or-pure-with-side-effects >> we should constrain things more. > > > That would be fine with me. > > Jason >