compilation 2013 register allocation, cont’d -...
TRANSCRIPT
Compilation 2013
Register Allocation, cont’d
Erik Ernst Aarhus University
Register allocation
Register Allocation
§ Recall: • using interference graph • graph coloring represents allocation • algo.: simplify coalesce freeze may_spill select did_spill • Basic parameter: K registers • Node n heavy: degree(n) ≥ K, otherwise n light !
§ ToDo: • no reference to actual registers (e.g., fails for ‘imull’) • consider other heuristics — achieved for free? • extensive example
"2
Register allocation
Registers and Coloring
§ Registers are often not equal (‘imull’ again) § Registers must exist in interference graph !
§ One node per register “pre-colored”! § Forced properties:
• all register node pairs interfere (full subgraph) • each register R must have a unique color c • the color c must map to R • of course, other temps can have color c (means “is R”) • cannot spill nor freeze a register node, coalesce two …
§ Simple rule: “A register node has infinite degree”
"3
Register allocation
Copy Registers Eagerly
§ Long-lived register bad • interferes with many temps • prevents many possibilities
§ Easily avoided: • copy register to fresh temp and back • if low pressure: coalesce, eliminate
moves, all gone • ok outcome: temp is other register • if high pressure: temp has few uses/
defs, will spill § Typical case: callee-save register
"4
live-in: r7 L1_blocks: # save r7 t231 := r7 . . . # restore r7 r7 := t231 L32_block_done: live-out: r7
Register allocation
Treatment of Caller-Save Registers
§ They interfere with each temp with a ‘call’ in a live range (is in def of that instruction)
§ Hence, these registers are used for other temps (short-lived) !
§ Note old heuristic: • temp live across calls: use callee-save register • temp not live across calls: use caller-save
§ In fact, we may get both: • callee-save register saved, interference-free, available • caller-save register pushed toward short-lived temps
"5
Register allocation
Example: Graph Coloring w/precoloring
§ Consider a C function f, with generated pseudo-assembly code !
§ Platform has K = 3 § r1, r2 caller-save; r3 callee-save § arguments passed in r1, r2
(usual trick: copy to fresh temp) !
§ now compute interference graph(skip control flow graph, boring)
"6
live-in: r1 r2 r3 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 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
Register allocation
Example: Graph Coloring w/precoloring
§ Interference graph
"7
live-in: r1 r2 r3 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 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
be
r1
r3
r2
a
c
d
Register allocation
Example
§ Cannot simplify, freeze, coalesce, must spill
"8
live-in: r1 r2 r3 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 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
be
r1
r3
r2
a
c
d
Register allocation
Example
§ Cannot simplify, freeze, coalesce, must spill — using (o+10i) / d
"9
live-in: r1 r2 r3 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 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }Node
use/def outside
loop
use/def in loop degree spill
priority
a 2 0 4 0,50
b 1 1 4 2,75
c 2 0 6 0,33
d 2 2 4 5,50
e 1 3 3 10,33
Register allocation
Example
§ Spilled c; now coalesce a&e, OK by Briggs
"10
live-in: r1 r2 r3 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 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
be
r1
r3
r2
a d
Register allocation
Example
§ Coalesced a&e; now coalesce ae&r1 or b&r2, OK by George
§ Q: Why not d&r1 ?
"11
live-in: r1 r2 r3 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 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
b
r1
r3
r2
ae d
Register allocation
Example
§ Coalesced b&r2; now coalesce ae&r1 or d&r1, OK by George
§ Q: Why is d&r1 OK now?
"12
live-in: r1 r2 r3 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 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
r1
r3
br2
ae d
Register allocation
Example
§ Coalesced ae&r1; now simplify d § Q: Why not d&aer1 ?
"13
live-in: r1 r2 r3 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 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
aer1
r3
br2
d
Register allocation
Example
§ Graph now fully precolored, select: § b can get color r3, § c an actual spill: change program!
"14
live-in: r1 r2 r3 enter: c1 := r3 M[cloc] := 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[cloc] r3 := c2 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
aer1
r3
br2
Register allocation
Example
§ New interference graph
"15
live-in: r1 r2 r3 enter: c1 := r3 M[cloc] := 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[cloc] r3 := c2 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
be
r1
r3
r2
a d
c1
c2
Register allocation
Example
§ Coalesced c1&r3, c2&r3 (by ..?)
"16
live-in: r1 r2 r3 enter: c1 := r3 M[cloc] := 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[cloc] r3 := c2 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
be
r1
c1c2r3
r2
a d
Register allocation
Example
§ Coalesced a&e, b&r2 (as earlier)
"17
live-in: r1 r2 r3 enter: c1 := r3 M[cloc] := 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[cloc] r3 := c2 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
r1
c1c2r3
br2
ae d
Register allocation
Example
§ Coalesced ae&r1, simplified d (again, as earlier)
"18
live-in: r1 r2 r3 enter: c1 := r3 M[cloc] := 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[cloc] r3 := c2 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
aer1
c1c2r3
br2
Register allocation
Example
§ Graph precolored, start select: § only d on stack, gets color r3
"19
live-in: r1 r2 r3 enter: r3 := r3 M[cloc] := r3 r1 := r1 r2 := r2 r3 := 0 r1 := r1 loop: r3 := r3 + r2 r1 := r1 - 1 if r1>0 goto loop r1 := r3 r3 := M[cloc] r3 := r3 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }Node/Temp Color/Register
a r1
b r2
c r3
d r3
e r1
Register allocation
Example
§ Many no-ops detected
"20
live-in: r1 r2 r3 enter: r3 := r3 M[cloc] := r3 r1 := r1 r2 := r2 r3 := 0 r1 := r1 loop: r3 := r3 + r2 r1 := r1 - 1 if r1>0 goto loop r1 := r3 r3 := M[cloc] r3 := r3 live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }Node/Temp Color/Register
a r1
b r2
c r3
d r3
e r1
Register allocation
Example
§ Final program !
§ NB: This is a serious piece of optimization, including many ad-hoc techniques
"21
live-in: r1 r2 r3 enter: M[cloc] := r3 r3 := 0 loop: r3 := r3 + r2 r1 := r1 - 1 if r1>0 goto loop r1 := r3 r3 := M[cloc] live-out: r1 r3
int f(int a, int b) { int d = 0; int e = a; do { d = d+b; e = e-1; } while (e>0); return d; }
Register allocation
Register Allocation for Trees
§ Could ignore it — just a special case of solution we already have obtained !
§ However, optimal solution within reach § ‘Sethi-Ullman’ algorithm includes spilling !
§ Assumes reordering OK, must know side-effects
"22
Register allocation
Summary
!§ Register allocation so far ignored registers ;-) § Must exist in interference graph, pre-colored § Special treatment gathered into ‘infinite degree’ § Useful technique: copy to/from fresh temp § Ex: allows flexible handling of callee-save register § Ex: caller-save register gravitates toward short life § (Example) § Note special case: Register allocation for trees
"23