You are on page 1of 11

UNIT- COMPILER

UNIT VI
CODE OPTIMIZATION
Introduction:
Code Optimization is required to produce an efficient target code. Elimination
of unnecessary instructions in object code or the replacement of one sequence
of instruction by a faster sequence of instructions that does the same thing is
usually called code improvement or code optimization.
In code optimization, we need to take care of the semantic equivalence of the
source program.
The improvement over the program efficiency must be achieved without
changing the algorithm of the program.
Code becomes inefficient because of two factors: such as, Programmer &
Compiler.
Code optimization can be performed in different phases of a compiler. Such as,
In Front end: Programmer can make use of efficient algorithm
In ICG phase: Apply Transformations on loops, procedure calls and address
calculation.
In Code generation: Use registers, Select appropriate instructions and apply
peephole optimization.
Types of optimization:
Optimization is of two types such as, Machine Dependent optimization and
Machine independent optimization.
The machine dependent optimization is based on characteristics of the target
machine (the instruction set used and addressing modes used for the instructions) to
generate efficient target code.
The machine independent optimization is based on the characteristics of the
programming languages for appropriate programming structure and usage of
efficient arithmetic properties in order to reduce execution time.

1|Page
UNIT- COMPILER

Machine dependant optimization can be achieved by Allocating sufficient number


of resources to improve the execution efficiency of the program and by using
immediate instruction wherever necessary.
Machine independent code optimization can be achieved by analysing the code and
using alternative equivalent source code that will produce minimum amount of
target code. Or using appropriate program structure in order to improve the
efficiency of the code. Eliminating unreachable code etc.
Semantic Preserving Transformations:
Semantic preserving transformation means the ways in which a compiler can
improve a program without changing the function it computes. Several such
techniques are,
o Common sub-expression elimination
o Copy Propagation
o Dead Code elimination
o Constant folding
o Strength Reduction
o Loop optimization
Common sub-expression elimination:
The common sub expression is an expression appearing repeatedly in the program
which is computed previously. Then if the operands of this sub expression do not
get changed at all then result of such sub expression is used instead of recomputing
it each time.

t1=4*I; t1=4*I;
Can be written as
t2=a[t1] t2=a[t1]
t3=4*j t3=4*j

2|Page
UNIT- COMPILER

Copy Propagation
In compiler theory, copy propagation is the process of replacing the occurrences of targets
of direct assignments with their values.
A direct assignment is an instruction of the form x = y, which simply assigns the value of
y to x.
Example 1:
y=x
z = 3 + y copy propagation would yield z=3+x
Example 2:
x=pi;
rea= x * r * r; can be written as, rea=pi*r*r
Dead Code Elimination
A variable is said to be live in a program if the value contained into it is used
subsequently. On the other hand, the variable is said to be dead at a point in a
program if the value contained into it is never been used.
The code containing such a variable is called as dead code and hence can be
eliminated.
Example 1:
i=j;

X=i+10
Optimization can be done by eliminating the assignment statement i=j.
Example 2:
i=0
if(i=1)
{
a=x+5;

3|Page
UNIT- COMPILER
}

Here, the statement in the if block is called as dead code which can be eliminated.
Because the condition never gets true and the statement will never get executed.
Constant Folding:
In the folding technique the computation of constant is done at compile time
instead of execution time.
E.g length=(22/7)*d;
Here, folding is implied by performing the computation 22/7 at compile time
instead of execution time.
Strength Reduction:
The strength of certain operators is higher than others. For instance strength of *
(multiplication) Is higher than + (addition).
In strength reduction technique the higher strength operators can be replaced by
lower strength operators.
Example:
for (i=1;i<=50;i++)
{
count=i*7;
}
This code can be replace by using strength reduction as follows
Temp=7;
for(i=1;i<=50;i++)
{
count=temp;
temp=temp+7;
}

4|Page
UNIT- COMPILER

Loop Optimization:
Code optimization can be done in loops in a program. Specially inner loop is a
place where program spends large amount of time.
Hence if number of instructions are less in inner loop then the running time of the
program will get decreased to a large extent.
Hence loop optimization is a technique in which code optimization performed in
inner loops. The loop optimization is carried out using following methods.
o Code motion( Loop invariant method)
o strength reduction
o Loop unrolling
o Loop fusion
Code motion:
Code motion is a technique which moves the code outside the loop. Hence the
name.
If there lies some expression in the loop whose result remains unchanged even after
executing the loop several times, then such an expression should be placed just
before the loop.(outside the loop)
E.g. while(i<=max-1)
{
sum = sum + a[i];
}
Here, the above loop can be optimized by using the statement max-1 outside the
loop.
Strength Reduction:

5|Page
UNIT- COMPILER
The strength of certain operators is higher than others. For instance strength of *
(multiplication) Is higher than + (addition).
In strength reduction technique the higher strength operators can be replaced by
lower strength operators.

Example:
for (i=1;i<=50;i++)
{
count=i*7;
}
This code can be replace by using strength reduction as follows
Temp=7;
for(i=1;i<=50;i++)
{
count=temp;
temp=temp+7;
}
Loop Unrolling
In this method the number of jumps and tests can be reduced by writing the code
multiple times.

Int i=1;
Int i=1; While(i<=100)
While(i<=10 Can be written as {
0)
A[i]=b[i];
{
i++;
6|Page
UNIT- COMPILER
Here, the same code present inside the loop is written twice so as to minimize number of
jumps to the while condition. In this case, the number of condition check is reduced by
50%.

Loop fusion or loop Jamming:


In loop fusion or loop jamming, several loops are merged if they have same number
of iterations and they use same indices. This eliminates test of one loop.
Example:

for(i=0;i<10;i++) for(i=0;i<10;i++)

for(j=0;j<10;j++) {

X[i,j]=0; for(j=0;j<10;j++)

Procedure Inline: X[i,j]=0;


When we define a procedure, normally the compiler makes a copy of that definition
in the memory and when a call to that procedure is made, the compiler jumps to
these copied instructions.
When the control returns from the procedure, the execution resumes from the next
line in the calling function.
Hence, if we make a call to that procedure multiple times, then the control is
transferred multiple times to refer the same copy of the definition
If the procedure contains less lines of code, then these frequent jumps will increase
the performance overhead of the program. (slows down the execution)
Hence the solution is make the procedure inline.

7|Page
UNIT- COMPILER
The inline procedure is a function type of procedure whose code is copied in place
of the procedure call. The inline specifies that the compiler should insert the
complete body at the place of function call.
In this way we can minimize frequent jumps but it may increase memory
requirements of the program.(Hence, only small functions are preferred to make
inline).

Example: inline function in C++ programming.

#include<iostream.h>

inline int sum(int x, int y)

return(x+y);

void main()

Instruction scheduling:

The order of three-address code affects the cost of the object code being generated. i.e.
by changing the order in which computations are done, we can obtain the object code
with minimum cost.
Code optimization can be achievedMov by scheduling the instructions in proper order. This
R0,a
technique is called as instruction scheduling.
Mov
R0,c consider the expression
For example: ADD(a+b)+(e+(c-d))
R0,b
Sub
R0,d Mov R1,c
t1=a+b
Movt2=c-d Sub R1,d
8|Page
R1,e
UNIT- COMPILER

t2=c- d

t3=e+t2

Scheduled

Interprocedural Optimization (IPO):

In this technique, collection of optimization techniques are used to improve the


performance of the program that contain many frequently used functions or blocks.
IPO eliminates duplicate calculations, inefficient use of memory and simplifies
loops.
IPO may re-order the routines for better memory utilization. The compiler tests for
branches that are never taken and removes the code in that branch.
IPO also checks if constants are used properly or not.
Example:
t6=4*i i=m-1 t6=4*i

val=a[t6] J=n val=a[t6]


B
t7=4* i 1 t1=4*n t7=4* i

t8=4*j K=a[t1] t8=4*j

t9=a[t8] T2=4*I t9=a[t8]


t2=t2+4
a[t7]=t9 B T4=4*j a[t7]=t9
2 T3=a[t2]
t10=4*j t4=t4-4 t10=4*j
If t3<k goto B2
B a[t10]=val B t5=a[t4] a[t10]=val
B
9|Page
5 Goto B2 4
3 If
if t2>=t4
t5>k goto
goto
B3B6 Goto B2 6
UNIT- COMPILER

In block B5 there are common sub-expressions 4*i and 4*j. we can remove these
common code. The code will be.

t6=4*i

val=a[t6]
This is called local transformation.
t8=4*j

t9=a[t8]

We cana[t6]=t9
also apply global transformation. Because, 4 * i is already computed as t2
in B1 so we can replace t6 by t2. Similarly t8 can be replaced by t4 as in B1 it has
a[t8]=val
been calculated. Hence, t6 and t8 can be eliminated. Code will be,
Goto B2

Val=a[t2]

t9=a[t4]

a[t2]=t9
But val contains a[t2] which is already stored in t3. so we can replace value by t3.
10 | P a g e
UNIT- COMPILER
Similarly, a[t4] is already computed in block B3 and its value is stored in t5.
Hence, t9 can be eliminated. The optimized block will be,

a[t2]=t5

a[t4]=t3

Similarly, Block B6 can be optimized as,

t14=a[t1]

a[t2]=t14

11 | P a g e