This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Attribute const and inline functions
- From: David Brown <david at westcontrol dot com>
- To: Sebastian Huber <sebastian dot huber at embedded-brains dot de>
- Cc: GCC Help <gcc-help at gcc dot gnu dot org>
- Date: Mon, 24 Feb 2014 16:07:23 +0100
- Subject: Re: Attribute const and inline functions
- Authentication-results: sourceware.org; auth=none
- References: <5308EC44 dot 4010708 at embedded-brains dot de> <530B178F dot 9080704 at westcontrol dot com> <530B36AB dot 1010003 at embedded-brains dot de>
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.
>