0% found this document useful (0 votes)
151 views

Unit-5 Compiler Design - Code Generation

The document discusses intermediate code generation in compilers. It covers various topics related to intermediate code representation including: - Variants of syntax trees like DAGs to represent common subexpressions. - Three-address code as an intermediate representation where each instruction has at most three operands. - Generating three-address code for expressions, control flow statements, and performing type checking. - Concepts like backpatching to avoid an extra pass for setting symbolic labels in conditional jumps.

Uploaded by

Amulya Reddy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
151 views

Unit-5 Compiler Design - Code Generation

The document discusses intermediate code generation in compilers. It covers various topics related to intermediate code representation including: - Variants of syntax trees like DAGs to represent common subexpressions. - Three-address code as an intermediate representation where each instruction has at most three operands. - Generating three-address code for expressions, control flow statements, and performing type checking. - Concepts like backpatching to avoid an extra pass for setting symbolic labels in conditional jumps.

Uploaded by

Amulya Reddy
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 42

Chapter 6

Intermediate Code Generation

By Varun Arora
Outline
 Variants of Syntax Trees
 Three-address code
 Types and declarations
 Translation of expressions
 Type checking
 Control flow
 Backpatching

By Varun Arora
Introduction
 Intermediate code is the interface between front end
and back end in a compiler
 Ideally the details of source language are confined to
the front end and the details of target machines to the
back end (a m*n model)
 In this chapter we study intermediate representations,
static type checking and intermediate code generation

Static Intermediate Code


Parser
Checker Code Generator Generator
Front end
By Varun Arora
Back end
Variants of syntax trees
 It is sometimes beneficial to crate a DAG instead of
tree for Expressions.
 This way we can easily show the common sub-
expressions and then use that knowledge during code
generation
 Example: a+a*(b-c)+(b-c)*d

+ *

*
d
a -

By Varun Arora b c
SDD for creating DAG’s
Production Semantic Rules
1) E -> E1+T E.node= new Node(‘+’, E1.node,T.node)
2) E -> E1-T E.node= new Node(‘-’, E1.node,T.node)
3) E -> T E.node = T.node
4) T -> (E) T.node = E.node
5) T -> id T.node = new Leaf(id, id.entry)
6) T -> num T.node = new Leaf(num, num.val)
Example:
1) p1=Leaf(id, entry-a) 8) p8=Leaf(id,entry-b)=p3
2) P2=Leaf(id, entry-a)=p1 9) p9=Leaf(id,entry-c)=p4
3) p3=Leaf(id, entry-b) 10) p10=Node(‘-’,p3,p4)=p5
4) p4=Leaf(id, entry-c) 11) p11=Leaf(id,entry-d)
5) p5=Node(‘-’,p3,p4) 12) p12=Node(‘*’,p5,p11)
6) p6=Node(‘*’,p1,p5) 13) p13=Node(‘+’,p7,p12)
7) p7=Node(‘+’,p1,p6) By Varun Arora
Value-number method for
constructing DAG’s
= id To entry for i
num 10
+ + 1 2
3 1 3
i 10

 Algorithm
 Search the array for a node M with label op, left child l
and right child r
 If there is such a node, return the value number M
 If not create in the array a new node N with label op, left
child l, and right child r and return its value
 We may use a hash table
By Varun Arora
Three address code
 In a three address code there is at most one operator at
the right side of an instruction
 Example:

+
t1 = b – c
+ * t2 = a * t1
t3 = a + t2
* t4 = t1 * d
d
t5 = t3 + t4
a -

b c

By Varun Arora
Forms of three address
instructions
 x = y op z
 x = op y
 x=y
 goto L
 if x goto L and ifFalse x goto L
 if x relop y goto L
 Procedure calls using:
 param x
 call p,n
 y = call p,n
 x = y[i] and x[i] = y
 x = &y and x = *y and *x =y

By Varun Arora
Example
 do i = i+1; while (a[i] < v);

L: t1 = i + 1 100: t1 = i + 1
i = t1 101: i = t1
t2 = i * 8 102: t2 = i * 8
t3 = a[t2] 103: t3 = a[t2]
if t3 < v goto L 104: if t3 < v goto 100

Symbolic labels Position numbers

By Varun Arora
Data structures for three
address codes
 Quadruples
 Has four fields: op, arg1, arg2 and result
 Triples
 Temporaries are not used and instead references to
instructions are made
 Indirect triples
 In addition to triples we use a list of pointers to triples

By Varun Arora
Three address code
Example t1 = minus c
t2 = b * t1
 b * minus c + b * minus c t3 = minus c
t4 = b * t3
t5 = t2 + t4
a = t5

Quadruples Triples Indirect Triples


op arg1 arg2 result op arg1 arg2 op op arg1 arg2
minus c t1 0 minus c 35 (0) 0 minus c
* b t1 t2 1 * b (0) 36 (1) 1 * b (0)
minus c t3 2 minus c 37 (2) 2 minus c
* b t3 t4 3 * b (2) b (2)
38 (3) 3 *
+ t2 t4 t5 4 + (1) (3) 39 (4) 4 + (1) (3)
= t5 a 5 = a (4) 40 (5) 5 = a (4)

By Varun Arora
Type Expressions
Example: int[2][3]
array(2,array(3,integer))

 A basic type is a type expression


 A type name is a type expression
 A type expression can be formed by applying the array type
constructor to a number and a type expression.
 A record is a data structure with named field
 A type expression can be formed by using the type constructor g for
function types
 If s and t are type expressions, then their Cartesian product s*t is a
type expression
 Type expressions may contain variables whose values are type
expressions By Varun Arora
Type Equivalence
 They are the same basic type.
 They are formed by applying the same constructor to
structurally equivalent types.
 One is a type name that denotes the other.

By Varun Arora
Declarations

By Varun Arora
Storage Layout for Local Names
 Computing types and their widths

By Varun Arora
Storage Layout for Local Names
 Syntax-directed translation of array types

By Varun Arora
Sequences of Declarations

 Actions at the end:


By Varun Arora
Fields in Records and Classes

By Varun Arora
Translation of Expressions and
Statements
 We discussed how to find the types and offset of
variables
 We have therefore necessary preparations to discuss
about translation to intermediate code
 We also discuss the type checking

By Varun Arora
Three-address code for expressions

By Varun Arora
Incremental Translation

By Varun Arora
Addressing Array Elements
 Layouts for a two-dimensional array:

By Varun Arora
Semantic actions for array reference

By Varun Arora
Translation of Array References

Nonterminal L has three synthesized


attributes:
 L.addr
 L.array
 L.type

By Varun Arora
Conversions between primitive
types in Java

By Varun Arora
Introducing type conversions into
expression evaluation

By Varun Arora
Abstract syntax tree for the
function definition
fun length(x) =
if null(x) then 0 else length(tl(x)+1)

This is a polymorphic function


in ML language

By Varun Arora
Inferring a type for the function length

By Varun Arora
Algorithm for Unification

By Varun Arora
Unification algorithm
boolean unify (Node m, Node n) {
s = find(m); t = find(n);
if ( s = t ) return true;
else if ( nodes s and t represent the same basic type ) return true;
else if (s is an op-node with children s1 and s2 and
t is an op-node with children t1 and t2) {
union(s , t) ;
return unify(s1, t1) and unify(s2, t2);
}
else if s or t represents a variable {
union(s, t) ;
return true;
}
else return false;
}
By Varun Arora
Control Flow
boolean expressions are often used to:
 Alter the flow of control.
 Compute logical values.

By Varun Arora
Short-Circuit Code

By Varun Arora
Flow-of-Control Statements

By Varun Arora
Syntax-directed definition

By Varun Arora
Generating three-address code for booleans

By Varun Arora
translation of a simple if-statement

By Varun Arora
Backpatching
 Previous codes for Boolean expressions insert symbolic labels for
jumps
 It therefore needs a separate pass to set them to appropriate addresses
 We can use a technique named backpatching to avoid this
 We assume we save instructions into an array and labels will be indices
in the array
 For nonterminal B we use two attributes B.truelist and B.falselist
together with following functions:
 makelist(i): create a new list containing only I, an index into the array
of instructions
 Merge(p1,p2): concatenates the lists pointed by p1 and p2 and returns a
pointer to the concatenated list
 Backpatch(p,i): inserts i as the target label for each of the instruction
on the list pointed to by p

By Varun Arora
Backpatching for Boolean Expressions

By Varun Arora
Backpatching for Boolean Expressions
 Annotated parse tree for x < 100 || x > 200 && x ! = y

By Varun Arora
Flow-of-Control Statements

By Varun Arora
Translation of a switch-statement

By Varun Arora
Readings
 Chapter 6 of the book

By Varun Arora

You might also like