0% found this document useful (0 votes)
34 views33 pages

Compiler - Three Addr Codes

The document discusses intermediate code in compilers, focusing on the role of intermediate representations, static type checking, and code generation. It covers the construction of Directed Acyclic Graphs (DAGs) for expressions, three address code formats, and data structures like quadruples and triples. Additionally, it addresses type expressions, array references, and control flow statements, including techniques like backpatching for managing jumps in code.
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)
34 views33 pages

Compiler - Three Addr Codes

The document discusses intermediate code in compilers, focusing on the role of intermediate representations, static type checking, and code generation. It covers the construction of Directed Acyclic Graphs (DAGs) for expressions, three address code formats, and data structures like quadruples and triples. Additionally, it addresses type expressions, array references, and control flow statements, including techniques like backpatching for managing jumps in code.
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
You are on page 1/ 33

THREE ADDRESS CODES

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 Code


Parser
Checker Generator Generator

Front end 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 -

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)
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
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
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
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


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
Example Three address code
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)
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
Declarations
Storage Layout for Local Names
• Computing types and their widths
Three-address code for expressions
Incremental Translation
Addressing Array Elements
• Layouts for a two-dimensional array:
Semantic actions for array reference
Translation of Array References

Nonterminal L has three synthesized


attributes:
•L.addr
•L.array
•L.type
Conversions between primitive types
in Java
Introducing type conversions into
expression evaluation
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
Three Address Codes for Control Flow Stmts

Boolean expressions are often used to:


•Alter the flow of control.
•Compute logical values.
Short-Circuit Code


Flow-of-Control Statements
Syntax-directed definition
Generating three-address code for booleans
translation of a simple if-statement


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
Backpatching for Boolean Expressions


Backpatching for Boolean Expressions

• Annotated parse tree for x < 100 || x > 200 && x ! = y


Flow-of-Control Statements
Translation of a switch-statement
Thank You

You might also like