You are on page 1of 22

Code Generation

Code generation phase


Final phase in the compiler model Takes as input:

intermediate representation (IR) code symbol table information

Produces output:
semantically equivalent target program

Code generation phase


Compilers need to produce efficient target programs Includes an optimization phase prior to code generation May make multiple passes over the IR before generating the target program

Target Program Code

The back-end code generator of a compiler may generate different forms of code, depending on the requirements:
Absolute machine code (executable code) Relocatable machine code (object files for linker) Assembly language (facilitates debugging) Byte code forms for interpreters (e.g.

Code generation phase

Code generator has three primary tasks:


Instruction selection Register allocation and assignment Instruction ordering

Instruction selection
choose appropriate target-machine instructions to implement the IR statements

Register allocation and assignment

Code generation phase

Instruction ordering
decide in what order to schedule the execution of instructions

Design of all code generators involve the above three tasks Details of code generation are dependent on the specifics of IR, target language, and run-time system

The Target Machine


Implementing code generation requires thorough understanding of the target machine architecture and its instruction set Our (hypothetical) machine:

Byte-addressable (word = 4 bytes) Has n general purpose registers R0, R1, , Rn1 Two-address instructions of the form op source, destination Op op-code Source, destination data fields
6

The Target Machine: Opcodes


Op-codes (op), for example MOV (move content of source to destination) ADD (add content of source to destination) SUB (subtract content of source from destination)

There are also other ops

The Target Machine: Address modes


Mode Absolute Register Indexed Indirect register Form M R c(R) *R Address M R c+contents(R) contents(R) Added Cost 1 0 1 0

Indirect indexed *c(R)


Literal #c

contents(c+contents(R))
N/A

1
1

Instruction Costs
Machine is a simple processor with fixed instruction costs Define the cost of instruction = 1 + cost(source-mode) + cost(destinationmode)

Examples
Instruction Operation MOV R0,R1 Store content(R0) into register R1 MOV R0,M Store content(R0) into memory location M MOV M,R0 Store content(M) into register R0 MOV 4(R0),M Store contents(4+contents(R0)) into M MOV *4(R0),M Store contents(contents(4+contents(R0))) into M MOV #1,R0 Store 1 into R0 ADD 4(R0),*12(R1) Add contents(4+contents(R0)) to value at location contents(12+contents(R1)) Cost 1 2 2 3 3 2
3

10

Instruction Selection
Instruction selection is important to obtain efficient code Suppose we translate three-address code

x:= y + z

to: MOV

y,R0 ADD z,R0 MOV R0,x

a:=a+1

MOV a,R0 ADD #1,R0 MOV R0,a Cost = 6

Better

Best

ADD #1,a Cost = 3

INC a Cost = 2

11

Instruction Selection: Utilizing Addressing Modes

Suppose we translate a:=b+c into


MOV b,R0 ADD c,R0 MOV R0,a

Assuming addresses of a, b, and c are stored in R0, R1, and R2

MOV *R1,*R0 ADD *R2,*R0 Assuming R1 and R2 contain values of b and c ADD R2,R1 MOV R1,a
12

Need for Global MachineSpecific Code Optimizations

Suppose we translate three-address code


x:=y+z

to: MOV

y,R0 ADD z,R0 MOV R0,x

Then, we translate
a:=b+c d:=a+e

to: MOV
ADD MOV MOV ADD MOV

a,R0 b,R0 R0,a a,R0 e,R0 R0,d

Redundant

13

Register Allocation and Assignment


Efficient utilization of the limited set of registers is important to generate good code Registers are assigned by

Register allocation to select the set of variables that will reside in registers at a point in the code Register assignment to pick the specific register that a variable will reside in

Finding an optimal register assignment in general is NP-complete

14

Example
t:=a*b t:=t+a t:=t/d
{ R1=t } MOV MUL ADD DIV MOV a,R1 b,R1 a,R1 d,R1 R1,t MOV MOV MUL ADD DIV MOV

t:=a*b t:=t+a t:=t/d


{ R0=a, R1=t } a,R0 R0,R1 b,R1 R0,R1 d,R1 R1,t
15

Choice of Evaluation Order

When instructions are independent, their evaluation order can be changed


MOV ADD MOV MOV ADD MOV MUL MOV SUB MOV a,R0 b,R0 R0,t1 c,R1 d,R1 e,R0 R1,R0 t1,R1 R0,R1 R1,t4

a+b-(c+d)*e

t1:=a+b t2:=c+d t3:=e*t2 t4:=t1-t3

reorder
t2:=c+d t3:=e*t2 t1:=a+b t4:=t1-t3

MOV ADD MOV MUL MOV ADD SUB MOV

c,R0 d,R0 e,R1 R0,R1 a,R0 b,R0 R1,R0 R0,t4

16

Two Classes of Storage in Processor

Registers
Fast access, but only a few of them Address space not visible to programmer
Doesnt support pointer access!

Memory
Slow access, but large Supports pointers

4 Distinct Regions of Memory

Code space Instructions to be executed


Best if read-only

Static (or Global) Variables that retain their value over the lifetime of the program Stack Variables that is only as long as the block within which they are defined (local) Heap Variables that are defined by calls to the system storage allocator

Memory Organization
Code
Static Data Stack Code and static data sizes determined by the compiler Stack and heap sizes vary at run-time Stack grows downward Heap grows upward

...
Heap

Some machines have stack/heap switched

Storage Class Selection

Standard (simple) approach


Globals/statics memory Locals
Composite types (structs, arrays, etc.) memory Scalars
Preceded by register keyword? register Rest memory

All memory approach


Put all variables into memory Compiler register allocation relocates some memory variables to registers later

Class Problem
Specify whether each variable is stored in register or memory. For memory, which area of the memory? int a; float j; void foo(int b, double c) { int d; int h[10]; register char i = 5; int *m = new int[10]; }

You might also like