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
>

Reply via email to