You are on page 1of 16

Intermediate Code Generation

1
Intermediate Code Generation
• The compiler converts the source program
into an intermediate representation at the
end of the analysis phase

• The use of machine independent


Intermediate Code helps to:
– Facilitate retargetting the compiler to another
platform
– Apply machine independent code optimization
2
Intermediate Languages
• The intermediate code may be represented
using any one of the following:
– Abstract Syntax Tree
parse tree without syntactic sugar
– Postfix notation
Read more about Abstract tree & Postfix notation
– Three Address Code
The 3 @ code is a sequence of statements of the form
x := y op z or x := op z
where x, y, and z are either names, constants or compiler
generated temporaries. Op is an operator such as integer to
floating point arithmetic operator or logical operator on boolean
data.

3
Three Address Code
• Important notes about statements in three
address code statements:
– No predefined arithmetic (or any) operator is
permitted.
– Only one operation is allowed in a statement
Ex. w = x+ y * z
becomes
t1 = y * z
w = x + t1
• 3 @ code statements can have labels and
statements for flow control (ex. goto) 4
Types of 3 @ Statements
• Assignment (binary operation)
– x := z op w
• Assignment (unary operation)
– x := op y
• Copy
– x := y
• Unconditional Jump
– Goto L
• Conditional Jump
– if x relop y goto L 5
Types of Statements (cont'd)
• Function call
– Parameter specification
• param x1
– Calling the function
• call P, N { P : function & N : no. of parameters }
• Indexed Arguments
– x := y[I] { x = value at address y+I }
– y[I] := x { value at address y+I = x }

6
Types of Statements (cont'd)
• Address and Pointer Assignments
– x := &y { x = address of y }
– x := *y { x = the value at address y }
– *x := y { value at address x = y }

7
Syntax Directed Translation into
Three Address Code
• The 3 @ code is generated either as an attribute
of the parse tree or by writing the statements in
a file as soon as they are generated.

• When the 3 @ code is generated, it is often


necessary to use temporary variables and
temporary names.

• For this purpose, the following functions are


given:
8
Syntax Directed Translation into
Three Address Code (cont'd)
• NewTemp() :
each time it is called, gives distinct names that can be
used for temporary variables.

• NewLabel() :
each time it is called gives distinct names that
can be used for label names.

• In addition, we use the function gen to create


three address code statements from a number of
strings.

9
3 @ Code Generation
(Assignment & Expression)
S → id := E S.code := E. code || gen(id.lexeme,”:=”, E.place)
E1 → E2 + E3 E1.place := newTemp();
E1.code := E2.code || E3.code || gen(E1.place, “:=”, E2.place, “+”,
E3.place)
E1 → E2 * E3
E1 → - E2 E1.place := newTemp();
E1.code := E2.code || gen(E1.place, “:=”, “-”, E2.place)
E1 → (E2) E1.code := E2.code
E1.place := E2.place
E → id E.place := id.lexeme
E1 → E2 < E3 E1.place = newTemp()
E1.code = E2.code || E3.code || gen(E1.place, “:=“, E2.place, “<“,
E3.place);
10
3 @ Code Generation (Assignment
& Expression)
S1 → while E do S2
S1.begin := newLabel();
S1.after := newLabel();
S1.code := gen(S1.begin, “:”) || E.code || gen(
“if”, E.place, “= 0 goto”, S1.after) || S2.code ||
gen( “goto”, S1.begin) || gen( S1.after, “:”);

11
3 @ Code Generation
(Assignment & Expression)
• Example:
1. Consider the string:
A := B + C
Draw the decorated parse tree based on the
previous syntax directed translation.
2. Consider the string:
while a < b do a := a + 1
Draw the decorated parse tree.

12
Declarations
• While process declarations, the compiler
– reserves memory area for the variables
– stores the relative address of each variable in the symbol table (the
relative address is an address in the static data area relative to the
beginning – offset address)
• For this purpose, the compiler maintains an offset variable
that indicates the first address not yet allocated.
• Initially, offset is set to zero.
• Each time an address is allocated to a variable, the offset
is incremented by the width of the data object denoted by
the name.
• The procedure enter (name, type, address) creates a
symbol table entry for name with type type and address
address. 13
Declarations (cont’d)
P → {offset = 0} D S
D → D;D
D → id : T enter(id.lexeme, T.type, offset);
T → integer T.type = integer;
T.size = 2;
T → real T.type = real;
T.size = 4;
T → array[num] of T T1.type = array([num.value], T2.type);
T1.size = num.value*T2.size;
T → ^T T1.type = pointer( T2.type);
T1.size = 2;
14
Declarations (cont’d)
• Example
Consider the following declaration
x : integer;
y : real;
z : char;
t : array[10] of integer;
v : ^Integer;
What would be the content of the symbol
table after this declaration is processed?
15
Declarations (cont’d)
Symbol table after processing the previous declarations.

Name Type address


x Integer 0
y Real 2
z Char 6
t Array([10], Integer) 7
v Pointer(Integer) 27

16

You might also like