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]

Functions that are CSEable but not pure


In C++ there is a common idiom called "initialize on first use". In its simplest form it looks like

int& lazy_i()
{
  static int i = init;
  return i;
}

If the initialization is expensive or order-sensitive, this is a useful alternative to initialization on load (http://www.parashift.com/c++-faq/static-init-order-on-first-use.html).

An interesting property of such functions is that they only have side-effects the first time they are called, so subsequent calls can be optimized away to just use the return value of the first call.

Currently there is no way to express this in GCC so that the optimizers know that multiple calls are redundant. Marking the function as pure causes calls to be CSEd as desired, but also asserts that the first call has no side-effects, which is not the case.

My implementation of dynamic initialization of TLS variables as mandated by the C++11 and OpenMP standards uses this idiom implicitly, so I'd really like to be able to optimize away multiple calls.

Right now we have the following ECF flags (among others):

const = no read, no write, no side-effects, cseable
pure = no write, no side-effects, cseable
novops = no read, no write
looping_const_or_pure = wait, actually there are side-effects

Seems like the difference between novops and looping_const_or_pure is whether calls are subject to CSE. Is that right?

Rather than checking these flag bundles, it seems to me that we ought to break them up into

no reads
no writes
no side-effects
cseable side-effects

So const      would be noread|nowrite|noside
   pure       would be nowrite|noside
const|looping would be noread|nowrite|cseside
pure|looping  would be nowrite|cseside
   novops     would be noread|nowrite

and the behavior I want would be just cseside.

Does this make sense? Anyone more familiar with this area of the code want to implement it for me? :}

Jason


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