ARM: Efficient C for ARM: Pointer Aliasing

by David Thomas on

Pointer Aliasing

  • Pointers alias when they point to the same address.
    • Writing via one pointer will change the value read through another.
  • The compiler often doesn’t know which pointers alias.
    • The compiler must assume that any write through a pointer may affect the value read from any another pointer!
    • This can significantly reduce code efficiency.

Examples

void timers1(int *t1, int *t2, int *step)
{
  *t1 += *step;
  *t2 += *step;
}
timers1 LDR r3,[r0]   ; R3 = *t1
        LDR r12,[r2]  ; R12 = *step
        ADD r3,r3,r12 ; R3 += R12
        STR r3,[r0]   ; *t1 = R3
        LDR r0,[r1]   ; R0 = *t2
        LDR r2,[r2]   ; R2 = *step  *** step loaded again
        ADD r0,r0,r2  ; R0 += R2
        STR r0,[r1]   ; *t2 = R0
        MOV pc,r14

You’d expect *step to be pulled from memory once and used twice. That does not happen.

Once rewritten to cache *step in a local variable, the redundant load is eliminated:

void timers2(int *t1, int *t2, int *step)
{
  int s = *step;
  *t1 += s;
  *t2 += s;
}
timers2 LDR r2,[r2]  ; R2 = *step
        LDR r3,[r0]  ; R3 = *t1
        ADD r3,r3,r2 ; R3 += R2
        STR r3,[r0]  ; *t1 = R3
        LDR r0,[r1]  ; R0 = *t2
        ADD r0,r0,r2 ; R0 += R2
        STR r0,[r1]  ; *t2 = R0
        MOV pc,r14

Remarks

C99’s restrict qualifier goes some way towards mitigating the effects of pointer aliasing. Understanding strict aliasing.

This is based on section 5.6 of ARM System Developer’s Guide.

Navigate