This page explains register allocation using Iterated Register Coalescing in the presence of precolored nodes (temporary variables already assigned to machine registers).
The instruction-selection phase of a compiler may generate arbitrarily many temporary variables, which must then be assigned to a finite set of machine registers.
But some of the variables produced by instruction selection must be assigned to specific machine registers, because of standard parameter-passing conventions, or the use of special registers such as stack pointer or frame pointer. These variables are precolored before register allocation. For each machine register, there may be at most one node precolored with that color.
Precolored nodes should be considered to have infinite degree. Therefore, simplify, freeze, and spill cannot be performed on them. However, an ordinary (non-precolored) node may be coalesced with a precolored node.
enter:
c := r3
a := r1
b := r2
d := 0
e := a
loop:
d := d+b
e := e-1
if e>0 goto loop
r1 := d
r3 := c
return
[ r1,r3 live out]
The target machine has three registers, r1, r2,
r3. Registers r1 and r2 are caller-save,
and r3 is callee-save. The code generator has
therefore made arrangements to preserve the value of r3
explicitly, by copying it into the temporary c and back again.
The interference graph for this function is:

The register allocation proceeds as follows (with K=3):
| Node |
|
|
degree |
|
||||||||||
| a: | ( | 2 | +10* | 0 | ) / | 4 | = | 0.50 | ||||||
| b: | ( | 1 | +10* | 1 | ) / | 4 | = | 2.75 | ||||||
| c: | ( | 2 | +10* | 0 | ) / | 6 | = | 0.33 | ||||||
| d: | ( | 2 | +10* | 2 | ) / | 4 | = | 5.50 | ||||||
| e: | ( | 1 | +10* | 3 | ) / | 3 | = | 10.3 |
Spilling c, we obtain the graph,





enter:
c1 := r3
M[c_loc] := c1
a := r1
b := r2
d := 0
e := a
loop:
d := d+b
e := e-1
if e>0 goto loop
r1 := d
c2 := M[c_loc]
r3 := c2
return
[ r1,r3 live out]




| Node | Color |
| a | r1 |
| b | r2 |
| c | r3 |
| d | r3 |
| e | r1 |
enter:
r3 := r3
M[c_loc] := r3
r1 := r1
r2 := r2
r3 := 0
r1 := r1
loop:
r2 := r3+r2
r1 := r1-1
if r1>0 goto loop
r1 := r3
r3 := M[c_loc]
r3 := r3
return
[ r1,r3 live out]
enter:
M[c_loc] := r3
r3 := 0
loop:
r2 := r3+r2
r1 := r1-1
if r1>0 goto loop
r1 := r3
r3 := M[c_loc]
return
[ r1,r3 live out]
The final program has only one uncoalesced move instruction.