pure/const function attribute and memoization
Florian Weimer
fweimer@redhat.com
Sat May 18 20:22:00 GMT 2013
On 05/18/2013 10:02 PM, Jan Hubicka wrote:
>> On 05/15/2013 11:01 AM, Richard Biener wrote:
>>> Now - if there would ever be an architecture where special call-site preparation
>>> is required for a callee to write to global memory then marking a function 'const'
>>> when it does in fact write to global memory then GCC may choose to optimize
>>> the call site to not do that call-site preparation. At least that
>>> would be valid according to the current documentation.
>>
>> That's a good point.
>>
>> The more immediate concern is that the compiler could apply the
>> const attribute to the function definition itself and deduct that
>> code paths with global memory references are unreachable.
>> Apparently, this is something that Clang does in some cases.
>
> It is bit crazy idea though :) Do you have reference to the corresponding thread?
<http://sourceware.org/ml/libc-alpha/2013-05/msg00389.html>
The function is in glibc's math/atest-exp2.c file.
> BTW we deduce all loops to be finite within const/pure functions that is also
> bit crazy effect of the attribute.
Uhm, okay.
> The memoization you mention is IMO not really safe even with current GCC. With
> bit of trickery one can convince GCC to early inline the memoizing const
> function in some cases and not in others. Optimizers will then expect your
> memoizing cache to not change across the non-inlined calls that may lead to
> wrong code.
Oh.
> At the moment I can not think of anything that would break if you had pure/const
> function modifying global memory and restoring it before returning.
Well, with a bit of cheating, that's actually easy:
int f1(void) __attribute__((const));
void f2(int);
void lock(void);
void unlock(void);
void
g()
{
for (int i = 0; i < 10; ++i) {
lock();
f2(f1());
unlock();
}
}
As expected, the loop turns into:
.L2:
call lock
movl %ebp, %edi
call f2
call unlock
subl $1, %ebx
jne .L2
If g() is called from multiple threads, this is no longer thread-safe
unless f1() performs its own locking.
I think we should warn about memoization and thread safety issues.
Trying to come up with more general semantics for const/pure appears to
be difficult to impossible, and as you say, does not match what the
compiler does today.
--
Florian Weimer / Red Hat Product Security Team
More information about the Gcc
mailing list