CSE-303 Chapter-06 Final
CSE-303 Chapter-06 Final
Intermediate-Code Generation
+ +
+ * + *
_ d
a d
* *
a _ b c a _
b c b c
Syntax Tree DAG
Example 6.1 (Cont…)
+
• The leaf for ‘a’ has two parents, because ‘a’
appears twice in the expression + *
• More interestingly, the two occurrences of
the common subexpression ‘b−c’ are
represented by one node, the node labeled d
‘−’ *
a _
b c
DAG
Example 6.1 (Cont…)
+
• That node has two parents,
representing its two uses in the + *
subexpressions ‘a∗(b−c)’ and
‘(b−c)∗d’ d
*
• Even though ‘b’ and ‘c’ appear twice in
the complete expression, their nodes a _
each have one parent, since both uses
are in the common subexpression ‘b−c’
b c
DAG
Example 6.1(Cont…)
The SDD of figure can construct either syntax trees or DAG’s
Example 6.2
The sequence of steps shown in figure constructs the DAG
a + a*(b−c) + (b−c)*d
1) p1 = Leaf p1
(id, entry-a)
+ 2) p2 = Leaf (id, entry-a) = p1
3) p3 = Leaf (id,
p1 entry-b)
4) p4 = Leaf (id, entry-c)
+ * 5) p5 = Node (‘−’, p3 , p4)
6) p6 = Node (‘*’, p1 , p5)
d 7) p7 = Node (‘+’, p1 , p6)
• Leaves have one additional field, which holds the lexical value (either a
symbol-table pointer or a constant, in this case)
• Interior nodes have two additional fields indicating the left and right children
Syntax Tree or DAG Node for an Interior Node with two children
The Value-Number Method for Constructing DAG’s (Cont…)
• In the array, we refer to nodes by giving the integer index of the record for
that node within the array
• This integer historically has been called the value number for the node or
for the expression represented by the node
The Value-Number Method for Constructing DAG’s (Cont…)
DAG for i = i + 10
1 id to entry for i
=
2 num 10
3 + 1 2
+
4 = 1 3
i 10 5 …
t2 = a * t1
+ *
t3 = a + t2
* t4 = t1 * d
a _
d
t5 = t3 + t4
b c
param a
t1 = call g, 1
param t1
t2 = call f, 2
n = t2
Addresses and Instructions (Cont…)
Indexed copy instructions of the form x = y[i] and x[i] = y
The instruction x = y[i] sets x to the value in the location i memory units
beyond location y
The instruction x[i] = y sets the contents of the location i units beyond x to
the value of y
Addresses and Instructions (Cont…)
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
+ y z x
Quadruples (Cont…)
The following are some exceptions to this rule:
• Instructions with unary operators like x = minus y or x = y do not use arg2
minus y x
Quadruples (Cont…)
= y x
Quadruples (Cont…)
The following are some exceptions to this rule:
• Operators like param use neither arg2 nor result. For example, param x
param x
Quadruples (Cont…)
goto L
Quadruples (Cont…)
The following are some exceptions to this rule:
goto x L
Quadruples (Cont…)
The following are some exceptions to this rule:
• Conditional and unconditional jumps put the target label in result
• For example, if x < y goto L
< x y t1
goto t1 L
Example 6.6
Three-Address Code and Quadruples for the expression, a = b * -c + b * -c
op arg1 arg2
Example 6.7
Syntax Tree and Triples for the expression, a = b * -c + b * -c
op arg1 arg2
=
0 minus c
a + 1 * b (0)
2 minus c
* 3 * b (2)
*
4 + (1) (3)
b minus b 5 = a (4)
minus
…
c c
(a) Syntax Tree (b) Triples
A Syntax Tree and its Corresponding Triples
Triples (Cont…)
• In the triple representation in (b), the copy statement a = t5 is encoded in the
triple representation by placing a in the arg1 field and (4) in the arg2 field
op arg1 arg2
5 = a (4)
Triples (Cont…)
• A ternary operation like x[i] = y requires two entries in the triple structure
• For example, we can put x and i in one triple and y in the next
op arg1 arg2
0 * i 4
1 + x (0)
2 = (1) y
Triples (Cont…)
• Similarly, x = y[i] can implemented by treating it as if it were the two
instructions t = y[i] and x = t, where t is a compiler-generated temporary
• Note that the temporary t does not actually appear in a triple, since
temporary values are referred to by their position in the triple structure
op arg1 arg2
0 * i 4
1 + y (0)
2 = x (1)
Benefit of Quadruples over Triples
• A benefit of quadruples over triples can be seen in an optimizing compiler,
where instructions are often moved around
• With quadruples, if we move an instruction that computes a temporary t, then
the instructions that use t require no change
• With triples, the result of an operation is referred to by its position, so moving
an instruction may require us to change all references to that result. This
problem does not occur with indirect triples, which we consider next.
Benefit of Quadruples over Triples (Cont…)
Before Optimizing,
t1 = itof (60)
t2 = a * t 1
t3 = t2 + 40
op arg1 arg2 result op arg1 arg2
0 itof 60 t1 0 itof 60
1 * a t1 t2 1 * a (0)
2 + t2 40 t3 2 + (1) 40
Quadruples Triples
Benefit of Quadruples over Triples (Cont…)
After Optimizing,
t2 = a * 60.0
t3 = t2 + 40
Quadruples Triples
Indirect Triples
… 2 + (1) 40 3 …
• In C, the type int [2][3] can be read as, “array of 2 arrays of 3 integers”
• The corresponding type expression array(2,array(3,integer)) is represented
by the tree in figure
• When type expressions are represented by graphs, two types are structurally
equivalent if and only if one of the following conditions is true:
• 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
• If type names are treated as standing for themselves, then the first two
conditions in the above definition lead to name equivalence of type
expressions
Name Equivalence
• Name Equivalence: two types are equal if and only if they have the same
name
• Thus, for example in the code (using C syntax)
struct ST{ struct T{
int a; int a;
float b; float b;
}X,Y; }M,N;
Name Equivalence (Cont…)
struct ST{ struct T{
int a; int a;
float b; float b;
}X,Y; }M,N;
• Structural Equivalence: two types are equal if and only if, they have the
same structure which can be interpreted in different ways
• A strict interpretation would be that the names and types of each
component of the two types must be the same and must be listed in the
same order in the type definition
• A less stringent requirement would be that the component types must be
the same and in the same order in the two types, but the names of the
components could be different
Structural Equivalence (Cont…)
struct ST{ struct T{
int a; int a;
float b; float b;
}X,Y; }M,N;
• Again looking at the example above using structural equivalence the two
types ST and T would be considered equivalent which means that a translator
would accept statements such as X = M
• Note that C doesn't support structural equivalence for struct and classes and
will give error for above assignment
Declarations
• For the grammar given above, construct parse tree for the following input
strings:
• int a; float b;
• int [3] [4] a;
• record { int a; float b; int [3] [4] a; }
Practice Problem-3
• Modify the grammar given above so that it can construct parse tree for
declarations with list of names and then construct parse tree for the following
input
• record { int a, b; int [3] [4] a; }
[Hint: Use Example 5.10]
Storage Layout for Local Names
• From the type of a name, we can determine the amount of storage that will be
needed for the name at run time
• At compile time, we can use these amounts to assign each name a relative
address
• The type and relative address are saved in the symbol-table entry for the
name
• Data of varying length, such as strings or data whose size cannot be
determined until run time, such as dynamic arrays is handled by reserving a
known fixed amount of storage for a pointer to the data
Storage Layout for Local Names (Cont…)
• Suppose storage comes in blocks of contiguous bytes where byte is the
smallest unit of addressable memory
• Typically a byte is eight bits, and some number of bytes form a machine word
• Multibyte objects are stored in consecutive bytes and given the address of the
first byte
• The width of a type is the number of storage units needed for objects of that
type
Storage Layout for Local Names (Cont…)
• The syntax directed translation scheme (SDT) in figure computes types and
their widths for basic and array types
1) T→ B { t = B.type; w = B.width; }
C { T.type = C.type; T.width = C.width; }
2) B→ int { B.type = integer; B.width = 4; }
3) B→ float { B.type = float; B.width = 8; }
4) C→ ϵ { C.type = t; C.width = w; }
5) C→ [num] C1 { C.type = array(num.value, C1.type);
C.width = num.value X C1.width; }
Computing types and their width
Example 6.9 (Cont…) T
int
[ 2 ] C
[ 3 ] C
[ 3 ] C
ϵ
Example 6.9 (Cont…) T
t= integer
SDT of Array Types for int [2] [3]
w= 4 C
B type= integer
width= 4
int [ 2 ]
C
[ 3 ] C
ϵ
Example 6.9 (Cont…) T
t= integer
SDT of Array Types for int [2] [3]
w= 4 C
B type= integer
width= 4
int [ 2 ]
C
[ 3 ] C type= integer
width= 4
ϵ
Example 6.9 (Cont…) T
t= integer
SDT of Array Types for int [2] [3]
w= 4 C
B type= integer
width= 4
int [ 2 ] type= array(3, integer)
C width= 12
[ 3 ] C type= integer
width= 4
ϵ
T
Example 6.9 (Cont…)
t= integer
SDT of Array Types for int [2] [3]
w= 4
B type= integer
width= 4
int type= array(2, array(3, integer))
C width= 24
[ 2 ] type= array(3, integer)
C width= 12
[ 3 ] C type= integer
width= 4
ϵ
T
Example 6.9 (Cont…) type= array(2, array(3, integer))
t= integer width= 24
SDT of Array Types for int [2] [3]
w= 4
B type= integer
width= 4
int type= array(2, array(3, integer))
C width= 24
[ 2 ] type= array(3, integer)
C width= 12
[ 3 ] C type= integer
width= 4
ϵ
Syntax-directed translation of array types
Comparison of Example 6.9 and Example 5.13
Sequences of Declarations
Task-2: Draw
Annotated parse
tree for a= b + -c
and output the
three address
code.
Translation of Array References - SDT