0% found this document useful (0 votes)
10 views45 pages

CD Unit-5

Code optimization is a technique aimed at improving program efficiency by reducing resource consumption and increasing speed without altering the program's meaning. It involves transforming high-level constructs into efficient low-level code through various methods such as machine-independent and machine-dependent optimizations, including dead code elimination and loop optimization. Key strategies include compile-time evaluation, variable propagation, and the use of directed acyclic graphs (DAGs) for managing basic block transformations.

Uploaded by

indiaurdutimes1
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)
10 views45 pages

CD Unit-5

Code optimization is a technique aimed at improving program efficiency by reducing resource consumption and increasing speed without altering the program's meaning. It involves transforming high-level constructs into efficient low-level code through various methods such as machine-independent and machine-dependent optimizations, including dead code elimination and loop optimization. Key strategies include compile-time evaluation, variable propagation, and the use of directed acyclic graphs (DAGs) for managing basic block transformations.

Uploaded by

indiaurdutimes1
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/ 45

Code Optimization

Code Optimization
• Optimization is a program transformation technique, which tries to improve the
code by making it consume less resources (i.e. CPU, Memory) and deliver high
speed.
• In optimization, high-level general programming constructs are replaced by very
efficient low-level programming codes. A code optimizing process must follow the
three rules given below:
• The output code must not, in any way, change the meaning of the program.
• Optimization should increase the speed of the program and if possible, the program
should demand less number of resources.
• Optimization should itself be fast and should not delay the overall compiling
process.
• Efforts for an optimized code can be made at various levels of compiling the
process.
• At the beginning, users can change/rearrange the code or use better algorithms to
write the code.
• After generating intermediate code, the compiler can modify the intermediate code
by address calculations and improving loops.
• While producing the target machine code, the compiler can make use of memory
hierarchy and CPU registers.
• Optimization can be categorized broadly into two types : machine independent and
machine dependent.
Machine-Independent Optimization

• Machine independent optimization attempts to improve the


intermediate code to get a better target code. The part of the
code which is transformed here does not involve any
absolute memory location or any CPU registers.
• The process of intermediate code generation introduces
much inefficiency like: using variable instead of constants,
extra copies of variable, repeated evaluation of expression.
Through the code optimization, you can remove such
efficiencies and improves code.
• It can change the structure of program sometimes of beyond
recognition like: unrolls loops, inline functions, eliminates
some variables that are programmer defined.
(1) Compile Time Evaluation:

• (a) z = 5*(45.0/5.0)*r
Perform 5*(45.0/5.0)*r at compile time.
• (b) x = 5.7
y = x/3.6
Evaluate x/3.6 as 5.7/3.6 at compile time.
(2) Variable Propagation:

• Before Optimization the code is:


• c=a*b
• x=a
• till
• d=x*b+4
• After Optimization the code is:
• c=a*b
• x=a
• till
• d=a*b+4
• Here, after variable propagation a*b and x*b identified as
common sub expression.
(3) Dead code elimination:

• Before elimination the code is:


• c=a*b
• x=b
• till
• d=a*b+4
• After elimination the code is:
• c=a*b
• till
• d=a*b+4
• Here, x= b is a dead state because it will never subsequently
used in the program. So, we can eliminate this state.
(4) Code Motion:

• It reduces the evaluation frequency of expression.


• It brings loop invariant statements out of the loop.
• do
• {
• item = 10;
• valuevalue = value + item;
• } while(value<100);


• //This code can be further optimized as

• item = 10;
• do
• {
• valuevalue = value + item;
• } while(value<100);
(5) Induction Variable and Strength
Reduction:
• Strength reduction is used to replace the high
strength operator by the low strength.
• An induction variable is used in loop for the
following kind of assignment like i = i + constant.
• Before reduction the code is:
• i = 1;
• while(i<10)
• {
• y = i * 4;
• }
• After Reduction the code is:
• i=1
• t=4
• {
• while( t<40)
• y = t;
• t = t + 4;
• }
Loop Optimization

• Loop optimization is most valuable machine-independent


optimization because program's inner loop takes bulk to time
of a programmer.
• If we decrease the number of instructions in an inner loop
then the running time of a program may be improved even if
we increase the amount of code outside that loop.
• For loop optimization the following three techniques are
important:
• Code motion
• Induction-variable elimination
• Strength reduction

1.Code Motion:

• Code motion is used to decrease the amount of code in loop.


This transformation takes a statement or expression which
can be moved outside the loop body without affecting the
semantics of the program.
• For example
• In the while statement, the limit-2 equation is a loop
invariant equation.
• while (i<=limit-2) /*statement does not change limit*/
• After code motion the result is as follows:
• a= limit-2;
• while(i<=a) /*statement does not change limit or a*/
2.Induction-Variable Elimination

• Induction variable elimination is used to


replace variable from inner loop.
• It can reduce the number of additions in a loop.
It improves both code space and run time
performance.
3.Reduction in Strength

• Strength reduction is used to replace the expensive operation by the


cheaper once on the target machine.
• Addition of a constant is cheaper than a multiplication. So we can
replace multiplication with an addition within the loop.
• Multiplication is cheaper than exponentiation. So we can replace
exponentiation with multiplication within the loop.
• Example:
• while (i<10)
• {
• j= 3 * i+1;
• a[j]=a[j]-2;
• i=i+2;
• }
• After strength
• s= 3*i+1;
• while (i<10)
• {
• j=s;
• a[j]= a[j]-2;
• i=i+2;
• s=s+6;
• }
• In the above code, it is cheaper to compute s=s+6 than
j=3 *i
Principle Source of Optimization
Common Sub Expression Elimination
Copy Propogation
Dead Code Elimination
Peephole Optimization
• This optimization technique works locally on
the source code to transform it into an
optimized code. By locally, we mean a small
portion of the code block at hand.
• These methods can be applied on intermediate
codes as well as on target codes.
• A bunch of statements is analyzed and are
checked for the following possible
optimization:
Redundant Instruction Elimination
Unreachable code
• Unreachable code is a part of the program code that is never accessed
because of programming constructs.
• • Programmers may have accidently written a piece of code that can never
be reached. Example:
• void add_ten(int x)
• {
• return x + 10;
• printf(“value of x is %d”, x);
• }
• In this code segment, the printf statement will never be executed as the
program control returns back before it can execute, hence printf can be
removed
• • In this code segment, the printf statement will never be executed as the
program control returns back before it can execute, hence printf can be
removed.
Flow of control optimization
• There are instances in a code where the program control jumps back
and forth without performing any significant task.
• These jumps can be removed. Consider the following chunk of
code: ...
MOV R1,
R2 GOTO L1 ...
L1: GOTO L2
L2: INC R1
• In this code, label L1 can be removed as it passes the control to L2.
So instead of jumping to L1 and then to L2, the control can directly
reach L2, as shown below: ...
MOV R1,
R2 GOTO L2
... L2: INC R1
• 4. Algebraic expression simplification
• • There are occasions where algebraic expressions can be
made simple. For example, the expression a = a + 0 can be
replaced by a itself and the expression a = a + 1 can simply
be replaced by INC a.
• 5. Strength reduction
• • There are operations that consume more time and space.
Their ‘strength’ can be reduced by replacing them with other
operations that consume less time and space, but produce the
same result. • For example, x * 2 can be replaced by x << 1,
which involves only one left shift. Though the output of a *
a and a2 is same, a2 is much more efficient to implement.
Optimization of Basic Blocks:

• Optimization process can be applied on a basic


block. While optimization, we don't need to
change the set of expressions computed by the
block.
• There are two type of basic block optimization.
These are as follows:
• Structure-Preserving Transformations
• Algebraic Transformations
Structure preserving transformations:

• The primary Structure-Preserving


Transformation on basic blocks is as follows:
• Common sub-expression elimination
• Dead code elimination
• Renaming of temporary variables
• Interchange of two independent adjacent
statements
(a) Common sub-expression
elimination:
• In the common sub-expression, you don't need to be computed it
over and over again. Instead of this you can compute it once and
kept in store from where it's referenced when encountered again.
• a:=b+c
• b:=a-d
• c:=b+c
• d:=a-d
• In the above expression, the second and forth expression computed
the same expression. So the block can be transformed as follows:
• a:=b+c
• b:=a-d
• c:=b+c
• d:=b
Dead Code Elimination
• It is possible that a program contains a large
amount of dead code.
• This can be caused when once declared and
defined once and forget to remove them in this
case they serve no purpose.
• Suppose the statement x:= y + z appears in a block
and x is dead symbol that means it will never
subsequently used. Then without changing the
value of the basic block you can safely remove this
statement.
• (c) Renaming temporary variables
• A statement t:= b + c can be changed to u:= b + c where t is
a temporary variable and u is a new temporary variable. All
the instance of t can be replaced with the u without changing
the basic block value.
• (d) Interchange of statement
• Suppose a block has the following two adjacent statements:
• t1 : = b + c
• t2 : = x + y
• These two statements can be interchanged without affecting
the value of block when value of t1 does not affect the value
of t2.
2. Algebraic transformations:

• In the algebraic transformation, we can change the set of


expression into an algebraically equivalent set. Thus the expression
x:= x + 0 or x:= x *1 can be eliminated from a basic block without
changing the set of expression.
• Constant folding is a class of related optimization. Here at compile
time, we evaluate constant expressions and replace the constant
expression by their values. Thus the expression 5*2.7 would be
replaced by13.5.
• Sometimes the unexpected common sub expression is generated by
the relational operators like <=, >=, <, >, +, = etc.
• Sometimes associative expression is applied to expose common
sub expression without changing the basic block value. if the
source code has the assignments
• a:= b + c
• e:= c +d +b
DAG representation for basic blocks

• A DAG for basic block is a directed acyclic graph with the


following labels on nodes.
• The leaves of graph are labeled by unique identifier and that
identifier can be variable names or constants.
• Interior nodes of the graph is labeled by an operator symbol.
• Nodes are also given a sequence of identifiers for labels to
store the computed value.
• DAGs are a type of data structure. It is used to implement
transformations on basic blocks.
• DAG provides a good way to determine the common
sub-expression.
• It gives a picture representation of how the value computed
by the statement is used in subsequent statements.
Algorithm for construction of DAG

• Input:It contains a basic block


• Output: It contains the following information:
• Each node contains a label. For leaves, the label is
an identifier.
• Each node contains a list of attached identifiers to
hold the computed values.
• Case (i) x:= y OP z
• Case (ii) x:= OP y
• Case (iii) x:= y
Method:

• Step 1:
• If y operand is undefined then create node(y).
• If z operand is undefined then for case(i) create node(z).
• Step 2:
• For case(i), create node(OP) whose right child is node(z) and left
child is node(y).
• For case(ii), check whether there is node(OP) with one child
node(y).
• For case(iii), node n will be node(y).
• Output:
• For node(x) delete x from the list of identifiers. Append x to
attached identifiers list for the node n found in step 2. Finally set
node(x) to n.
Example:

• Consider the following three address statement:


• S1:= 4 * i
• S2:= a[S1]
• S3:= 4 * i
• S4:= b[S3]
• S5:= s2 * S4
• S6:= prod + S5
• Prod:= s6
• S7:= i+1
• i := S7
• if i<= 20 goto (1)
Stages in DAG Construction:

You might also like