Re: Attribute const and inline functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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.
> 





[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux