Unit 5
Peephole Optimization
Peephole optimization is a code optimization technique applied to small segments of code,
known as a "peephole" or "window." It replaces code with shorter and faster alternatives
without changing the program's output. It is machine-dependent and aims to:
Improve performance
Reduce memory usage
Minimize code size
Techniques of Peephole Optimization:
1. Redundant Load and Store Elimination: Removes unnecessary variable
assignments.
Initial:
y = x + 5; i = y; z = i; w = z * 3;
Optimized:
y = x + 5; w = y * 3;
2. Constant Folding: Simplifies constant expressions at compile time.
Initial: x = 2 * 3;
Optimized: x = 6;
3. Strength Reduction: Replaces costly operations with faster equivalents.
Initial: y = x * 2;
Optimized: y = x + x;
4. Null Sequence Removal: Eliminates operations with no effect.
Examples: a = a + 0;, a = a * 1;
5. Combine Operations: Merges multiple operations into one.
6. Dead Code Elimination: Removes code that doesn't affect output.
Initial: Contains unnecessary computations.
Optimized: Retains only essential lines.
Register Allocation and Assignment in Compiler Design (8 Marks)
Register Allocation and Register Assignment are crucial phases in compiler design for
managing processor registers effectively.
Register Allocation
This process decides which variables should be stored in registers to reduce memory access.
Key steps include:
1. Live Variable Analysis: Identifies variables that are active (live) at a given program
point.
2. Interference Graph: Builds a graph where each node represents a variable, and
edges show conflicts between variables that cannot share a register.
3. Graph Coloring: Assigns registers to variables by coloring the graph such that no
two adjacent nodes share the same color (register).
Register Assignment
This phase maps specific physical registers to the variables determined during register
allocation. It implements the decisions from the interference graph and handles scenarios
where registers are insufficient.
Strategies
1. Spilling: Stores some variables in memory when registers are insufficient.
2. Local vs. Global Allocation:
o Local allocation works within a single basic block.
o Global allocation spans multiple blocks using live range analysis.
3. Priority-based Allocation: Allocates registers to frequently accessed variables first.
Directed Acyclic Graph (DAG) in Compiler Design (8 Marks)
A Directed Acyclic Graph (DAG) is a special kind of Abstract Syntax Tree used to optimize
basic blocks in a compiler. It is acyclic, meaning it contains no cycles, and each node in the
graph has a unique value.
Optimization of Basic Blocks
DAGs are constructed using Three Address Code to optimize basic blocks. They help in:
Dead Code Elimination: Removing unnecessary computations.
Common Sub-expression Elimination: Avoiding redundant calculations.
Properties of DAGs
1. Reachability relation forms a partial order.
2. Transitive closure and reduction are uniquely defined.
3. Topological orderings are possible.
Applications of DAGs
Identifying common sub-expressions computed more than once.
Detecting computations performed outside the block but used inside.
Identifying values in the block that can be reused outside.
Simplifying Quadruples by skipping unnecessary assignments.
Rules for Constructing DAGs
1. Interior Nodes represent operators, while Exterior Nodes (Leaves) represent
constants, identifiers, or variable names.
2. Before adding a new node, check for existing nodes with the same value to detect
common sub-expressions.
3. Assignment instructions like x := y are avoided unless necessary.
Code Optimizatioin:
1. Compile Time Evaluation-
Two techniques that falls under compile time evaluation are-
A) Constant Folding-
In this technique,
As the name suggests, it involves folding the constants.
The expressions that contain the operands having constant values at compile time are
evaluated.
Those expressions are then replaced with their respective results.
Example-
Circumference of Circle = (22/7) x Diameter
Here,
This technique evaluates the expression 22/7 at compile time.
The expression is then replaced with its result 3.14.
This saves the time at run time.
B) Constant Propagation-
In this technique,
If some variable has been assigned some constant value, then it replaces that variable with
its constant value in the further program during compilation.
The condition is that the value of variable must not get alter in between.
Example-
pi = 3.14
radius = 10
Area of circle = pi x radius x radius
Here,
This technique substitutes the value of variables ‘pi’ and ‘radius’ at compile time.
It then evaluates the expression 3.14 x 10 x 10.
The expression is then replaced with its result 314.
This saves the time at run time.
2. Common Sub-Expression Elimination-
The expression that has been already computed before and appears again in the code for computation
is called as Common Sub-Expression.
In this technique,
As the name suggests, it involves eliminating the common sub expressions.
The redundant expressions are eliminated to avoid their re-computation.
The already computed result is used in the further program when required.
Example-
Code Before Optimization Code After Optimization
S1 = 4 x i
S1 = 4 x i
S2 = a[S1]
S2 = a[S1]
S3 = 4 x j
S3 = 4 x j
S4 = 4 x i // Redundant Expression
S5 = n
S5 = n
S6 = b[S1] + S5
S6 = b[S4] + S5
3. Code Movement-
In this technique,
As the name suggests, it involves movement of the code.
The code present inside the loop is moved out if it does not matter whether it is present
inside or outside.
Such a code unnecessarily gets execute again and again with each iteration of the loop.
This leads to the wastage of time at run time.
Example-
Code Before Optimization Code After Optimization
for ( int j = 0 ; j < n ; j ++) x=y+z;
{ for ( int j = 0 ; j < n ; j ++)
x=y+z; {
a[j] = 6 x j; a[j] = 6 x j;
} }
4. Dead Code Elimination-
In this technique,
As the name suggests, it involves eliminating the dead code.
The statements of the code which either never executes or are unreachable or their output is
never used are eliminated.
Example-
Code Before Optimization Code After Optimization
i=0;
if (i == 1)
{ i=0;
a=x+5;
5. Strength Reduction-
In this technique,
As the name suggests, it involves reducing the strength of expressions.
This technique replaces the expensive and costly operators with the simple and cheaper
ones.
Example-
Code Before Optimization Code After Optimization
B=Ax2 B=A+A
Here,
The expression “A x 2” is replaced with the expression “A + A”.
This is because the cost of multiplication operator is higher than that of addition operator.
Issues in code Generator see