You are on page 1of 13

Three address code is a type of intermediate code which is easy to generate and can be easily

converted to machine code.It makes use of at most three addresses and one operator to represent
an expression and the value computed at each instruction is stored in temporary variable
generated by compiler. The compiler decides the order of operation given by three address code.

General representation –
a = b op c
Where a, b or c represents operands like names, constants or compiler generated temporaries and
op represents the operator

Example-1: Convert the expression a * – (b + c) into three address code.

Example-2: Write three address code for following code


for(i = 1; i<=10; i++)
{
a[i] = x * 5;
}

Implementation of Three Address Code –


There are 3 representations of three address code namely
1. Quadruple
2. Triples
3. Indirect Triples
1. Quadruple –
It is structure with consist of 4 fields namely op, arg1, arg2 and result. op denotes the operator
and arg1 and arg2 denotes the two operands and result is used to store the result of the
expression.
Advantage –
 Easy to rearrange code for global optimization.
 One can quickly access value of temporary variables using symbol table.
Disadvantage –
 Contain lot of temporaries.
 Temporary variable creation increases time and space complexity.
Example – Consider expression a = b * – c + b * – c.
The three address code is:

t1 = uminus c
t2 = b * t1
t3 = uminus c
t4 = b * t3
t5 = t2 + t4
a = t5

2. Triples –
This representation doesn’t make use of extra temporary variable to represent a single operation
instead when a reference to another triple’s value is needed, a pointer to that triple is used. So, it
consist of only three fields namely op, arg1 and arg2.
Disadvantage –
 Temporaries are implicit and difficult to rearrange code.
 It is difficult to optimize because optimization involves moving intermediate code. When
a triple is moved, any other triple referring to it must be updated also. With help of
pointer one can directly access symbol table entry.
Example – Consider expression a = b * – c + b * – c
3. Indirect Triples –
This representation makes use of pointer to the listing of all references to computations which is
made separately and stored. Its similar in utility as compared to quadruple representation but
requires less space than it. Temporaries are implicit and easier to rearrange code.
Example – Consider expression a = b * – c + b * – c

Question – Write quadruple, triples and indirect triples for following expression : (x + y) * (y +
z) + (x + y + z)
Explanation – The three address code is:
t1 = x + y
t2 = y + z
t3 = t1 * t2
t4 = t1 + z
t5 = t3 + t4
 

Peephole optimization is a type of Code Optimization performed on a small part of the code. It is
performed on the very small set of instructions in a segment of code.
The small set of instructions or small part of code on which peephole optimization is performed
is known as peephole or window.

It basically works on the theory of replacement in which a part of code is replaced by shorter and
faster code without change in output.
Peephole is the machine dependent optimization.

irected Acyclic Graph-


 
Directed Acyclic Graph (DAG) is a special kind of Abstract Syntax Tree.
 
 Each node of it contains a unique value.
 It does not contain any cycles in it, hence called Acyclic.
 
Optimization Of Basic Blocks-
 
DAG is a very useful data structure for implementing transformations on Basic Blocks.
 
 A DAG is constructed for optimizing the basic block.
 A DAG is usually constructed using Three Address Code.
 Transformations such as dead code elimination and common sub expression elimination
are then applied.
 
Properties-
 
 Reachability relation forms a partial order in DAGs.
 Both transitive closure & transitive reduction are uniquely defined for DAGs.
 Topological Orderings are defined for DAGs.
 
Applications-
 
DAGs are used for the following purposes-
 To determine the expressions which have been computed more than once (called
common sub-expressions).
 To determine the names whose computation has been done outside the block but used
inside the block.
 To determine the statements of the block whose computed value can be made available
outside the block.
 To simplify the list of Quadruples by not executing the assignment instructions x:=y
unless they are necessary and eliminating the common sub-expressions.
 
Construction of DAGs-
 
Following rules are used for the construction of DAGs-
 
Rule-01:
 
In a DAG,
 Interior nodes always represent the operators.
 Exterior nodes (leaf nodes) always represent the names, identifiers or constants.
 
Rule-02:
 
While constructing a DAG,
 A check is made to find if there exists any node with the same value.
 A new node is created only when there does not exist any node with the same value.
 This action helps in detecting the common sub-expressions and avoiding the re-
computation of the same.
 
Rule-03:
 
The assignment instructions of the form x:=y are not performed unless they are necessary.
 
Also Read- Code Optimization
 
PRACTICE PROBLEMS BASED ON DIRECTED
ACYCLIC GRAPHS-
 
Problem-01:
 
Consider the following expression and construct a DAG for it-
(a+b)x(a+b+c)
 
Solution-
 
Three Address Code for the given expression is-
 
T1 = a + b
T2 = T1 + c
T3 = T1 x T2
 
Now, Directed Acyclic Graph is-
 
 
NOTE
 
From the constructed DAG, we observe-
 The common sub-expression (a+b) has been expressed into a single node in the
DAG.
 The computation is carried out only once and stored in the identifier T1 and reused
later.
 
This illustrates how the construction scheme of a DAG identifies the common sub-
expression and helps in eliminating its re-computation later.
 
Problem-02:
 
Consider the following expression and construct a DAG for it-
(((a+a)+(a+a))+((a+a)+(a+a)))
 
Solution-
 
Directed Acyclic Graph for the given expression is-
 

 
Problem-03:
 
Consider the following block and construct a DAG for it-
 
(1) a = b x c
(2) d = b
(3) e = d x c
(4) b = e
(5) f = b + c
(6) g = f + d
 
Solution-
 
Directed Acyclic Graph for the given block is-
 

 
Problem-04:
 
Optimize the block in the Problem-03.
 
Solution-
 
Step-01:
 
Firstly, construct a DAG for the given block (already done above).
 
Step-02:
 
Now, the optimized block can be generated by traversing the DAG.
 The common sub-expression e = d x c which is actually b x c (since d = b) is eliminated.
 The dead code b = e is eliminated.
 
The optimized block is-
 
(1) a = b x c
(2) d = b
(3) f = a + c
(4) g = f + d
 
Problem-05:
 
Consider the following basic block-
 
B10:
S1 = 4 x I
S2 = addr(A) – 4
S3 = S2[S1]
S4 = 4 x I
S5 = addr(B) – 4
S6 = S5[S4]
S7 = S3 x S6
S8 = PROD + S7
PROD = S8
S9 = I + 1
I = S9
If I <= 20 goto L10
 
1. Draw a directed acyclic graph and identify local common sub-expressions.
2. After eliminating the common sub-expressions, re-write the basic block.
 
Solution-
 
Directed Acyclic Graph for the given basic block is-
 
 
In this code fragment,
 4 x I is a common sub-expression. Hence, we can eliminate because S1 = S4.
 We can optimize S8 = PROD + S7 and PROD = S8 as PROD = PROD + S7.
 We can optimize S9 = I + 1 and I = S9 as I = I + 1.
 
After eliminating S4, S8 and S9, we get the following basic block-
 
B10:
S1 = 4 x I
S2 = addr(A) – 4
S3 = S2[S1]
S5 = addr(B) – 4
S6 = S5[S1]
S7 = S3 x S6
PROD = PROD + S7
I=I+1

Loop Optimization in Compiler Design


 Difficulty Level : Basic
 Last Updated : 21 Nov, 2019
Loop Optimization is the process of increasing execution speed and reducing the overheads
associated with loops. It plays an important role in improving cache performance and making
effective use of parallel processing capabilities. Most execution time of a scientific program is spent
on loops.
Loop Optimization is a machine independent optimization.

Decreasing the number of instructions in an inner loop improves the running time of a program even
if the amount of code outside that loop is increased.
Loop Optimization Techniques:

1. Frequency Reduction (Code Motion):


In frequency reduction, the amount of code in loop is decreased. A statement or expression,
which can be moved outside the loop body without affecting the semantics of the program, is
moved outside the loop.
Example:
Initial code:

while(i<100)
{
a = Sin(x)/Cos(x) + i;
i++;
}

Optimized code:

t = Sin(x)/Cos(x);
while(i<100)
{
a = t + i;
i++;
}
2. Loop Unrolling:
Loop unrolling is a loop transformation technique that helps to optimize the execution time of a
program. We basically remove or reduce iterations. Loop unrolling increases the program’s speed
by eliminating loop control instruction and loop test instructions.
Example:
Initial code:

for (int i=0; i<5; i++)


printf("Pankaj\n");

Optimized code:

printf("Pankaj\n");
printf("Pankaj\n");
printf("Pankaj\n");
printf("Pankaj\n");
printf("Pankaj\n");
3. Loop Jamming:
Loop jamming is the combining the two or more loops in a single loop. It reduces the time taken
to compile the many number of loops.
Example:
Initial Code:
for(int i=0; i<5; i++)
a = i + 5;
for(int i=0; i<5; i++)
b = i + 10;

Optimized code:
for(int i=0; i<5; i++)
{
a = i + 5;
b = i + 10;
}
Case Statements
Switch and case statement is available in a variety of languages. The syntax of case statement is
as follows:

1.     switch E  
2.                 begin   
3.                              case V1: S1  
4.                              case V2: S2  
5.                              .  
6.                              .  
7.                              .  
8. case Vn-1: Sn-1  
9. default: Sn  
10.                 end  
The translation scheme for this shown below:
Code to evaluate E into T

1. goto TEST  
2.                 L1:         code for S1  
3.                               goto NEXT  
4.                 L2:         code for S2  
5.                               goto NEXT  
6.                               .  
7.                               .  
8.                               .  
9.                 Ln-1:      code for Sn-1  
10.                               goto NEXT  
11.                 Ln:         code for Sn  
12. goto NEXT  
13.                 TEST:      if T = V1 goto L1       
14.                                if T = V2goto L2  
15.                                .  
16.                                .  
17.                                .  
18.                                if T = Vn-1 goto Ln-1  
19.                                goto   
20. NEXT:  
o When switch keyword is seen then a new temporary T and two new labels test and next
are generated.
o When the case keyword occurs then for each case keyword, a new label Li is created and
entered into the symbol table. The value of Vi of each case constant and a pointer to this
symbol-table entry are placed on a stack.

Next Topic eBackground: Parser uses a CFG(Context-free-Grammar) to

validate the input string and produce output for the next phase of the compiler.
Output could be either a parse tree or an abstract syntax tree. Now to interleave
semantic analysis with the syntax analysis phase of the compiler, we use
Syntax Directed Translation. 
Definition 
Syntax Directed Translation has augmented rules to the grammar that facilitate
semantic analysis. SDT involves passing information bottom-up and/or top-
down the parse tree in form of attributes attached to the nodes. Syntax-directed
translation rules use 1) lexical values of nodes, 2) constants & 3) attributes
associated with the non-terminals in their definitions. 

You might also like