How do I tell GCC that a global variable is immutable after initialization?

Sebastian Huber sebastian.huber@embedded-brains.de
Wed Jun 22 07:49:00 GMT 2016


On 22/06/16 09:42, Mason wrote:
> On 22/06/2016 09:00, Sebastian Huber wrote:
>
>> is there a way to tell GCC that a global variable is immutable after
>> initialization? For example
>>
>> struct {
>>       int (*f)(void);
>> } s;
>>
>> int f(void)
>> {
>>       int a;
>>       int b;
>>
>>       a = (*s.f)();
>>       b = (*s.f)();
>>
>>       return a + b;
>> }
>>
>> yields on ARMv8 for example
>>
>> f:
>>           push    {r4, r5, r6, lr}
>>           movw    r4, #:lower16:s
>>           movt    r4, #:upper16:s
>>           ldr     r3, [r4]
>>           blx     r3
>>           ldr     r3, [r4] <- I would like to get rid of this load here
>>           mov     r5, r0
>>           blx     r3
>>           add     r0, r5, r0
>>           pop     {r4, r5, r6, pc}
>>
>> The
>>
>> a = (*s.f)();
>>
>> is a call to a global function, so GCC must assume that s might have
>> changed afterwards. I would like to get rid of the second load of s.f.
>> Is there a special attribute to tell GCC that s is essentially
>> immutable? I cannot use the const qualifier, since the structure is
>> initialized during system start.
> A simple solution would be storing the function pointer in a local variable.
> Thus, the compiler "knows" you intended to call the same function twice.
>
> typedef int func(void);
> struct { func *f; } s;
> int f(void)
> {
>       func *g = s.f;
>       int a = g();
>       int b = g();
>       return a + b;
> }
>
> 	push	{r3, r4, r5, lr}
> 	movw	r3, #:lower16:s
> 	movt	r3, #:upper16:s
> 	ldr	r4, [r3]
> 	blx	r4
> 	mov	r5, r0
> 	blx	r4
> 	add	r0, r0, r5
> 	pop	{r3, r4, r5, pc}
>
> Regards.

My problem is that the actual (*s.f)() call is an implementation detail. 
I have a function which returns a timestamp via an architecture specific 
way, e.g. on PowerPC this is something like this:

static inline int timestamp(void)
{
   int t;
    __asm__(... t ...).
   return t;
}

On SPARC this is something like this:

static inline int timestamp(void)
{
   return (*s.f)();
}

So, I cannot use a local variable for this particular use case.

-- 
Sebastian Huber, embedded brains GmbH

Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone   : +49 89 189 47 41-16
Fax     : +49 89 189 47 41-09
E-Mail  : sebastian.huber@embedded-brains.de
PGP     : Public key available on request.

Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.



More information about the Gcc-help mailing list