Lecture 6
Register Allocation Part 2
Live Ranges (live on exit)
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 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
Example:

- The live ranges of r1 and r3 do not overlap
- r2, r3 are live on exit
- r1 is not live on exit
Physical register ra assigned to r1 can also be re-assigned to r3

Register allocation as a graph coloring problem:
Interference Graph:
- Nodes: live ranges
- Edges: live at the same time

Graph coloring problem
- Color all nodes
- Use minimal number of colors such that no adjacent nodes have the same color
Answer: 2 colors

Top Down Allocator
The idea:
- Machine has k physical registers
- Keep the “busiest” values in an assigned register
- Use the feasible (reserved) set, F, for the rest
- F is the minimal set of registers needed to execute any instruction with all operands in memory
- Move values with no assigned register from/to memory by adding LOADs and STOREs (SPILL CODE)
Basic algorithm (not graph coloring!)
- Rank values by number of occurrences (or some other metric)
- Allocate first k to F values to registers
- Rewrite code (with spill code) to reflect these choices
Example
Take the following ILOC code with the live ranges (on exit) for each virtual register
loadI 1028 => r1 // r1
load r1 => r2 // r1 r2
mult r1,r2 => r3 // r1 r2 r3
loadI 5 => r4 // r1 r2 r3 r4
sub r4,r2 => r5 // r1 r3 r5
loadI 8 => r6 // r1 r3 r5 r6
mult r5,r6 => r7 // r1 r3 r7
sub r7,r3 => r8 // r1 r8
store r8 => r1 //