0% found this document useful (0 votes)
14 views11 pages

Unit 6 Final

Code optimization improves the performance and efficiency of compiled programs through various transformations, categorized as machine independent and machine dependent optimizations. Key techniques include common sub-expression elimination, copy propagation, dead-code elimination, constant folding, and loop optimizations, which aim to enhance execution speed and reduce code size without altering program functionality. Peephole optimization further refines target code by examining short sequences of instructions to eliminate redundancies and unreachable code.

Uploaded by

kuttia726
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)
14 views11 pages

Unit 6 Final

Code optimization improves the performance and efficiency of compiled programs through various transformations, categorized as machine independent and machine dependent optimizations. Key techniques include common sub-expression elimination, copy propagation, dead-code elimination, constant folding, and loop optimizations, which aim to enhance execution speed and reduce code size without altering program functionality. Peephole optimization further refines target code by examining short sequences of instructions to eliminate redundancies and unreachable code.

Uploaded by

kuttia726
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/ 11

UNIT VI - CODE OPTIMIZATION

INTRODUCTION

 The code produced by the straight forward compiling algorithms can often be made to run
faster or take less space, or both. This improvement is achieved by program transformations
that are traditionally called optimizations. Compilers that apply code-improving
transformations are called optimizing compilers.

 Optimizations are classified into two categories. They are


 Machine independent optimizations:
 Machine dependant optimizations:

Machine independent optimizations:

 Machine independent optimizations are program transformations that improve the target code
without taking into consideration any properties of the target machine.

Machine dependant optimizations:

 Machine dependant optimizations are based on register allocation and utilization of special
machine-instruction sequences.

The criteria for code improvement transformations:

 Simply stated, the best program transformations are those that yield the most benefit for the
least effort.

 The transformation must preserve the meaning of programs. That is, the optimization must
not change the output produced by a program for a given input, or cause an error such as
division by zero, that was not present in the original source program. At all times we take the
“safe” approach of missing an opportunity to apply a transformation rather than risk
changing what the program does.

 A transformation must, on the average, speed up programs by a measurable amount. We are


also interested in reducing the size of the compiled code although the size of the code has
less importance than it once had. Not every transformation succeeds in improving every
program, occasionally an “optimization” may slow down a program slightly.

 The transformation must be worth the effort. It does not make sense for a compiler writer to
expend the intellectual effort to implement a code improving transformation and to have the
compiler expend the additional time compiling source programs if this effort is not repaid
when the target programs are executed. “Peephole” transformations of this kind are simple
enough and beneficial enough to be included in any compiler.
Organization for an Optimizing Compiler:

 Flow analysis is a fundamental prerequisite for many important types of code


improvement.
 Generally control flow analysis precedes data flow analysis.
 Control flow analysis (CFA) represents flow of control usually in form of graphs, CFA
constructs such as
 control flow graph
 Call graph
 Data flow analysis (DFA) is the process of ascerting and collecting information prior to
program execution about the possible modification, preservation, and use of certain
entities (such as values or attributes of variables) in a computer program.

PRINCIPAL SOURCES OF OPTIMISATION

 A transformation of a program is called local if it can be performed by looking only at the


statements in a basic block; otherwise, it is called global.
 Many transformations can be performed at both the local and global levels. Local
transformations are usually performed first.

Function-Preserving Transformations

 There are a number of ways in which a compiler can improve a program without
changing the function it computes.
 The transformations

 Common sub expression elimination,


 Copy propagation,
 Dead-code elimination, and
 Constant folding

are common examples of such function-preserving transformations. The other


transformations come up primarily when global optimizations are performed.
 Frequently, a program will include several calculations of the same value, such as an
offset in an array. Some of the duplicate calculations cannot be avoided by the
programmer because they lie below the level of detail accessible within the source
language.

 Common Sub expressions elimination:

 An occurrence of an expression E is called a common sub-expression if E was previously


computed, and the values of variables in E have not changed since the previous
computation. We can avoid recomputing the expression if we can use the previously
computed value.
 For example
t1: = 4*i
t2: = a [t1]
t3: = 4*j
t4: = 4*i
t5 : = n
t6: = b [t4] +t5

The above code can be optimized using the common sub-expression elimination as
t1: = 4*i
t2: = a [t1]
t3: = 4*j
t5 : = n
t6: = b [t1] +t5

The common sub expression t4: =4*i is eliminated as its computation is already in t 1. And
value of i is not been changed from definition to use.

 Copy Propagation:

 Assignments of the form f : = g called copy statements, or copies for short. The idea
behind the copy-propagation transformation is to use g for f, whenever possible after the
copy statement f: = g. Copy propagation means use of one variable instead of another.
This may not appear to be an improvement, but as we shall see it gives us an opportunity
to eliminate x.
 For example:

x=Pi;
……
A=x*r*r;

The optimization using copy propagation can be done as follows:

A=Pi*r*r;

Here the variable x is eliminated

 Dead-Code Eliminations:

 A variable is live at a point in a program if its value can be used subsequently; otherwise,
it is dead at that point. A related idea is dead or useless code, statements that compute
values that never get used. While the programmer is unlikely to introduce any dead code
intentionally, it may appear as the result of previous transformations. An optimization can
be done by eliminating dead code.
Example:

i=0;
if(i=1)
{
a=b+5;
}

Here, ‘if’ statement is dead code because this condition will never get satisfied.

 Constant folding:

 We can eliminate both the test and printing from the object code. More generally,
deducing at compile time that the value of an expression is a constant and using the
constant instead is known as constant folding.

 One advantage of copy propagation is that it often turns the copy statement into dead
code.
 For example,
a=3.14157/2 can be replaced by
a=1.570 there by eliminating a division operation.

 Loop Optimizations:

 We now give a brief introduction to a very important place for optimizations, namely
loops, especially the inner loops where programs tend to spend the bulk of their time. The
running time of a program may be improved if we decrease the number of instructions in
an inner loop, even if we increase the amount of code outside that loop.
 Three techniques are important for loop optimization:

 code motion, which moves code outside a loop;


 Induction-variable elimination, which we apply to replace variables from inner loop.
 Reduction in strength, which replaces and expensive operation by a cheaper one, such as
a multiplication by an addition.

 Code Motion:

 An important modification that decreases the amount of code in a loop is code motion.
This transformation takes an expression that yields the same result independent of the
number of times a loop is executed ( a loop-invariant computation) and places the
expression before the loop. Note that the notion “before the loop” assumes the existence
of an entry for the loop. For example, evaluation of limit-2 is a loop-invariant
computation in the following while-statement:

while (i <= limit-2) /* statement does not change limit*/

Code motion will result in the equivalent of


t= limit-2;
while (i<=t) /* statement does not change limit or t */

 Induction Variables :

 Loops are usually processed inside out. For example consider the loop around B3.
 Note that the values of j and t4 remain in lock-step; every time the value of j decreases by
1, that of t4 decreases by 4 because 4*j is assigned to t 4. Such identifiers are called
induction variables.
 When there are two or more induction variables in a loop, it may be possible to get rid of
all but one, by the process of induction-variable elimination. For the inner loop around
B3 in Fig. we cannot get rid of either j or t4 completely; t4 is used in B3 and j in B4.
However, we can illustrate reduction in strength and illustrate a part of the process of
induction-variable elimination. Eventually j will be eliminated when the outer loop of B2
- B5 is considered.

Example:
As the relationship t4:=4*j surely holds after such an assignment to t4 in Fig. and t4 is not
changed elsewhere in the inner loop around B3, it follows that just after the statement
j:=j-1 the relationship t4:= 4*j-4 must hold. We may therefore replace the assignment t 4:=
4*j by t4:= t4-4. The only problem is that t4 does not have a value when we enter block B3
for the first time. Since we must maintain the relationship t 4=4*j on entry to the block B3,
we place an initializations of t4 at the end of the block where j itself is

before after

initialized, shown by the dashed addition to block B1 in second Fig.


 The replacement of a multiplication by a subtraction will speed up the object code if
multiplication takes more time than addition or subtraction, as is the case on many
machines.

 Reduction In Strength:

 Reduction in strength replaces expensive operations by equivalent cheaper ones on the


target machine. Certain machine instructions are considerably cheaper than others and
can often be used as special cases of more expensive operators.
 For example, x² is invariably cheaper to implement as x*x than as a call to an
exponentiation routine. Fixed-point multiplication or division by a power of two is
cheaper to implement as a shift. Floating-point division by a constant can be implemented
as multiplication by a constant, which may be cheaper.

OPTIMIZATION OF BASIC BLOCKS

There are two types of basic block optimizations. They are :

 Structure-Preserving Transformations
 Algebraic Transformations

Structure-Preserving Transformations:

The primary Structure-Preserving Transformation on basic blocks are:

 Common sub-expression elimination


 Dead code elimination
 Renaming of temporary variables
 Interchange of two independent adjacent statements.

 Common sub-expression elimination:

Common sub expressions need not be computed over and over again. Instead they can be
computed once and kept in store from where it’s referenced when encountered again – of course
providing the variable values in the expression still remain constant.

Example:

a: =b+c
b: =a-d
c: =b+c
d: =a-d

The 2nd and 4th statements compute the same expression: b+c and a-d

Basic block can be transformed to

a: = b+c
b: = a-d
c: = a
d: = b
 Dead code elimination:

It’s possible that a large amount of dead (useless) code may exist in the program. This
might be especially caused when introducing variables and procedures as part of construction or
error-correction of a program – once declared and defined, one forgets to remove them in case
they serve no purpose. Eliminating these will definitely optimize the code.

 Renaming of temporary variables:

 A statement t:=b+c where t is a temporary name can be changed to u:=b+c where u is


another temporary name, and change all uses of t to u.
 In this we can transform a basic block to its equivalent block called normal-form block.

 Interchange of two independent adjacent statements:

 Two statements

t1:=b+c

t2:=x+y

can be interchanged or reordered in its computation in the basic block when value of t 1
does not affect the value of t2.

Algebraic Transformations:

 Algebraic identities represent another important class of optimizations on basic blocks.


This includes simplifying expressions or replacing expensive operation by cheaper ones
i.e. reduction in strength.
 Another class of related optimizations is constant folding. Here we evaluate constant
expressions at compile time and replace the constant expressions by their values. Thus
the expression 2*3.14 would be replaced by 6.28.
 The relational operators <=, >=, <, >, + and = sometimes generate unexpected common
sub expressions.
 Associative laws may also be applied to expose common sub expressions. For example, if
the source code has the assignments

a :=b+c
e :=c+d+b

the following intermediate code may be generated:

a :=b+c
t :=c+d
e :=t+b

 Example:

x:=x+0 can be removed

x:=y**2 can be replaced by a cheaper statement x:=y*y


PEEPHOLE OPTIMIZATION

 A statement-by-statement code-generations strategy often produce target code that


contains redundant instructions and suboptimal constructs .The quality of such target
code can be improved by applying “optimizing” transformations to the target program.
 A simple but effective technique for improving the target code is peephole optimization,
a method for trying to improving the performance of the target program by examining a
short sequence of target instructions (called the peephole) and replacing these
instructions by a shorter or faster sequence, whenever possible.
 The peephole is a small, moving window on the target program. The code in the peephole
need not contiguous, although some implementations do require this.it is characteristic of
peephole optimization that each improvement may spawn opportunities for additional
improvements.
 We shall give the following examples of program transformations that are characteristic
of peephole optimizations:

 Redundant-instructions elimination
 Flow-of-control optimizations
 Algebraic simplifications
 Use of machine idioms
 Unreachable Code
Redundant Loads And Stores:

If we see the instructions sequence

(1) MOV R0,a

(2) MOV a,R0

we can delete instructions (2) because whenever (2) is executed. (1) will ensure that the value of
a is already in register R0.If (2) had a label we could not be sure that (1) was always executed
immediately before (2) and so we could not remove (2).

Unreachable Code:

 Another opportunity for peephole optimizations is the removal of unreachable instructions.


An unlabeled instruction immediately following an unconditional jump may be removed.
This operation can be repeated to eliminate a sequence of instructions. For example, for
debugging purposes, a large program may have within it certain segments that are executed
only if a variable debug is 1. In C, the source code might look like:

#define debug 0

….

If ( debug ) {

Print debugging information

 In the intermediate representations the if-statement may be translated as:

If debug =1 goto L2

goto L2

L1: print debugging information

L2: …………………………(a)

 One obvious peephole optimization is to eliminate jumps over jumps .Thus no matter what
the value of debug; (a) can be replaced by:

If debug ≠1 goto L2

Print debugging information

L2: ……………………………(b)

 As the argument of the statement of (b) evaluates to a constant true it can be replaced
by
If debug ≠0 goto L2

Print debugging information

L2: ……………………………(c)

 As the argument of the first statement of (c) evaluates to a constant true, it can be replaced by
goto L2. Then all the statement that print debugging aids are manifestly unreachable and
can be eliminated one at a time.

Flows-Of-Control Optimizations:

 The unnecessary jumps can be eliminated in either the intermediate code or the target code
by the following types of peephole optimizations. We can replace the jump sequence

goto L1

….

L1: gotoL2

by the sequence

goto L2

….

L1: goto L2

 If there are now no jumps to L1, then it may be possible to eliminate the statement L1:goto
L2 provided it is preceded by an unconditional jump .Similarly, the sequence

if a < b goto L1

….

L1: goto L2

can be replaced by

If a < b goto L2

….

L1: goto L2

 Finally, suppose there is only one jump to L1 and L1 is preceded by an unconditional goto.
Then the sequence

goto L1

……..
L1: if a < b goto L2

L3: …………………………………..(1)

 May be replaced by

If a < b goto L2

goto L3

…….

L3: ………………………………….(2)

 While the number of instructions in (1) and (2) is the same, we sometimes skip the
unconditional jump in (2), but never in (1).Thus (2) is superior to (1) in execution time

Algebraic Simplification:

 There is no end to the amount of algebraic simplification that can be attempted through
peephole optimization. Only a few algebraic identities occur frequently enough that it is
worth considering implementing them .For example, statements such as

x := x+0

Or

x := x * 1

 Are often produced by straightforward intermediate code-generation algorithms, and they can
be eliminated easily through peephole optimization.

Reduction in Strength:

 Reduction in strength replaces expensive operations by equivalent cheaper ones on the target
machine. Certain machine instructions are considerably cheaper than others and can often be
used as special cases of more expensive operators.
 For example, x² is invariably cheaper to implement as x*x than as a call to an exponentiation
routine. Fixed-point multiplication or division by a power of two is cheaper to implement as
a shift. Floating-point division by a constant can be implemented as multiplication by a
constant, which may be cheaper.

X2 → X*X

Use of Machine Idioms:

 The target machine may have hardware instructions to implement certain specific operations
efficiently. For example, some machines have auto-increment and auto-decrement addressing
modes. These add or subtract one from an operand before or after using its value.
 The use of these modes greatly improves the quality of code when pushing or popping a
stack, as in parameter passing. These modes can also be used in code for statements like i :
=i+1. i=i-1.

You might also like