You are on page 1of 27

Chapter 17::

Code Improvement

Programming Language Pragmatics, Fourth Edition


Michael L. Scott

Copyright © 2016 Elsevier


Code Optimization
Why
 To derive the best possible performance
from the given resources.
 To balance Speed and Memory Tradeoffs
according to requirements.
 More emphasis is on writing efficient code
(Smart code)
 Faster execution
 Efficient memory usages
 Yielding better performance
Code Optimization
What
 Optimization is the process of
transforming a piece of code to make it
more efficient.
 It does not change the meaning of
program.
Introduction

• Code improvement at the level of basic blocks is known as


local optimization
– elimination of redundant operations (unnecessary loads, common sub-
expression calculations)
– effective instruction scheduling and register allocation
• At higher levels of aggressiveness, compilers employ
techniques that analyze entire subroutines for further speed
improvements
• These techniques are known as global optimization
– multi-basic-block versions of redundancy elimination
– instruction scheduling, and register allocation
– code modifications designed to improve the performance of loops
Phases of Code Improvement
Code Optimization

Techniques for Speed optimization


 Constant propagation
 Constant folding
 Algebraic simplification, strength reduction
 Copy propagation
 Common subexpression elimination
 Unreacheable code elimination
 Dead code elimination
 Loop Optimization
Code Optimization

Techniques for Memory optimization


 Reduce Padding
 Local Vs Global Variables
Code Optimization Techniques
 Constant Propagation
If the value of a variable is a constant,
then replace the variable by the constant
Ex.
N := 10; C := 2;
for (i:=0; i<N; i++) for (i:=0; i<10; i++)
{ {
s := s + i*C; s := s + i*2;
} }
Code Optimization Techniques
 Constant Folding
Simplifying constant expressions as much as
possible

Ex.
static final int a = 2; int b = 30 * a;
// folding would create
int b = 60;
Code Optimization Techniques
 Algebraic simplification
 More general form of constant folding,
 x+0⇒x x–0⇒x
 x*1⇒x x/1⇒x
 x*0⇒0

 Strength reduction
 Replace expensive operations
 x := x * 8 ⇒ x := x << 3
Code Optimization Techniques

 Code Motion (Out of loops)


A modification that decreases the amount of code in a
loop.
Invariant expressions should be executed only once.
Ex.
for (int i = 0; i < x.length; i++)
x[i] *= Math.PI *Math.cos(y);

//Code motion will result in the equivalent of


double cosy = Math.PI * Math.cos(y);
for (int i = 0; i < x.length; i++)
x[i] *= cosy;
Code Optimization Techniques

 Copy propagation
Extension of constant propagation
After y is assigned to x, use y to replace x till x is
assigned again
Ex.
x := y; ⇒ s := y * f(y)
s := x * f(x)

Reduce the copying


If y is reassigned in between, then this action cannot
be
Code Optimization Techniques
 Common sub expression elimination
Searches for instances of identical expression,
replacing them with a single variable holding the
computed value (if possible)
Ex. a := b + c a := b + c
c := b + c ⇒ c := a
d := b + c d := a

Example in array index calculations


 c[i+1] := a[i+1] + b[i+1]
 During address computation, i+1 should be reused
 Not visible in high level code, but in intermediate code
Code Optimization Techniques
 Unreacheable code elimination
Construct the control flow graph
Unreachable code block will not have an incoming edge
 Dead code elimination
Ineffective statements
 x := y + 1 (immediately redefined, eliminate!)
 y := 5 ⇒ y := 5
 x := 2 * z x := 2 * z

A variable is dead if it is never used after last definition


 Eliminate assignments to dead variables
Need to do data flow analysis to find dead variables
Code Optimization Techniques

Function inlining
 Replace a function call with the body of the
function.
 Program will spend less time in the function call
and return parts, etc.
 It has also some disadvantages – Increase program
size and break encapsulation.
Function cloning
 Create specialized code for a function for different
calling parameters
Code Optimization Techniques
Loop optimization: is the process of the increasing
execution speed and reducing the overheads associated
of loops. Consumes 90% of the execution time, a larger
payoff to optimize the code within a loop

Techniques:
 Loop invariant detection and code motion
 Induction variable elimination
 Strength reduction in loops
 Loop unrolling
 Loop peeling
 Loop fusion
Code Optimization Techniques
Loop invariant detection and code motion
 If the result of a statement or expression does not
change within a loop, and it has no external side-
effect

Computation can be moved to the outside of the loop


Ex.
c := x/y;
for (i=0; i<n; i++)
for (i=0; i<n; i++)
a[i] := a[i] + x/y;
a[i] := a[i] + c;
Code Optimization Techniques
Induction variable elimination
 If there are multiple induction variables in a
loop, can eliminate the ones which are used only
in the test condition

Ex.
s := 0;
for (i=0; i<n; i++) { s := s + 4; }

s := 0;
while (s < 4*n) { s := s + 4; }
Code Optimization Techniques
Loop fusion
 Some adjacent loops can be fused into one loop to reduce
loop overhead and improve run-time performance.
Ex.
for i=1 to N do for i=1 to N do
A[i] = B[i] + 1 A[i] = B[i] + 1
endfor C[i] = A[i] / 2
for i=1 to N do D[i] = 1 / C[i+1]
C[i] = A[i] / 2 endfor
endfor
for i=1 to N do
D[i] = 1 / C[i+1]
endfor
Code Optimization Techniques
Memory based Optimization
 Reduce Padding
Declare local variables based on their size. Prefer to
declare larger to smaller data type variables.
Ex.
struct
{ char x;
int y; }
Here size of struct is 4 bytes !!!!!
 Points to be remember while using Register variable –
Code Optimization Techniques
/* sizeof = 64 bytes */ /*sizeof = 48 bytes */
struct foo sturct foo
{ float a; double b; { double b; double d;
float c; double d; short long f;
e; long h;
long f; float c;
short g; float a;
long h; int j;
char i; int l;
int j; short e;
char k; short g;
int l; }; char k;
char I;};
Local Vs Global Variables
 Local variables are stored in registers.
 Keep the number of local variables low to allow
them to be fit in the available registers and avoid
stack usage.
 Global Variables are stored in RAM.
 Manipulating and accessing local variables is less
costly as it uses registers compared to accessing from
memory.
 Avoid referring to global or static variables inside the
tightest loops, instead use local variables.
 Declare local variables in the inner most scope.
Code Optimization tricks in C
 Usages of Register Variables
Use Register variables whenever possible. Accessed
from register rather from memory, so accessing is
faster.
Ex. register float val;
register double dval;
register int ival;

Points to be remember while using Register variable -


 Only declare those variables as register which are heavily used
 We can not take the address of register variable, so never try this.
&ival would fail.
Code Optimization tricks in C

Miscellaneous
 Use unsigned int instead of int if we know the value
will never be negative.
 Avoid unnecessary division.
Ex: (a / b) > c can be rewritten as a > (c * b)
 Use shift operations >> and << instead of integer
multiplication and division, where possible.
Code Optimization tricks in C

Miscellaneous
 Try to use Switch in place of nested
if…elseif…elseif…else
 Prefer Integer comparison.
 Avoid calculations in loop and try to use
simplify expression.
 Try to minimize usages of global variables.
They are never allocated to registers.
 use the prefix operator (++obj) instead of the
postfix operator (obj++).
Code Optimization tricks in C

Miscellaneous Continue…..
 Use unsigned int instead of int if we know
the value will never be negative.
 Avoid unnecessary division.
Phases of Code Improvement