56
1 Theory of Compilation 236360 Erez Petrank Lecture 10: Code Generation

1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Embed Size (px)

Citation preview

Page 1: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Theory of Compilation 236360

Erez Petrank

Lecture 10: Code Generation

Page 2: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

You are here

2

Executable

code

exe

Source

text

txt

Compiler

Lexica

lA

naly

sis

Syn

tax

An

aly

sis

Sem

an

ticA

naly

sis

Inte

r.R

ep

. (IR)

Cod

e

Gen

.

chara

cters

toke

ns A

ST

(Abstra

ct Synta

x Tre

e)

An

nota

ted

AS

T

Page 3: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Code Generation: Backend

Generate code for a specific machine. Assume no errors at this point. Input: Intermediate language code + symbol

table Output: target language code

Page 4: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

target languages

Absolute machine code

Code

Gen.

Relativemachine code

Assembly

IR + Symbol Table

Page 5: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

From IR to ASM: Challenges

mapping IR to ASM operations what instruction(s) should be used to implement an

IR operation? how do we translate code sequences

call/return of routines managing activation records

memory allocation register allocation optimizations

Page 6: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Intel IA-32 Assembly

Going from Assembly to Binary… Assembling Linking

AT&T syntax vs. Intel syntax We will use AT&T syntax

matches GNU assembler (GAS)

Page 7: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

AT&T versus Intel Syntax

Attribute AT&T Intel

Parameter order

Source comes before the destination

Destination before

Parameter Size

Mnemonics are suffixed with a letter indicating the size of the operands (e.g., "q" for qword, "l" for dword, "w" for word, and "b" for byte)

Derived from the name of the register that is used

Immediate value signals

Prefixed with a "$", and registers must be prefixed with a "%”

The assembler automatically detects the type of symbols; i.e., if they are registers, constants or something else.

Effective addresses

General syntax DISP(BASE,INDEX,SCALE)Example: movl mem_location(%ebx,%ecx,4), %eax

Use variables, and need to be in square brackets; additionally, size keywords like byte, word, or dword have to be used.[1]Example: mov eax, dword [ebx + ecx*4 + mem_location]

Page 8: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

IA-32 Registers

Eight 32-bit general-purpose registers EAX – accumulator for operands and result data.

Used to return value from function calls. EBX – pointer to data. Often use as array-base address ECX – counter for string and loop operations EDX – data/general ESI – GP and source pointer for string operations EDI – GP and destination pointer for string operations EBP – stack frame (base) pointer ESP – stack pointer

EFLAGS register EIP (instruction pointer) register … (ignore the rest for our purposes)

Page 9: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Not all registers are born equal

EAX Required operand of MUL,IMUL,DIV and IDIV instructions Contains the result of these operations

EDX Stores remainder of a DIV or IDIV instruction

(EAX stores quotient) ESI, EDI

ESI – required source pointer for string instructions EDI – required destination pointer for string instructions

Destination Registers of Arithmetic operations EAX, EBX, ECX, EDX

EBP – stack frame (base) pointer ESP – stack pointer

Page 10: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

IA-32 Addressing Modes

Machine-instructions take zero or more operands

Source operand Immediate Register Memory location (I/O port)

Destination operand Register Memory location (I/O port)

Page 11: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Immediate and Register Operands

Immediate Value specified in the instruction itself GAS syntax – immediate values preceded by $ add $4, %esp

Register Register name is used GAS syntax – register names preceded with % mov %esp,%ebp

Page 12: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Memory and Base Displacement Operands

Memory operands Value at given address GAS syntax - parentheses mov (%eax), %eax

Base displacement Value at computed address Address computed out of

base register, index register, scale factor, displacement offset = base + (index*scale) + displacement Syntax: disp(base,index,scale) movl   $42, $2(%eax) movl $42, $1(%eax,%ecx,4)

Page 13: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Base Displacement Addressing

Mov (%ebx,%ecx,4), %eax

7

Array Base Reference

4 4

0 2 4 5 6 7 1

4 4 4 4 4 4

%ebx = base%ecx = 3

Addr = base + (index*scale) + displacement

Addr = base + (3*4) + 0 = base + 12

(%ebx,%ecx,4)

Page 14: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Basic Blocks

An important notion. Start by breaking the IR into basic blocks A basic block is a sequence of instructions

with A single entry (to first instruction), no jumps to the

middle of the block A single exit (last instruction) Thus, code execute as a sequence from first

instruction to last instruction without any jumps

An edge from one basic block B1 to another block B2 when the last statement of B1 may jump to B2

Page 15: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Example

False

B1

B2 B3

B4

True

t1 := 4 * it2 := a [ t1 ]if t2 <= 20 goto B3

t5 := t2 * t4

t6 := prod + t5

prod := t6

goto B4

t7 := i + 1i := t2

Goto B5

t3 := 4 * it4 := b [ t3 ]goto B4

Page 16: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

creating basic blocks Input: A sequence of three-address statements Output: A list of basic blocks with each three-

address statement in exactly one block Method

Determine the set of leaders (first statement of a block) The first statement is a leader Any statement that is the target of a conditional or

unconditional jump is a leader Any statement that immediately follows a goto or

conditional jump statement is a leader For each leader, its basic block consists of the leader

and all statements up to but not including the next leader or the end of the program

Page 17: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

control flow graph

A directed graph G=(V,E) nodes V = basic blocks edges E = control flow

(B1,B2) E if control from B1 flows to B2

A loop is a strongly connected component of the graph that has a single entry point.

An inner loop is a loop that has no sub-loop.

B1

B2

t1 := 4 * it2 := a [ t1 ]t3 := 4 * it4 := b [ t3 ]t5 := t2 * t4

t6 := prod + t5

prod := t6

t7 := i + 1i := t7

if i <= 20 goto B2

prod := 0i := 1

Page 18: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

example1) i = 1

2) j =1

3) t1 = 10*I

4) t2 = t1 + j

5) t3 = 8*t2

6) t4 = t3-88

7) a[t4] = 0.0

8) j = j + 1

9) if j <= 10 goto (3)

10) i=i+1

11) if i <= 10 goto (2)

12) i=1

13) t5=i-1

14) t6=88*t5

15) a[t6]=1.0

16) i=i+1

17) if I <=10 goto (13)

i = 1

j = 1

t1 = 10*It2 = t1 + jt3 = 8*t2t4 = t3-88a[t4] = 0.0j = j + 1if j <= 10 goto B3i=i+1if i <= 10 goto B2

i = 1

t5=i-1t6=88*t5a[t6]=1.0i=i+1if I <=10 goto B6

B1

B2

B3

B4

B5

B6

for i from 1 to 10 do for j from 1 to 10 do a[i, j] = 0.0;for i from 1 to 10 do a[i, i] = 1.0;

source

IR CFG

Page 19: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Optimizations Possible to obtain performance improvements by

working inside basic block boundaries. A better accuracy is obtained when considering

all blocks in a routine. It is best to consider all blocks in the program

(whole program analysis). But: Costly Usually unknown.

Optimization employs “program understanding” = program analysis.

An example: to allocate registers efficiently we need to analyze liveness of variables.

Page 20: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Variable Liveness A statement x = y + z

defines x uses y and z

A variable x is live at a program point if its value is used at a later point without being defined beforehand

If x is defined in instruction i, used in instr. j, and there is a computation path from i to j that does not modify x, then instr. j is using the value of x that is defined in instr. i.

y = 42z = 73

x = y + zprint(x);

x is live, y dead, z dead

x undef, y live, z live

x undef, y live, z undef

x is dead, y dead, z dead

(showing state after the statement)

Page 21: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Computing Liveness Information

between basic blocks – dataflow analysis (next lecture)

within a single basic block? idea

use symbol table to record next-use information scan basic block backwards update next-use for each variable

Page 22: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Computing Liveness Information INPUT: A basic block B of three-address statements.

symbol table initially shows all non-temporary variables in B as being live on exit.

OUTPUT: At each statement i: x = y + z in B, liveness and next-use information of x, y, and z at i.

Algorithm: Start at the last statement in B and scan backwards At each statement i: x = y + z in B, we do the following:1. Attach to i the information currently found in the symbol

table regarding the next use and liveness of x, y, and z.2. In the symbol table, set x to "not live" and "no next use.“3. In the symbol table, set y and z to "live" and the next uses

of y and z to i

Page 23: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Computing Liveness Information

Start at the last statement in B and scan backwards At each statement i: x = y + z in B, we do the following:1. Attach to i the information currently found in the symbol

table regarding the next use and liveness of x, y, and z.2. In the symbol table, set x to "not live" and "no next use.“3. In the symbol table, set y and z to "live" and the next uses of

y and z to i

can we change the order between 2 and 3?

x = 1 y = x + 3 z = x * 3 x = x * z

Page 24: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

common-subexpression elimination

common-subexpression elimination

Easily identified by DAG representation.

a = b + cb = a - dc = b + cd = a - d

a = b + cb = a - dc = b + cd = b

Page 25: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

DAG Representation of Basic Blocks

a = b + cb = a - d

c = b + cd = a - d

b c

+ d

-

+

a

b,d

c

Page 26: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Use indices to distinguish variable assignments

a = b + cb = a - d

c = b + cd = a - d

b0 c0

+ d0

-

+

a

b,d

c

Page 27: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

DAG and Dead Code

a = b + cb = b - dc = c + de = b + c

b0 c0

+

d0

- +a b c

+ e

• Perform dead code elimination.

• Assume a is not used outside the block.

Page 28: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

algebraic identities

a = x^2b = x*2e = x*2i

c = x/2i

d = 1*xf = x+0

a = x*xb = x+xe = shift(x,i)c = shift(x,-i)d = xf = x

Page 29: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

simple code generation

registers used as operands of instructions can be used to store temporary results can (should) be used as loop indexes due to frequent

arithmetic operation used to manage administrative info (e.g., runtime

stack)

Number of registers is limited Need to allocate them in a clever way Critical for program efficiency.

29

Page 30: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

simple code generation

assume machine instructions of the form LD reg, mem ST mem, reg OP reg,reg,reg

further assume that we have all registers available for our use ignore registers allocated for stack management

30

Page 31: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

simple code generation Translate each 3AC instruction separately A register descriptor keeps track of the variable names

whose current value is in that register. we use only those registers that are available for local use

within a basic block, we assume that initially, all register descriptors are empty.

As code generation progresses, each register will hold the value of zero or more names.

For each program variable, an address descriptor keeps track of the location or locations where the current value of that variable can be found. The location may be a register, a memory address, a stack

location, or some set of more than one of these Information can be stored in the symbol-table entry for that

variable

31

Page 32: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

simple code generationFor each three-address statement x := y op z,

1. Invoke getreg (x := y op z) to select registers Rx, Ry, and Rz.

2. If Ry does not contain y, issue: “LD Ry, y’ ”, for a location y’ of y.

3. If Rz does not contain z, issue: “LD Rz, z’ ”, for a location z’ of z.

4. Issue the instruction “OP Rx,Ry,Rz”

5. Update the address descriptors of x, y, z, if necessary. Rx is the only location of x now, and

Rx contains only x (remove Rx from other address descriptors).

32

Page 33: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

updating descriptors

1. For the instruction LD R, xa) Change the register descriptor for register R so it holds

only x.b) Change the address descriptor for x by adding register R

as an additional location.

2. For the instruction ST x, R change the address descriptor for x to include its own

memory location.

33

Page 34: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

updating descriptors 3. For an operation such as ADD Rx, Ry, Rz,

implementing a 3AC instruction x = y + za) Change the register descriptor for Rx so that it holds only

x.b) Change the address descriptor for x so that its only

location is Rx. Note that the memory location for x is not now in the address descriptor for x.

c) Remove Rx from the address descriptor of any variable other than x.

4. When we process a copy statement x = y, after generating the load for y into register Ry, if needed, and after managing descriptors as for all load statements (rule 1):a) Add x to the register descriptor for Ry.b) Change the address descriptor for x so that its only

location is Ry .

34

Page 35: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

example

35

t= A – Bu = A- Cv = t + u

A = DD = v + u

A B C D = live outside the blockt,u,v = temporaries in local storate

R1 R2 R3

A B C

A B C

D

D t u v

t = A – B LD R1,A LD R2,B SUB R2,R1,R2

A t

R1 R2 R3A,R1 B C

A B C

DR2

D t u v

u = A – C LD R3,C SUB R1,R1,R3

v = t + u ADD R3,R2,R1

u t C

R1 R2 R3

A B C,R3

A B C

DR2

R1

D t u v

u t v

R1 R2 R3

A B C

A B C

DR2

R1

D t uR3

v

Page 36: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

example

36

t= A – Bu = A- Cv = t + u

A = DD = v + u

A B C D = live outside the blockt,u,v = temporaries in local storate

A = D LD R2, D

u A,D v

R1 R2 R3

R2 B C

A B CD,R2

R1

D t uR3

v

D = v + u ADD R1,R3,R1

exit ST A, R2 ST D, R1

D A v

R1 R2 R3R2

B C

A B CR1

D t uR3

v

u t v

R1 R2 R3

A B C

A B C

DR2

R1

D t uR3

v

D A v

R1 R2 R3A,R2 B C

A B CD,R1

D t uR3

v

Page 37: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

design of getReg

many design choices

simple rules If y is currently in a register, pick a register already

containing y as Ry. No need to load this register If y is not in a register, but there is a register that is

currently empty, pick one such register as Ry

complicated case y is not in a register, but there is no free register

Page 38: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

design of getReg instruction: x = y + z y is not in a register, no free register let R be a taken register holding value of a

variable v possibilities:

if v is x, the value computed by the instruction, we can use it as Ry (it is going to be overwritten anyway)

if v is not used later (dead), we can use R as Ry if the value v is available somewhere other than R,

we can allocate R to be Ry (just by updating descriptors).

otherwise: spill the value to memory by ST v,R

Page 39: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

global register allocation

so far we assumed that register values are written back to memory at the end of every basic block

want to save load/stores by keeping frequently accessed values in registers e.g., loop counters

idea: compute “weight” for each variable for each use of v in B prior to any definition of v add 1 point for each occurrence of v in a following block using v add 2

points, as we save the store/load between blocks cost(v) = Buse(v,B) + 2*live(v,B)

use(v,B) is the number of times v is used in B prior to any definition of v

live(v, B) is 1 if v is live on exit from B and is assigned a value in B after computing weights, allocate registers to the “heaviest”

values

Page 40: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Examplea = b + cd = d - be = a + f

bcdf

f = a - d

acde

cdef

b = d + fe = a – c

acdf

bcdef

b = d + c

cdef

bcdef

b,c,d,e,f live

B1

B2 B3

B4

acdef

cost(a) = B use(a,B) + 2*live(a,B) = 4cost(b) = 6cost(c) = 3cost(d) = 6cost(e) = 4cost(f) = 4

b,d,e,f live

Page 41: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

ExampleLD R3,c

ADD R0,R1,R3SUB R2,R2,R1

LD R3,fADD R3,R0,R3

ST e, R3

SUB R3,R0,R2ST f,R3

LD R3,fADD

R1,R2,R3LD R3,c

SUB R3,R0,R3ST e, R3

LD R3,cADD R1,R2,R3

B1

B2 B3

B4

LD R1,bLD R2,d

ST b,R1ST d,R2

ST b,R1ST a,R2

Page 42: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Register Allocation by Graph Coloring

Address register allocation by Spilling operations are costly – minimize them. Finding register allocation that minimizes spilling is

NP-Hard. We use heuristics from graph coloring.

Main idea register allocation = coloring of an interference

graph every node is a variable edge between variables that “interfere” = are both

live at the same time number of colors = number of registers

Page 43: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Example

v1

v2

v3

v4

v5

v6

v7

v8

time

V1

V8

V2

V4

V7

V6

V5

V3• Analyze liveness • Build interference graph• If interfering vertices

get the same register (color), then a spill is needed.

Page 44: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

But note that interference is conservative

a = read();b = read();c = read();a = a + b + c;if (a<10) { d = c + 8; print(c);} else if (a<2o) { e = 10; d = e + a; print(e);} else { f = 12; d = f + a; print(f);} print(d);

a = read();b = read();c = read();a = a + b + c;if (a<10) goto B2 else goto B3

d = c + 8;print(c);

if (a<20) goto B4 else goto B5

e = 10;d = e + a;print(e);

f = 12;d = f + a;print(f);

print(d);

B1

B2B3

B4B5

B6

b

ac

d

ef

dd

Page 45: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Example: Interference Graph

f a b

d e c

a = read();b = read();c = read();a = a + b + c;if (a<10) goto B2 else goto B3

d = c + 8;print(c);

if (a<20) goto B4 else goto B5

e = 10;d = e + a;print(e);

f = 12;d = f + a;print(f);

print(d);

B2B3

B4B5

B6

b

ac

d

ef

dd

Page 46: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Register Allocation by Graph Coloring

variables that interfere with each other cannot be allocated the same register

graph coloring classic problem: how to color the nodes of a graph

with the lowest possible number of colors bad news: problem is NP-complete (to even

approximate) good news: there are pretty good heuristic

approaches

Page 47: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Heuristic Graph Coloring

idea: color nodes one by one, coloring the “easiest” node last

“easiest nodes” are ones that have lowest degree fewer conflicts

algorithm at high-level find the least connected node remove least connected node from the graph color the reduced graph recursively re-attach the least connected node

Page 48: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Heuristic Graph Coloring

f a b

d e c

f a

d e c

f a

d e

f

d e

stack: stack: b

stack: cb stack: acb

Page 49: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Heuristic Graph Coloring

49

f

d e

stack: acb

f

d

stack: eacb

f

stack: deacbstack: fdeacb

f1

stack: deacb

f1

d2

stack: eacb

f1

d2 e1

stack: acb

f1 a2

d2 e1

stack: cb

Page 50: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Heuristic Graph Coloring

f1 a2

d2 e1

f1 a2

d2 e1

f1 a2

d2 e1

stack:

stack: bstack: cb

Result:3 registers for 6 variables

Can we do with 2 registers?

c1

c1

b3

Page 51: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Heuristic Graph Coloring

two sources of non-determinism in the algorithm choosing which of the (possibly many) nodes of

lowest degree should be detached choosing a free color from the available colors

Page 52: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Heuristic Graph Coloring

The above heuristic gives a coloring of the graph. But what we really need is to color the graph with a

given number of colors = number of available registers. Many times this is not possible.

(Telling whether it is possible is NP-Hard.)

We’d like to find the maximum sub-graph that can be colored.

Vertices that cannot be colored will represent variables that will not be assigned a register.

Page 53: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Similar Heuristic

1. Iteratively remove any vertex whose degree < k (with all of its edges).

2. Note: no matter how we color the other vertices, this one can be colored legitimately!

V1

V8

V2

V4

V7

V6

V5

V3

Page 54: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Similar Heuristic

1. Iteratively remove any vertex whose degree < k (with all of its edges).

2. Note: no matter how we color the other vertices, this one can be colored legitimately!

V1

V8

V2

V4

V7

V6

V5

V3

.4Now all vertices are of degree >=k (or graph is empty).5If graph empty: color the vertices one-by-one as in previous

slides. Otherwise ,.6Choose any vertex, remove it from the graph. Implication:

this variable will not be assigned a register. Repeat this step until we have a vertex with degree <k and go back to (1) .

Page 55: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Similar Heuristic

1. Iteratively remove any vertex whose degree < k (with all of its edges).

2. Note: no matter how we color the other vertices, this one can be colored legitimately!

V1

V8

V2

V4

V7

V6

V5

V3

.4Now all vertices are of degree >=k (or graph is empty).5If graph empty: color the vertices one-by-one as in previous

slides. Otherwise ,.6Choose any vertex, remove it from the graph. Implication:

this variable will not be assigned a register. Repeat this step until we have a vertex with degree <k and go back to (1) .

Source of non-determinism: choose which vertex to remove in (6).This decision determines the number of spills.

Page 56: 1 Lecture 10: Code Generation. You are here 2 Executable code exe Source text txt Compiler Lexical Analysis Syntax Analysis Semantic Analysis Inter. Rep

Summary: Code Generation

Depends on the target language and platform. GNU Assembly IA-32 platform.

Basic blocks and control flow graph show program executions paths.

Determining variable liveness in a basic block. useful for many optimizations. Most important use: register allocation.

Simple code generation. Better register allocation via graph coloring

heuristic.