This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Functions that are CSEable but not pure


On Thu, Oct 4, 2012 at 8:02 PM, Jason Merrill <jason@redhat.com> wrote:
> On 10/04/2012 01:42 PM, Richard Guenther wrote:
>>
>> So I suppose the testcase that would be "valid" but break with using
>> pure would be instead
>>
>> int main()
>> {
>>    int x = init_count;
>>    int *p = get_me();
>>    if (init_count == x)
>>      __builtin_abort();
>>    int *q = get_me();
>>    if (init_count == x)
>>      __builtin_abort();
>> }
>>
>> here when get_me is pure we CSE init_count over the _first_ call of
>> get_me.
>
>
> That's OK for C++ thread_local semantics; the initialization is specified to
> happen some time before the first use, so the testcase is making an invalid
> assumption.  This might not be desirable for user-written singleton
> functions, though.

Ok, so then let me make another example to try breaking a valid program
with the thread_local wrapper being pure:

int main()
{
  int &p = get_me();
  *p;
  if (init_count == 1)
    __builtin_abort();
}

note my using of C++ references (which in this case cannot bind to NULL
and thus *p might not trap(?)).  So the C++ source would be something like

thread_local int init_count;
int foo () { init_count = 1; return 0; }
thread_local int i = foo ();

int main()
{
  i;
  if (init_count != 1)
    __builtin_abort ();
}

is that valid?  When lowered to the above we would DCE the load of i
and the call to the initialization wrapper (because it is pure).  Obviously
then init_count is no longer 1.

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 realize that's somewhat ill-formed if the TLS variable was a class with
a static method doing the access to init_count - using that method
would not keep the class instance life.

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.

Richard.

> Jason
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]