On 24/02/14 13:10, Sebastian Huber wrote: > On 2014-02-24 10:57, David Brown wrote: >> On 22/02/14 19:28, Sebastian Huber wrote: >>> Hello, >>> >>> first some background information. I would like to read from a memory >>> mapped register (some sort of hardware counter). The problem is that >>> the address of this register is unknown at compile and link time. So >>> some low-level initialization code determines the register address and >>> later its value never changes. >>> >>> I hoped that the const function attribute is of some help here: >>> >>> http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html#Function-Attributes >>> >>> >>> >>> Here it explicitly says "function is not allowed to read global >>> memory". Unfortunately the compiler takes this serious. >>> >>> I have the following test code: >>> >>> extern volatile const int *ip; >>> >>> __attribute__((const)) volatile int *get_ip(void); >>> >>> /* This function reads from global memory and is declared as const. GCC >>> ignores the const attribute in this case. */ >>> __attribute__((const)) static inline volatile int *get_ip_inline(void) >>> { >>> return ip; >>> } >> >> Try the "pure" attribute rather than the "const" one. "pure" functions >> are allowed to read global memory, but not write it (or cause other >> side-effects), and the compiler can safely call them fewer times than >> the program says. > > I noticed that even if you have a const variable, e.g. > > extern const int const_var; > > GCC will read the value of const_var again after a compiler memory > barrier (e.g. __asm__ volatile("" ::: "memory")). That's the rules - a "memory clobber" says that /any/ memory may change, and things read from memory could change and must therefore be re-read. Specifying the extern var as "const" does not tell the compiler that the value is constant - it simply tells the compiler that /you/ promise not to change it. (It would be nice if C, or at least gcc, had a way to say that the value is never changed, but it does not.) It is possible to clobber only specific addresses rather than /all/ memory, by specifying the memory as extra inputs or outputs - maybe that will give you better code. > So in my case it > turned out that there is not much left to optimize. It seems that I > have to live with the superfluous loads. > >> >> Also, you don't say anything about optimisation options - "pure" and >> "const" attributes only help if optimisation is enabled. >> > > I use optimization level -O2. >