Lecture 5
Register Allocation
- Local: within single basic block
- Global: across procedure / function
Register -> Register model means you use a fresh register for each value

Critical properties
- Produce correct code that uses k (or fewer) registers
- Minimize added loads and stores
- Minimize space used to hold spilled values
- Operate efficiently
- O(n), O(n log2n), maybe O(n^2), but not O(2^n)
Memory Model / Code Shape
a := 1
b := 2
c := a + b + 3Assumption: no aliasing
Register-Register Model
- Values that may safely reside in registers are assigned to a unique virtual register (alias analysis; unambiguous values); there are different “flavors”
All in registers
loadI 1 => r1
loadI 2 => r2
add r1,r2 => r3
loadI 3 => r4
add r3,r4 => r5Preserve memory view (memory consistency)
loadI 1 => r1
storeAI r1 => r0,@a
loadI 2 => r2
storeAI r2 => r0,@b
add r1,r2 => r3
loadI 3 => r4
add r3,r4 => r5
storeAI r5 => r0,@cMemory-Memory Model
- All program-named values reside in memory, and are only kept in registers as briefly as possible (load operand from memory, perform computation, store result back into memory)
loadI 1 => r1
storeAI r1 => r0,@a
loadI 2 => r2
storeAI r2 => r0,@b
loadAI r0,@a => r3
loadAI r0,@b => r4
add r3,r4 => r5
loadI 3 => r7
add r5,r7 => r8
storeAI r8 => r0,@cConsider the following fragment of assembly code (or ILOC)
loadI 2 => r1 // r1 <- 2
loadAI r0,8 => r2 // r2 <- y
mult r1,r2 => r3 // r3 <- 2 * y
loadAI r0,4 => r4 // r4 <- x
sub r4,r3 => r5 // r5 <- x - (2 * y)The problem
- At each instruction, decide which values to keep in registers
- Note: a value is a pseudo-register (virtual register)
- Simple if |values| <= |registers|
- Harder if |values| > |registers|
- The compiler must automate this process
The Task
- At each point in the code, pick the values to keep in registerse
- Insert code to move values between registers & memory
- No reordering transformations (leave that to scheduling)
- Minimize inserted code - both dynamic & static measures
- Make good use of any extra registers
Allocation versus Assignment
- Allocation is deciding which values to keep in registers
- Assignment is choosing specific registers for values
- This distinction is often lost in the literature
- The compiler must perform both
Local Register Allocation
- What’s “local”?
- A local transformation operates on basic blocks
- Many optimizations are done locally
- Does local allocation solve the problem?
- It produces decent register use inside a block
- Inefficiencies can arise at boundaries between blocks
- How many passes can the allocator make?
- This is a compile-time (“off-line”) problem (not during program execution); typically, as many passes as it takes
- Memory-to-Memory vs. Register-to-Register model
- Code shape and safety issues
Basic Approach of Allocators
Allocator may need to reserve physical registers to ensure feasibility
Notation: k is the number of registers on the target machine
- Must be able to compute memory addresses
- Requires some minimal set of registers, F
- F depends on target architecture
- F contains registers to make spilling work
- set F registers “aside” for address computation & instruction execution, i.e., these are no available for register assignment
- Note: F physical registers need to be able to support the pathological case where all virtual registers are spilled
What if k - |F| < |values| < k?
- The allocator can either
- Check for this situation
- Accept the fact that the technique is an approximation
Top-down allocator
- May use notation of live ranges of virtual registers
- Work from “external” notion of what is important
- Assign registers in priority order
- Register assignment remains fixed for entire basic block
- Save some registers for the values relegated to memory (feasible set F)
Bottom-up allocator
- Work from detailed knowledge about problem instance
- Incorporate knowledge of partial solution at each step
- Register assignment may change across basic block
- Save some registers for the values relegated to memory (feasible set F)
Live Ranges
Assume i and j are two instructions in a basic block
A value (virtual register) is live between its definition and its uses
- Find definitions (x <- …) and uses (y <- … x …)
- From definition to last use is its live range
- How many static definitions can you have for a virtual register
- Can represent live range as an interval [i,j] (in block)
- Live on exit
Let MAXLIVE be the maximum, over each instruction i in the block, of the number of values (virtual registers) live at i.
- If MAXLIVE <= k, allocation should be easy
- No need to reserve set of F registers for spilling
- If MAXLIVE > k, some values must be spilled to memory
Finding live ranges is harder in the global case