On Thu, Oct 04, 2012 at 07:08:02PM +0200, Richard Guenther wrote: > But isn't it a fact that it _cannot_ modify init_count? If the second call > is CSEable then it cannot have side-effects that are observable at > the call site. Is the following an example you would consider to fall > under your CSEing? > > int init_count; > int data; > int initialized; > > void init() > { > if (!initialized) > { > data = ++init_count; > initialized = 1; > } > } > > inline int *get_me() __attribute ((pure)); > inline int *get_me() > { > init (); > return &data; > } > > int sink; > > int main() > { > sink = init_count; > int *p = get_me(); > if (init_count != 1) > __builtin_abort(); > initialized = 0; > int *q = get_me(); > if (init_count != 2) > __builtin_abort(); > return *p + *q; > }
The above isn't a singleton function, as you are clearing initialized, therefore it doesn't have the properties the thread_local var get_address wrapper has. The singleton function really is void singleton (void) { static __thread bool initialized; if (!initialized) { initialized = true; call_some_function_that_may_modify_memory (); } } and has side effects just first time in a thread. Jakub