38
Code Generation Professor Yihjia Tsai Tamkang University

Code Generation Professor Yihjia Tsai Tamkang University

  • View
    231

  • Download
    0

Embed Size (px)

Citation preview

Code Generation

Professor Yihjia TsaiTamkang University

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

9-38

Example Transformations …contd

• Reduction in strength– Replacing expensive operations by

cheaper ones– E.g., replace multiplication by two by

shifting

• Renaming temp variables• Interchange of statements