0% found this document useful (0 votes)
3 views20 pages

Intermediate Code Generation

Intermediate code generation translates source programs into machine-independent intermediate languages that are close to machine instructions. Various forms of intermediate languages, such as syntax trees, postfix notation, and three-address code, are utilized, with three-address code being particularly useful for its simplicity and optimizability. The document also discusses the syntax-directed translation into three-address code and the handling of different programming constructs like assignments and procedures.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views20 pages

Intermediate Code Generation

Intermediate code generation translates source programs into machine-independent intermediate languages that are close to machine instructions. Various forms of intermediate languages, such as syntax trees, postfix notation, and three-address code, are utilized, with three-address code being particularly useful for its simplicity and optimizability. The document also discusses the syntax-directed translation into three-address code and the handling of different programming constructs like assignments and procedures.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Intermediate Code Generation

Intermediate Code Generation


 Translating source program into an
“intermediate language.”
◦ Simple
◦ CPU Independent,
◦ …yet, close in spirit to machine language.

 Or, depending on the application other


intermediate languages may be used, but
in general, we opt for simple, well
structured intermediate forms.
Intermediate Code Generation
v Intermediate codes are machine independent codes, but they are close to
machine instructions.
v The given program in a source language is converted to an equivalent program
in an intermediate language by the intermediate code generator.
v Intermediate language can be many different languages, and the designer of the
compiler decides this intermediate language.
q syntax trees can be used as an intermediate language.

q postfix notation can be used as an intermediate language.


q three-address code (Quadraples) can be used as an intermediate language
Ø
we will use quadraples to discuss intermediate code generation
Ø
quadraples are close to machine instructions, but they are not actual machine instructions.

q some programming languages have well defined intermediate languages.


Ø
java – java virtual machine
Ø
prolog – warren abstract machine
Ø
In fact, there are byte-code emulators to execute instructions in these intermediate
languages.
Types of Intermediate Languages
 Graphical Representations.
◦ Consider the assignment a:=b*-c+b*-c:
assign assign

+
a + a

*
* *

b uminus uminus
uminus b

c c
b c
Syntax Dir. Definition for Assignment Statements

PRODUCTION Semantic Rule


S  id := E { [Link] = mknode (‘assign’, mkleaf(id, [Link]), [Link]) }

E  E1 + E2 {[Link] = mknode(‘+’, [Link],[Link]) }

E  E1 * E2 {[Link] = mknode(‘*’, [Link],[Link]) }

E  - E1 {[Link] = mknode(‘uminus’,[Link]) }

E  ( E1 ) {[Link] = [Link] }

E  id {[Link] = mkleaf(id, [Link]) }


Three Address Code
 Statements of general form x:=y op z

 No built-up arithmetic expressions are allowed.

 As a result, x:=y + z * w
should be represented as
t1:=z * w
t2:=y + t1
x:=t2

 Observe that given the syntax-tree or the dag of the graphical


representation we can easily derive a three address code for assignments
as above.

 In fact three-address code is a linearization of the tree.

 Three-address code is useful: related to machine-language/ simple/


optimizable.
Example of 3-address code

t1:=- c t1:=- c
t2:=b * t1 t2:=b * t1
t3:=- c t5:=t2 +t2
t4:=b * t3
a:=t5
t5:=t2 +t4
a:=t5
Types of Three-Address Statements.
Assignment Statement: x:=y op z
Assignment Statement: x:=op z
Copy Statement: x:=z
Unconditional Jump: goto L
Conditional Jump: if x relop y goto L
Stack Operations: Push/pop

More Advanced:
Procedure:
param x1
param x2

param xn
call p,n
Index Assignments:
x:=y[i]
x[i]:=y

Address and Pointer Assignments:


x:=&y
x:=*y
*x:=y
Syntax-Directed Translation into 3-
address code.
 First deal with assignments.
 Use attributes
◦ [Link]: the name that will hold the value of E

Identifier will be assumed to already have the place
attribute defined.
◦ [Link]:hold the three address code statements that
evaluate E (this is the `translation’ attribute).
 Use function newtemp that returns a new temporary
variable that we can use.
 Use function gen to generate a single three address
statement given the necessary information (variable names
and operations).
Syntax-Dir. Definition for 3-address code
PRODUCTION Semantic Rule
S  id := E { [Link] = [Link]||gen([Link] ‘=’ [Link] ‘;’) }
E  E1 + E2 {[Link]= newtemp ;
[Link] = [Link] || [Link] ||
|| gen([Link]‘:=’[Link]‘+’[Link]) }
E  E1 * E2 {[Link]= newtemp ;
[Link] = [Link] || [Link] ||
|| gen([Link]‘=’[Link]‘*’[Link]) }
E  - E1 {[Link]= newtemp ;
[Link] = [Link] ||
|| gen([Link] ‘=’ ‘uminus’ [Link]) }
E  ( E1 ) {[Link]= [Link] ; [Link] = [Link]}
E  id {[Link] = [Link] ; [Link] = ‘’ }

e.g. a := b * - (c+d)
What about things that are not

assignments?
E.g. while statements of the form “while E do S”
(intepreted as while the value of E is not 0 do S)
Extension to the previous syntax-dir. Def.
PRODUCTION
S  while E do S1
Semantic Rule
[Link] = newlabel;
[Link] = newlabel ;
[Link] = gen([Link] ‘:’)
|| [Link]
|| gen(‘if ’ [Link] ‘=’ ‘0’ ‘goto’ [Link])
|| [Link]
|| gen(‘goto’ [Link])
|| gen([Link] ‘:’)
Implementations of 3-address statements
Quadruples op arg1 arg2 result

t1:=- c (0) uminus c t1

t2:=b *t1 (1) * b t1 t2

t3:=- c (2) uminus c

t4:=b * t3 (3) * b t3 t4

t5:=t2 +t4 (4) + t2 t4 t5

a:=t5 (5) := t5 a

Temporary names must be entered into the


symbol table as they are created.
Implementations of 3-address statements, II
op arg1 arg2
 Triples
t1:=- c (0) uminus c

t2:=b * t1 (1) * b (0)

t3:=- c (2) uminus c

t4:=b * t3 (3) * b (2)

t5:=t2 + t4 (4) + (1) (3)

a:=t5 (5) assign a (4)

Temporary names are not entered into the symbol table.


Other types of 3-address statements
 e.g. ternary operations like
x[i]:=y x:=y[i]
 require two or more entries. e.g.
op arg1 arg2

(0) []= x i

(1) assign (0) y

op arg1 arg2

(0) []= y i

(1) assign x (0)


Implementations of 3-address statements, III

 Indirect Triples
op op arg1 arg2

(0) (14) (14) uminus c

(1) (15) (15) * b (14)

(2) (16) (16) uminus c

(3) (17) (17) * b (16)

(4) (18) (18) + (15) (17)

(5) (19) (19) assign a (18)


Dealing with Procedures
P  procedure id ‘;’ block ‘;’
Semantic Rule
begin = newlabel;
Enter into symbol-table in the entry of the procedure name the begin
label.
[Link] = gen(begin ‘:’) || [Link] ||
gen(‘pop’ return_address) || gen(“goto return_address”)

S  call id
Semantic Rule
Look up symbol table to find procedure name. Find its begin label called
proc_begin
return = newlabel;
[Link] = gen(‘push’return); gen(goto proc_begin) || gen(return “:”)
Declarations
Using a global variable offset

PRODUCTION Semantic Rule


PMD {}
M {offset:=0 }
D  id : T { addtype([Link], [Link], offset)
offset:=offset + [Link] }
T  char {[Link] = char; [Link] = 4; }
T  integer {[Link] = integer ; [Link] = 4; }
T  array [ num ] of T1
{[Link]=array(1..[Link],[Link])
[Link] = [Link] * [Link]}
T  ^T1 {[Link] = pointer([Link]);
[Link] = 4}
Nested Procedure Declarations
 For each procedure we should create a symbol table.

mktable(previous) – create a new symbol table where previous is the parent symbol table
of this new symbol table

enter(symtable,name,type,offset) – create a new entry for a variable in the given


symbol table.

enterproc(symtable,name,newsymbtable) – create a new entry for the procedure in


the symbol table of its parent.

addwidth(symtable,width) – puts the total width of all entries in the symbol table into
the header of that table.

 We will have two stacks:


◦ tblptr – to hold the pointers to the symbol tables
◦ offset – to hold the current offsets in the symbol tables in tblptr stack.
Keeping Track of Scope Information
Consider the grammar fraction:

PD
D  D ; D | id :T | proc id ; D ; S

Each procedure should be allowed to


use independent names.
Nested procedures are allowed.
Keeping Track of Scope Information
(a translation scheme)

PMD { addwidth(top(tblptr), top(offset)); pop(tblptr);


pop(offset) }

M { t:=mktable(null); push(t, tblptr); push(0, offset)}

D  D1 ; D2 ...

D  proc id ; N D ; S { t:=top(tblpr); addwidth(t,top(offset));


pop(tblptr); pop(offset);
enterproc(top(tblptr), [Link], t)}
N   {t:=mktable(top(tblptr)); push(t,tblptr); push(0,offset);}

D  id : T {enter(top(tblptr), [Link], [Link], top(offset);


top(offset):=top(offset) + [Link]

You might also like