This is the mail archive of the gcc-help@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]