Prof Monika Shah (NU) 1
Code Generation (Part -3)
Course : 2CS701/IT794 – Compiler
Construction
Prof Monika Shah
Nirma University
Ref : Ch.9 Compilers Principles, Techniques, and Tools by Alfred Aho, Ravi Sethi, and Jeffrey Ullman
Prof Monika Shah (NU) 2
Glimpse
Part-1
• Introduction
• Code Generation Issues
Part-2
• Basic Code Generation Case Study
• Introduction to Basic Block, and Control Flow Diagram
Part-3
• Algorithm : Code Generator using getReg( )
• Register Allocation Problem
• Use and Live to find optimal use of registers
• Global Register Allocation with Graph Coloring
Prof Monika Shah (NU) 3
A Code Generator
• Generates target code
• Input : Sequence of three-address statements
• Approach :
• Uses next-use information
• Uses new function getreg to assign registers to variables
• Computed results are kept in registers as long as possible, if:
• Result is needed in another computation
• Register is kept up to a procedure call or end of block
• Checks if operands to three-address code are available in registers
Prof Monika Shah (NU) 4
The Code Generation Algorithm
• For each statement x := y op z
1. Find location L = getreg ( y, z)
2. If y  L then generate
MOV y’,L
where y’ denotes one of the locations where the value of y is available (choose
register if possible)
3. Generate
OP z’,L
where z’ is one of the locations of z;
Update register/address descriptor of x to include L
4. If y and/or z has no next use and is stored in register, update register
descriptors to remove y and/or z
Prof Monika Shah (NU) 5
The getreg(y,z) Algorithm
1. If y is stored in a register R and R only holds the
value y, and y has no next use, then return R;
Update address descriptor: value y no longer in R
2. Else, return a new empty register if available
3. Else, find an occupied register R;
Store contents (register spill) by generating
MOV R,M
for every M in address descriptor of y;
Return register R
4. Return a memory location
Simplified version:
Return Register allocated to Y,
iff
• The register has no next-use
• No other register holds Y
Else, return any free register
Else, store any R to M
and return this freed R
Else, return Memory Location
Prof Monika Shah (NU) 6
Register and Address Descriptors
• A register descriptor : Specify what the register contains at a
particular point in the code, e.g.
MOV y,R0 “R0 contains a”
• An address descriptor : Specify locations, where value of
variables(address) are stored at runtime” e.g.
MOV x,R0
MOV R0,R1 “x in R0 and R1”
Prof Monika Shah (NU) 7
Code Generation Example
Statements
Code
Generated
Register
Descriptor
Address
Descriptor
t := a - b
u := a - c
v := t + u
d := v + u
Registers empty
MOV a,R0
SUB b,R0
getreg( ) returns R0 for a
R0 contains t t in R0
a is not in Registers
getreg( ) returns R1 for a
MOV a,R1
SUB c,R1
R0 contains t
R1 contains u
t in R0
u in R1
t is available in R0
getreg( ) returns R0 for t
ADD R1,R0 R0 contains v
R1 contains u
v in R0
u in R1
v is available in R0
u is available in R1
ADD R1,R0
MOV R0,d
R0 contains d d in R0
and
memory
Prof Monika Shah (NU) 8
Advantage and disadvantage of getReg
• +ve : Simple
• -ve : Registers hold values for single basic block
• -ve: sub-optimal
• All live variables in registers are stored (flushed) at the end of a
block
• All live variables at entry are loaded in the registers
Prof Monika Shah (NU) 9
Register Allocation Problem
• Register access is faster than other memory
• Intermediate Code use many temporary variables and Registers are
limited
• Register allocation :
• Rewrite code to use fewer temporary variables than machine registers
• Assign more temporaries to a register
Prof Monika Shah (NU) 10
Example
Consider the program
a := c + d
e := a + b
f := e - 1
with the assumption that a and e die after use. Temporary a can be “reused”
after e := a + b Can allocate a, e, and f all to one register (r1):
Basic Rule : t1 and t2 can share same registers , if at-most only one (t1 or t2)
live at any point of time
r1 := r2 + r3
r1 := r1 + r4
r1 := r1 - 1
Prof Monika Shah (NU) 11
Solution to Reduce number of load and
store
• keep these registers consistent across basic block
boundaries
• Keeping variables in registers in looping code can result in big
savings
• Global register allocation assigns variables to limited number
of available registers and attempts to keep these registers
consistent across basic block boundaries
Prof Monika Shah (NU) 12
Allocating Registers in Loops
• Suppose loading a variable x has a cost of 2
• Suppose storing a variable x has a cost of 2
• Benefit of allocating a register to a variable x within a loop L is
BL ( use(x, B) + 2 live(x, B) )
where,
• use(x, B) is the number of times x is used in B
• cost (use) is due to variables need to be loaded before use
• live(x, B) = true if x is live on exit from B
• cost (live) is due to variables need to be stored at end of block if live at end,
• cost (store) is due to variables need to be loaded at enty of block if live at
beginning of block
Prof Monika Shah (NU) 13
Control flow Graph of an Sample code
Prof Monika Shah (NU) 14
Control flow Graph of an Sample code
ID Use
(B1)
Live
(B1)
Use
(B2)
Live
(B2)
Use
(B3)
Live
(B3)
Use
(B4)
Live
(B4)
Total
cost
a 0 1 1 0 1 0 0 0 4
b 2 0 0 0 0 1 0 1 6
c 1 0 0 0 1 0 1 0 3
d 1 1 1 0 1 0 1 0 6
e 0 1 0 0 0 1 0 0 4
f 1 0 0 1 1 0 0 0 4
Prof Monika Shah (NU) 15
Reduce cost of load and store variables
• Basic Approach to save cost of load and save
• Keep variables allocated to registers
• Do not store at end of block, if live after
• Do not load at beginning of block, if live at entry of block
• What if Number of variables in a loop are more than number
of machine registers?
• Give priority to those variables having maximum cost benefit
• For example. Variables b and d have maximum cost benefit as per previous
slides
Prof Monika Shah (NU) 16
Global Register Allocation with Graph
Coloring
• When a register is needed but all available registers are in use,
the content of one of the used registers must be stored
(spilled) to free a register
• Graph coloring allocates registers and attempts to minimize
the cost of spills
• Build a conflict graph (interference graph)
• Find a k-coloring for the graph, with k the number of registers
Prof Monika Shah (NU) 17
Register Allocation with Graph Coloring: Example
a := read();
b := read();
c := read();
a := a + b + c;
if (a < 10) {
d := c + 8;
write(c);
} else if (a < 20) {
e := 10;
d := e + a;
write(e);
} else {
f := 12;
d := f + a;
write(f);
}
write(d);
Prof Monika Shah (NU) 18
Register Allocation with Graph Coloring: Live Ranges
a := read();
b := read();
c := read();
a := a+b+c;
a < 20
a < 10
d := c+8;
write(c);
f := 12;
d := f+a;
write(f);
e := 10;
d := e+a;
write(e);
write(d);
a
b
c
e f
d
d
d
a
f b
d e c
Interference graph:
connected vars have
overlapping ranges
Live range
of b
Prof Monika Shah (NU) 19
Register Allocation with Graph Coloring: Solution
a
f b
d e c
Interference graph
2
1 3
2 1 1
Solve Three registers:
a = r2
b = r3
c = r1
d = r2
e = r1
f = r1
r2 := read();
r3 := read();
r1 := read();
r2 := r2 + r3 + r1;
if (r2 < 10) {
r2 := r1 + 8;
write(r1);
} else if (r2 < 20) {
r1 := 10;
r2 := r1 + r2;
write(r1);
} else {
r1 := 12;
r2 := r1 + r2;
write(r1);
}
write(r2);
Approach : Assign different color (registers) to
connected variables

Code Generation Part-3 in Compiler Construction

  • 1.
    Prof Monika Shah(NU) 1 Code Generation (Part -3) Course : 2CS701/IT794 – Compiler Construction Prof Monika Shah Nirma University Ref : Ch.9 Compilers Principles, Techniques, and Tools by Alfred Aho, Ravi Sethi, and Jeffrey Ullman
  • 2.
    Prof Monika Shah(NU) 2 Glimpse Part-1 • Introduction • Code Generation Issues Part-2 • Basic Code Generation Case Study • Introduction to Basic Block, and Control Flow Diagram Part-3 • Algorithm : Code Generator using getReg( ) • Register Allocation Problem • Use and Live to find optimal use of registers • Global Register Allocation with Graph Coloring
  • 3.
    Prof Monika Shah(NU) 3 A Code Generator • Generates target code • Input : Sequence of three-address statements • Approach : • Uses next-use information • Uses new function getreg to assign registers to variables • Computed results are kept in registers as long as possible, if: • Result is needed in another computation • Register is kept up to a procedure call or end of block • Checks if operands to three-address code are available in registers
  • 4.
    Prof Monika Shah(NU) 4 The Code Generation Algorithm • For each statement x := y op z 1. Find location L = getreg ( y, z) 2. If y  L then generate MOV y’,L where y’ denotes one of the locations where the value of y is available (choose register if possible) 3. Generate OP z’,L where z’ is one of the locations of z; Update register/address descriptor of x to include L 4. If y and/or z has no next use and is stored in register, update register descriptors to remove y and/or z
  • 5.
    Prof Monika Shah(NU) 5 The getreg(y,z) Algorithm 1. If y is stored in a register R and R only holds the value y, and y has no next use, then return R; Update address descriptor: value y no longer in R 2. Else, return a new empty register if available 3. Else, find an occupied register R; Store contents (register spill) by generating MOV R,M for every M in address descriptor of y; Return register R 4. Return a memory location Simplified version: Return Register allocated to Y, iff • The register has no next-use • No other register holds Y Else, return any free register Else, store any R to M and return this freed R Else, return Memory Location
  • 6.
    Prof Monika Shah(NU) 6 Register and Address Descriptors • A register descriptor : Specify what the register contains at a particular point in the code, e.g. MOV y,R0 “R0 contains a” • An address descriptor : Specify locations, where value of variables(address) are stored at runtime” e.g. MOV x,R0 MOV R0,R1 “x in R0 and R1”
  • 7.
    Prof Monika Shah(NU) 7 Code Generation Example Statements Code Generated Register Descriptor Address Descriptor t := a - b u := a - c v := t + u d := v + u Registers empty MOV a,R0 SUB b,R0 getreg( ) returns R0 for a R0 contains t t in R0 a is not in Registers getreg( ) returns R1 for a MOV a,R1 SUB c,R1 R0 contains t R1 contains u t in R0 u in R1 t is available in R0 getreg( ) returns R0 for t ADD R1,R0 R0 contains v R1 contains u v in R0 u in R1 v is available in R0 u is available in R1 ADD R1,R0 MOV R0,d R0 contains d d in R0 and memory
  • 8.
    Prof Monika Shah(NU) 8 Advantage and disadvantage of getReg • +ve : Simple • -ve : Registers hold values for single basic block • -ve: sub-optimal • All live variables in registers are stored (flushed) at the end of a block • All live variables at entry are loaded in the registers
  • 9.
    Prof Monika Shah(NU) 9 Register Allocation Problem • Register access is faster than other memory • Intermediate Code use many temporary variables and Registers are limited • Register allocation : • Rewrite code to use fewer temporary variables than machine registers • Assign more temporaries to a register
  • 10.
    Prof Monika Shah(NU) 10 Example Consider the program a := c + d e := a + b f := e - 1 with the assumption that a and e die after use. Temporary a can be “reused” after e := a + b Can allocate a, e, and f all to one register (r1): Basic Rule : t1 and t2 can share same registers , if at-most only one (t1 or t2) live at any point of time r1 := r2 + r3 r1 := r1 + r4 r1 := r1 - 1
  • 11.
    Prof Monika Shah(NU) 11 Solution to Reduce number of load and store • keep these registers consistent across basic block boundaries • Keeping variables in registers in looping code can result in big savings • Global register allocation assigns variables to limited number of available registers and attempts to keep these registers consistent across basic block boundaries
  • 12.
    Prof Monika Shah(NU) 12 Allocating Registers in Loops • Suppose loading a variable x has a cost of 2 • Suppose storing a variable x has a cost of 2 • Benefit of allocating a register to a variable x within a loop L is BL ( use(x, B) + 2 live(x, B) ) where, • use(x, B) is the number of times x is used in B • cost (use) is due to variables need to be loaded before use • live(x, B) = true if x is live on exit from B • cost (live) is due to variables need to be stored at end of block if live at end, • cost (store) is due to variables need to be loaded at enty of block if live at beginning of block
  • 13.
    Prof Monika Shah(NU) 13 Control flow Graph of an Sample code
  • 14.
    Prof Monika Shah(NU) 14 Control flow Graph of an Sample code ID Use (B1) Live (B1) Use (B2) Live (B2) Use (B3) Live (B3) Use (B4) Live (B4) Total cost a 0 1 1 0 1 0 0 0 4 b 2 0 0 0 0 1 0 1 6 c 1 0 0 0 1 0 1 0 3 d 1 1 1 0 1 0 1 0 6 e 0 1 0 0 0 1 0 0 4 f 1 0 0 1 1 0 0 0 4
  • 15.
    Prof Monika Shah(NU) 15 Reduce cost of load and store variables • Basic Approach to save cost of load and save • Keep variables allocated to registers • Do not store at end of block, if live after • Do not load at beginning of block, if live at entry of block • What if Number of variables in a loop are more than number of machine registers? • Give priority to those variables having maximum cost benefit • For example. Variables b and d have maximum cost benefit as per previous slides
  • 16.
    Prof Monika Shah(NU) 16 Global Register Allocation with Graph Coloring • When a register is needed but all available registers are in use, the content of one of the used registers must be stored (spilled) to free a register • Graph coloring allocates registers and attempts to minimize the cost of spills • Build a conflict graph (interference graph) • Find a k-coloring for the graph, with k the number of registers
  • 17.
    Prof Monika Shah(NU) 17 Register Allocation with Graph Coloring: Example a := read(); b := read(); c := read(); a := a + b + c; if (a < 10) { d := c + 8; write(c); } else if (a < 20) { e := 10; d := e + a; write(e); } else { f := 12; d := f + a; write(f); } write(d);
  • 18.
    Prof Monika Shah(NU) 18 Register Allocation with Graph Coloring: Live Ranges a := read(); b := read(); c := read(); a := a+b+c; a < 20 a < 10 d := c+8; write(c); f := 12; d := f+a; write(f); e := 10; d := e+a; write(e); write(d); a b c e f d d d a f b d e c Interference graph: connected vars have overlapping ranges Live range of b
  • 19.
    Prof Monika Shah(NU) 19 Register Allocation with Graph Coloring: Solution a f b d e c Interference graph 2 1 3 2 1 1 Solve Three registers: a = r2 b = r3 c = r1 d = r2 e = r1 f = r1 r2 := read(); r3 := read(); r1 := read(); r2 := r2 + r3 + r1; if (r2 < 10) { r2 := r1 + 8; write(r1); } else if (r2 < 20) { r1 := 10; r2 := r1 + r2; write(r1); } else { r1 := 12; r2 := r1 + r2; write(r1); } write(r2); Approach : Assign different color (registers) to connected variables