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@xxxxxxxxxxxxxxxxxx
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.