This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
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
>