Attribute for a invariant function ?

I have a read-only lookup table, which takes integer arguments. Optimally I would like to indicate in the C source, that the function is invariant (?), so that the superflous calls can be optimized away.

extern void *lookup( int a);

void  foo( void)
  void  *a, *b;
  a = lookup( 0x12345678);
  bar( a);

  b = lookup( 0x12345678); // b guaranteed to be the same as a, no call to (slow) lookup needed
  baz( b);

But I don’t really find anything in clang or llvm in terms of function attributes. The best I could come up with is in the llvm code to use attributes “argmemonly=true” readonly=true". But still two calls did happen. (I am on 3.7)


I use ‘attribute((pure))’ for fast math functions and some other intrinsic function I have added such as getting the current core ID. This tells the compiler that calling the same function with the same arguments will always return the same value. A function declared with this attribute is not supposed to have any side-effects such as altering global variables.


extern void *lookup(int) attribute((pure));

might do what you need though.


I am considering a similar use case, which strictly speaking is not a
valid use of pure. Consider the xlocale interface:

l = newlocale(...);

if (isalpha_l(c, l))

if (isalpha_l(c, l))


The call to isalpha_l is redundant, but the value depends on l within
the life time -- strictly speaking with pure, the compiler could
remember the value of l and use a cached value accordingly.


Martin J. O’Riordan schrieb:

extern void *lookup(int) attribute((pure));

might do what you need though.

Good, that’s pretty much what I was looking for. With that I was able to google for

which leads me to:

attribute((const)) function attribute
Many functions examine only the arguments passed to them, and have no effects except for the return value. This is a much stricter class than attribute((pure)), because a function is not permitted to read global memory. If a function is known to operate only on its arguments then it can be subject to common sub-expression elimination and loop optimizations.

The last sentence is what I am after. :slight_smile: Unfortunately at least in clang 3.7 it does not seem to do anything.

Thanks for the help.


The problem is the intermediate call. That can invalidate the result of
a pure function. A function that returns the current value of some
global value is pure, but not const. If you call another global
function or modify some global memory, the value can have changed.
Essentially, there is an area between pure and const, that's currently
not handled well.


  extern void *lookup( int a) __attribute__ ((const));