Register Allocation

Register allocation is the process where the compiler decides which local variables of a C function should be kept in CPU registers (for fast access), and which should be kept in RAM (on the stack, which is slower).

Why is it Important

  • Accessing registers is super-fast (takes 1 cycle).
  • Accessing memory (spilled variables) is slower (takes multiple cycles).
  • Therefore, efficient use of registers = faster code and better optimization.

Available ARM Registers for C Programs

RegisterUsage
r0–r3Used for function arguments and return values
r4–r11Available for local variables (callee-saved)
r12Scratch register (in many compilers, used internally only)
r13Stack Pointer (SP)
r14Link Register (LR)
r15Program Counter (PC)

In practice, around 12 registers (r0–r11) are available for local variable allocation by the compiler.

1. Register Preference

The compiler always tries to keep the most-used variables in registers.

  • If your variable is inside a loop, the compiler gives it high priority.
  • If your variable is used only once, it’s more likely to be spilled to memory.

2. Spilled Variables

When there are more variables than registers, some variables are:

  • Moved to the stack (RAM)
  • Accessed using load/store instructions, which slows performance
  • Known as spilled variables

3. Reuse of Registers

If variables are not used at the same time, the same register can be reused:

void demo() {
int a = 10; // assigned to r4
int b = 20; // assigned to r5
// a is not used after this point
int c = 30; // compiler can reuse r4 here
}

How to Optimize Register Allocation in Your Code

1: Keep your function logic simple

  • Use less than 12 variables inside functions, especially loops.
  • Avoid deeply nested logic.

2: Use loops wisely

  • Frequently used loop variables (like counters or accumulators) are prioritized for register allocation.
for (int i = 0; i < 100; i++) {
sum += array[i]; // sum and i likely kept in registers
}

3: Avoid the register keyword

  • Modern compilers ignore or limit its usage.
  • Let the compiler decide the best allocation using its optimization flags.

Example: Register Allocation in Practice

C Code:

int sum_array(int* arr, int len) {
int sum = 0;
for (int i = 0; i < len; i++) {
sum += arr[i];
}
return sum;
}

What the Compiler Might Do:

VariableRegister Allocated
arrr0 (argument)
lenr1 (argument)
sumr4
ir5

No variables are spilled. Entire function runs from registers, making it fast and optimized

Leave a Reply

Your email address will not be published. Required fields are marked *