Code Generation Professor Yihjia Tsai Tamkang University
Dec 20, 2015
9-2
Outline
• Introduction• Run-time Storage Management• Basic Blocks• Flow Graphs• Liveness Analysis
• Student Presentations
9-3
Introduction
• Requirements of a code generator– Code generated must be correct– Code generated must be high quality
(which uses resources effectively on target machine)
– Code must have very low cost (where cost is execution time or code size etc.,…)
– Code generator itself must be efficient
9-4
Code Generation: Overview• Identify program segments in IR as a dag• Partition the dag into a set of disjoint
trees• Machine instructions are (tree) patterns
– Each pattern has a cost
• Selection of machine instructions means covering (or tiling) each tree of the dag by patterns – So that total cost is the lowest (or very low)
9-5
Issues to Consider
• What is the input (form of IR)?– May assume input is error-free
• What is the target?– Machine, absolute/relocatable/assembly
• Memory mgmt.– Names in IR become memory addresses
• Instruction selection• Register allocation
9-6
Run-time Storage Mgmt.
• How to manage activation records?• Static allocation
– Position of activation record fixed at compile time
• Stack allocation– New activation record pushed onto stack
at each invocation of a function– Record popped when activation ends
9-7
Static Allocation
• A “call” statement in IR implemented by a sequence of 2 target-code instructions– MOV (save return addr in callee activation
record ) and a GOTO (to callee code)– Return from callee implemented by GOTO (to
location pointed by callee activation record)
• Example (E.g. 9.1, p. 523, Dragon book)– Assume “action” instruction takes 20 bytes
9-8
Example• Input: 3AC
// code for cactioncall pactionhalt
// code for pactionreturn
return addr
j
Activation record for c (64 bytes)
0:
60:
return addr
n
Activation record for p (88 bytes)
0:
84:
9-9
Example …contd
// code for c100: action // c’s activation record120: MOV #140, 364 300: …..132: GOTO 200 304: …..140: action …….160: halt 360: ….
// p’s activation record//code for p 364: …200: action 368: …220: GOTO *364 …….
448: …
9-10
Stack Allocation
• Uses relative addresses for storage in activation records– Positions not known until run-time
• Relative addresses taken as offsets from a known position (e.g., SP register)– Function call: caller increments SP, saves
return addr and transfers control to callee– Return: callee transfers control back, caller
restores SP
9-11
Example
// code for sactioncall qactionhalt
// code for pactionreturn
// code for qactioncall pactioncall qactioncall qreturn
Input: 3ACHow can we generate code with stack allocation?(Assume: stack grows upwards)
9-12
Example …contd
// code for s100: MOV #600, SP108: action128: ADD #ssize, SP136: MOV #152, *SP144: GOTO 300152: SUB #ssize, SP160: action180: halt
// code for p200: action220: GOTO *0(SP)
// stack starts here600:
#ssize, #qsize : sizes of activation records for s, q
9-13
Example …contd// code for q
300: action320: ADD #qsize,
SP328: MOV #344, *SP336: GOTO 200344: SUB #qsize, SP352: action372: ADD #qsize,
SP380: MOV #396, *SP388: GOTO 300396: SUB #qsize, SP404: action …
// stack starts here600:
// code for p200: action220: GOTO *0(SP)
9-14
Basic Blocks
• A basic block is a sequence of consecutive statements in which flow of control:– Enters at the beginning– Leaves at the end– (no halt or branch except at the end)
• Ignore calculations and storage operations• Can lump together non-branch
instructions
9-15
Algorithm to Obtain Basic Blocks• Input: a program of 3AC statements• Output: a list of basic blocks (each 3AC
statement in exactly one basic block)1. Determine the set of leaders, i.e., 1st stmts
a) The 1st stmt of the program is a leaderb) A target stmt of a GOTO is a leaderc) A stmt immediately following a GOTO is a leader
2. For each leader, its basic block ends before next basic block or at the end of program
9-16
Exercise
• Given the following code segment, obtain:– The 3AC statements for this computation– The list of basic blocks by applying the
algorithm to the 3ACprod = 0; i = 1;do {
prod = prod + a[i] * b[i];i = i + 1;
} while ( i <= 20 );
9-17
Flow Graphs
• A directed graph representing a program– Also called control-flow graph
• Nodes in the graph represent computation– Each statement (or basic block) is a node– One node is distinguished as initial
• Directed edges represent flow of control– There is an edge from node n1 to node n2 if n2
can immediately follow n1 in execution
9-18
Flow Graphs …contd
• Edge from n1 to n2 exists if:– There is a GOTO from (the last stmt of) n1
to (the 1st stmt of) n2– n2 immediately follows n1 in the sequence
of the program and n1 does not end with GOTO
• Here, we say:– n1 a predecessor of n2, n2 a successor of
n1
• Example : for code in slide 9-16
9-19
Exercise
• Draw the flow graph for the following code segment (may consider a stmt as a node)
a ← 0
L1: b ← a + 1
c ← c + b
a ← b * 2
if a < N goto L1
return c
9-20
Liveness Analysis
• An example application– IR code (say 3AC) may have large # of
temps and program vars– But we have limited # of registers– Need to know which temps/vars are in
use at the same time (for efficient use of registers)
• A variable is live if it holds a value needed in the future
• This analysis is called liveness analysis
9-21
Liveness Analysis …contd
• Within a basic block context– A var is live at a given point if its value is used
after that point (maybe in another basic block)• A var is dead if it is never used later• Liveness analysis is done using a flow graph in
which each stmt is a node• We analyze liveness by going backward in a basic
block starting from the end
9-22
Example
1) a ← 0
2) L1: b ← a + 1
3) c ← c + b
4) a ← b * 2
5) if a < N goto L1
6) return c
• Live range of b:{34, 23}, a: {12, 452}, c:{12…6}– Vars a and b can share one register
9-23
Liveness Analysis …contd
• Next-use info collected in this analysis• Can be used in different situations
– Register assignment, temp’s in stack frame• “Use” of a var/name
– Suppose stmt i is “x := k”; stmt j has x as an operand; control can flow from i to j with no intervening stmt assigning a value to x
– We say stmt j uses value of x computed at i
9-24
Liveness Analysis …contd
• At a stmt k: “x := y <op> z”, check symbol table and update info as follows
1. Attach to stmt k, current info in symbol table on status (live/dead) & next use for x, y and z
2. In symbol table, set x to dead and no next use3. In symbol table, set y, z to live and their next
uses to k – Steps 2 and 3 must be in that order! (because
we may have “x := x <op> y”
9-25
Example
• Suppose we have: “d = (a+b) * (c-b);”• Suppose the 3AC for this is in a basic
block as:(1) u := a + b(2) v := c – b(3) w := u * v(4) d := w
– Show how the liveness analysis proceeds
9-26
Example
(1) u := a + b(2) v := c – b(3) w := u * v(4) d := w
• At the end of block, in the symbol table– Program vars a, b, c, d are marked “live”– Temp vars u, v, w marked “dead”– All vars marked “no next use”
9-27
Symbol Table (at start)
Variable Status Next use
a Live None
b Live None
c Live None
d Live None
u Dead None
v Dead None
w Dead None
9-28
While at line (4): Attached InfoLine Stmt Status Next use
(1) u := a + b
(2) v := c – b
(3) w := u * v
(4) d := w d live, w dead d, w: none
9-29
Symbol Table [after line (4)]
Variable Status Next use
a Live None
b Live None
c Live None
d Dead None
u Dead None
v Dead None
w Live (4)
9-30
While at line (3): Attached InfoLine Stmt Status Next use
(1)u := a + b
(2)v := c – b
(3)w := u * v
w live; u, v dead
w:(4); u, v: none
(4) d := w d live, w dead d, w: none
9-31
Symbol Table [after line (3)]
Variable Status Next use
a Live None
b Live None
c Live None
d Dead None
u Live (3)
v Live (3)
w Dead None
9-32
At the end: Attached Info
Line Stmt Status Next use
(1)u := a + b
u, a, b: liveu: (3); b(2);
a: none
(2)v := c – b
v, b, c: livev: (3); b, c:
none
(3)w := u * v
w live; u, v dead
w:(4); u, v: none
(4) d := w d live, w dead d, w: none
This info used later during code generation
9-33
Dataflow Problems
• Liveness of variables flows along edges of flow graps
• Determining the live range of each var is an example of a dataflow problem
• Other examples– Estimate values of a var at a given point– Finding available expressions and
deleting duplicates– Reaching expressions analysis
9-34
Storage for Temp’s
• Temporary names are generated by the compiler during compilation (e.g., in 3AC)
• Temp’s can be held in activation records– But with many temp’s, storage requirement
can be large• But we may be able to pack 2 temp’s in the same
location if they are not live simultaneously– Next-use info within basic blocks can be used
9-35
Transformations on Basic Blocks• A basic block computes a set of
expressions that are live on exit from block
• Many transformations possible within a block without changing these expressions– Local optimizations– Improve the target code for the block
9-36
Example Transformations• Common sub-expression elimination
• Dead-code elimination– Suppose x is dead (never used
subsequently) at the point of stmt “x = y + z;” in a basic block
– Then this stmt can be safely removed
9-37
Example Transformations …contd
• Constant folding– Sub-expressions whose operands are
constants can be replaced by the values at compile-time
• Copy propagation– If we have “x = y;” followed later by a
use of x as an operand, we may substitute y for x; the copy stmt may become useless code