0% found this document useful (0 votes)
7 views

Code Optimization

Uploaded by

Spandan Sahu
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

Code Optimization

Uploaded by

Spandan Sahu
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 64

Code Optimization

Introduction
Position of code optimizer:
Source target
Front Intermediate code Code Intermediate code Code program
program
end optimizer generator

Purpose of code optimizer:

•to get better efficiency


• Run faster
• Take less space
organization of the code optimizer

Control-
flow Data-flow transformations
analysis analysis

Control-flow analysis Collect information about the


Identify blocks and program as a whole and to
loops in the flow distribute this information to
graph of a program each block in the flow graph.
Basic Blocks and flow graphs
Basic Blocks:
A sequence of consecutive statements in
which flow of control enters at the beginning
and leaves at the end without halt or
possibility of branching except at the end.
Flow graph:
A directed graph that are composed of
the set of basic blocks making up a program
Algorithm for Partitioning
TAC into basic blocks
Input: A sequence of three-address statements.
Output: A list of basic blocks with each three-address statement in exactly one block.
Method:
1.We first determine the set of leaders, the first statements of basic
blocks.
The rules we use are the following:
I. The first statement is a leader.
II. Any statement that is the target of a conditional or
unconditional goto is leader.
III. Any statement that immediately follows a goto or conditional
goto statement is a leader.
2. For each leader, its basic block consists of the leader and all
statements up to but not including the next leader or the end of
the program.
Basic Blocks and flow graphs
Example 1 : program to compute dot product

begin
prod := 0;
i := 1;
do begin
prod := prod + a[i] * b[i];
i := i+1;
end
while i<= 20
end
Basic Blocks and flow graphs
three-address code of program to compute dot product

(1) prod := 0
(2) i := 1
(3) t1 := 4*I
(4) t2=a[t1]
(5) t3 := 4*I
(6) t4=b[t3]
(7) t5 :=t2*t4
(8) t6 := prod+t5
(9) prod := t6
(10) t7:= i+1
(11) i=t7
(12) if i<=20 goto (3)
Basic Blocks and flow graphs
three-address code of program to compute dot product

(1) prod := 0 leader by rule 1 (i)


(2) i := 1
(3) t1 := 4*I leader by rule 1 (iii)
(4) t2=a[t1]
(5) t3 := 4*I
(6) t4=b[t3]
(7) t5 :=t2*t4
(8) t6 := prod+t5
(9) prod := t6
(10) t7:= i+1
(11) i=t7
(12) if i<=20 goto (3)
Basic Blocks and flow graphs
Construction of flow graphs:
The node of flow graph are the basic blocks.
One node is distinguish as initial , it is the block whose
leader is the 1st statement
There is a directed edge from block B1 to Block B2 if B2
follow immediately B1 in some execution sequence, if
1.There is a conditional or uncnditional jump from the
last statement of B1 to the 1st statement of B2
2.B2 immediately follows B1 in the order of the program
and B1 doesn’t end in an unconditional jump.
flow graphs

prod := 0
i := 1 B1

t1 := 4*I
t2=addr(a)-4
t3 := t2 [ t1 ] B2
t4=addr(b)-4
t5 :=t4 [ t1 ]
t6 := t3*t5
prod := prod +t6
i := i+1
if i<=20 goto (3)
Basic Blocks and flow graphs
Example 2: exp(x)
{
exp(x)
int p=1;
{ i=2
int p=1; change do
for(i=2;i<=x;i++) p=p*I
p=p*i i++
r=p+1 while(i<=x)
r=p+1
}
}
Basic Blocks and flow graphs
1. p=1
1. p=1
2. i=2 2. i=2
3. t1=p*i 3. if (i<=x) goto 5
4. p=t1 4. goto 9
5. t2=i+1 5. t1=p*i
6. i=t2 6. p=t1
7. t2=i+1
7. if (i<=x) goto 3
8. i=t2
8. t3=p+1 9. t3=p+1
9. r=t3 10. r=t3

While condition at while condition at


end of loop beginning of loop
Basic Blocks and flow graphs
Leader 1
1. p=1
2. i=2
Leader 2
3. t1=p*i
4. p=t1
5. t2=i+1
6. i=t2
7. if (i<=x) goto 3
Leader 3
8. t3=p+1
9. r=t3
Basic Blocks and flow graphs

p=1
i=2

t1=p*i
p=t1
t2=i+1
i=t2
if (i<=x) goto 3

t3=p+1
r=t3
The Principal Sources of Optimization
The possibilities to improve a compiler can be explained with the following most
frequently applied transformation techniques:
1. Function-preserving transformations;
 Common subexpressions elimination;
 Copy propagation;
 Dead-code elimination;
 Constant Folding
2. Loop optimisations;
code motion, Induction variables and reduction in strength.
• A code improving transformation is called local if it is performed by
looking at statements within one concrete block
• a code improving transformation is global if it is performed by looking
at statements not only in one concrete block, but also outside in global
and other outside blocks
Quick Sort Example
void quicksort( int m, int n )
{
int i,j;
int v,x;
if ( n <= m ) return;
i = m - 1;
j = n;
v = a[ n ];
while ( 1 )
{
do i = i + 1; while ( a[ i ] < v );
do j = j - 1; while ( a[ j ] > v );
if ( I >= j ) break;
x = a[ i ];
a[ i ] = a[ j ];
a[ j ] = x;
}
x = a[ i ];
a[ i ] = a[ n ];
a[ n ] = x;
quicksort( m, j );
quicksort( i+1, n );
}
Quick Sort TAC
1) i := m - 1 16 ) t7 := 4 * i
2) j := n 17 ) t8 := 4 * j
3) t1 := 4 * n 18 ) t9 := a[ t8 ]
4) v := a[ t1 ] 19 ) a[ t7 ]:= t9
5) i := i + 1 20 ) t10 := 4 * j
6) t2 := 4 * i 21 ) a[ t10 ]:= x
7) t3 := a[ t2 ] 22 ) goto (5)
8) if ( t3 < v ) goto (5) 23 ) t11 := 4 * i
9) j := j - 1 24 ) x := a[ t11 ]
10 ) t4 := 4 * j 25 ) t12 := 4 * i
11 ) t5 := a[ t4 ] 26 ) t13 := 4 * n
12 ) if ( t5 > v ) goto (9) 27 ) t14 := a[ t13 ]
13 ) if ( i >= j ) goto (23) 28 ) a[ t12 ]:= t14
14 ) t6 := 4 * i 29 ) t15 := 4 * n
15 ) x := a[ t6 ] 30 ) a[ t15 ]:= x
Flowgraph
i := i + 1 j := j - 1
i := m - 1
t2 := 4 * i t4 := 4 * j
j := n
t3 := a[ t2 ] t5 := a[ t4 ]
t1 := 4 * n
if ( t3 < v ) goto B2 if ( t5 > v ) goto B3 B3
v := a[ t1 ]
B1 B2
if ( i >= j ) goto B6
B4
t6 := 4 * i t11 := 4 * i
x := a[ t6 ] x := a[ t11 ]
t7 := 4 * i t12 := 4 * i
t8 := 4 * j t13 := 4 *n
t9 := a[ t8 ] t14 := a[ t13 ]
a[ t7 ]:= t9 a[ t12 ]:= t14
t10 := 4 * j B5 t15 := 4 * n
a[ t10 ]:= x B6 a[ t ]:= x
15
goto B2
Common subexpressions Elimination
An expression E is called a common sub-expression if an
expression E was previously computed, and the values of
variables in E have not changed since the previous computation.
Notes: We can avoid re-computing the expression if we
can use the previously computed value
Example: Local Common subexpressions
Before After Before After
t6 := 4 * i t11 := 4 * i
x := a[ t6 ] t6 := 4 * i x := a[ t11 ] t11 := 4 * i
t7 := 4 * i x := a[ t6 ] t12 := 4 * i x := a[ t11 ]
t8 := 4 * j t8 := 4 * j t13 := 4 *n t13 := 4 *n
t9 := a[ t8 ] t9 := a[ t8 ] t14 := a[ t13 ] t14 := a[ t13 ]
a[ t7 ]:= t9 a[ t6 ]:= t9 a[ t12 ]:= t14 a[ t11 ]:= t14
t10 := 4 * j a[ t8 ]:= x t15 := 4 * n a[ t13 ]:= x
a[ t10 ]:= x goto B2 a[ t15 ]:= x
goto B2
B5 B5 B6 B6
Common subexpressions
Example: Global Common subexpressions
i := i + 1 j := j - 1
i := m - 1
t2 := 4 * i t4 := 4 * j
j := n
t3 := a[ t2 ] t5 := a[ t4 ]
t1 := 4 * n
if ( t3 < v ) goto B2 B3
v := a[ t1 ] if ( t5 > v ) goto B3
B2
B1
t11 := 4 * i
t6 := 4 * i
x := a[ t11 ]
x := a[ t6 ]
t13 := 4 *n
t8 := 4 * j
t14 := a[ t13 ]
t9 := a[ t8 ]
a[ t11 ]:= t14
a[ t6 ]:= t9
B5 a[ t8 ]:= x a[ t13 ]:= x B6
goto B2

Before Elimination
Common subexpressions
i := i + 1 j := j - 1
i := m - 1
t2 := 4 * i t4 := 4 * j
j := n
t3 := a[ t2 ] t5 := a[ t4 ]
t1 := 4 * n
if ( t3 < v ) goto B2 if ( t5 > v ) goto B3 B3
v := a[ t1 ]

B1 B2 if ( i >= j ) goto B6
B4

x := t3
x := t3 a[ t12 ]:= a[ t1 ]
a[ t2 ]:= t5
a[ t2 ] := t14
a[ t4 ]:= x
a[ t1 ]:= x
B5 goto B2
B6

After eliminating Global Common subexpressions


Copy Propagation
One concerns assignments of the form a=b called copy
statements.
If there is no change in either variable then we can replace
later occurrences of a with b
Example:

The copy of x in B5 and B6 can be replaced with t3


Before After
Before After
x := t3 a[ t12 ]:= a[ t1 ]
x := t3 a[ t12 ]:= a[ t1 ]
a[ t2 ]:= t5 a[ t2 ] := t14
a[ t2 ]:= t5 a[ t2 ] := t14
a[ t4 ]:= t3 a[ t1 ]:= t3
a[ t4 ]:= x a[ t1 ]:= x
goto B2
goto B2
B5 B6 B6
B5
Dead Code Elimination
A variable is live at a point in a program if its value can be
used subsequently; otherwise it is dead at that point.

Notes: A related idea is dead or useless code, statements


that compute values and never get used.
Example:
After copy propagation, the value of x in B5 and B6 is
never used again, we can eliminate this instruction
altogether Before After
Before After
x := t3 a[ t12 ]:= a[ t1 ]
x := t3 a[ t12 ]:= a[ t1 ]
a[ t2 ]:= t5 a[ t2 ] := t14
a[ t2 ]:= t5 a[ t2 ] := t14
a[ t4 ]:= t3 a[ t1 ]:= t3
a[ t4 ]:= t3 a[ t1 ]:= t3
goto B2
goto B2
B5 B6 B6
B5
Quick Sort Flow Graph
After eliminating Dead Code the flow graph look like:

i := i + 1 j := j - 1
i := m - 1
t2 := 4 * i t4 := 4 * j
j := n
t3 := a[ t2 ] t5 := a[ t4 ]
t1 := 4 * n
if ( t3 < v ) goto B2 if ( t5 > v ) goto B3 B3
v := a[ t1 ]
B1 B2
if ( i >= j ) goto B6
B4

a[ t12 ]:= a[ t1 ]
a[ t2 ]:= t5 a[ t2 ] := t14
a[ t4 ]:= t3 B6 a[ t1 ]:= t3
goto B2 B5
Constant Folding
Constant-folding is what allows a language to accept
constant expressions where a constant is required.

The evaluation at compile-time of expressions whose


operands are known to be constant

Example :
int arr[20 * 4 + 3];
switch (i) {
case 10 * 5: ...
}
• The expression can be resolved to an integer constant at compile time
Code Motion
• An important modification that decreases the amount of code
in a loop
• Loop-invariant computation
• A loop-invariant is a statements that evaluate the same
value at every iteration of the loop
• So move all loop-invariants to outside the loop
• Code Motion takes loop-invariant computation before its loop

t = limit -2
while (i <= limit-2) while (i <= t)

26
Induction Variables and Reduction in
Strength
• Induction variable
• For an induction variable x, there is a positive or negative constant c
such that each time x is assigned, its value increases by c
• Induction variables can be computed with a single increment
(addition or subtraction) per loop iteration
• Strength reduction
– The transformation of replacing an expensive operation, such as
multiplication, by a cheaper one, such as addition
• Induction variables lead to
– strength reduction
– eliminate computation
Induction Variables and Reduction in
Strength Let j=5
J - 4 3 21
t4 - 16 12 8 4
i := i + 1 j := j - 1 Here J and t4
i := m - 1
t2 := 4 * i t4 := 4 * j are induction
j := n
t3 := a[ t2 ] t5 := a[ t4 ] varible.
t1 := 4 * n
if ( t3 < v ) goto B2 if ( t5 > v ) goto B3 B3 As they are
v := a[ t1 ]
used later in
B2 B3 and B4 we
B1
if ( i >= j ) goto B6 cant
B4
eliminate
either
a[ t12 ]:= a[ t1 ]
a[ t2 ]:= t5 a[ t2 ] := t14
a[ t4 ]:= t3 B6 a[ t1 ]:= t3
goto B2 B5
Induction Variables and Reduction in
Strength
After strength reduction

i := m - 1 i := i + 1 j := j - 1
j := n t2 := t2 + 4 t4 := t4 -4
t1 := 4 * n t3 := a[ t2 ] t5 := a[ t4 ]
v := a[ t1 ] if ( t3 < v ) goto B2 if ( t5 > v ) goto B3 B3
t2 =4*i
B2
t4 =4*j
if ( i >= j ) goto B6 B4
B1

a[ t12 ]:= a[ t1 ]
a[ t2 ]:= t5 a[ t2 ] := t14
a[ t4 ]:= t3 B6 a[ t1 ]:= t3
goto B2 B5
Induction Variables and Reduction in
Strength As I and J
becomes dead
code ,so they
i := m - 1 are eliminated
j := n t2 := t2 + 4 t4 := t4 -4
t1 := 4 * n t3 := a[ t2 ] t5 := a[ t4 ]
v := a[ t1 ] if ( t3 < v ) goto B2 if ( t5 > v ) goto B3 B3
t2 := 4 * i
t4 := 4 * j B2
if (t2 >= t4 ) gotoB6 B4
B1

a[ t12 ]:= a[ t1 ]
a[ t2 ]:= t5 a[ t2 ] := t14
a[ t4 ]:= t3 B6 a[ t1 ]:= t3
goto B2 B5
Directed Acyclic Graph
• It is used for an expression to identify
common sub expression in the expression
• It is like a syntax tree
=

i 10

i = i +10
Directed Acyclic Graph
i = i +10
a=b+c
+ i1 b=a–d
c=b+c
d=a-d

i0 10

If the value is changed


then distinguish it by
using subscript
Directed Acyclic Graph

t1 = 4*i
t2=a[t1]

[]

*
a

4 i
Directed Acyclic Graph
Construction:

1. Set node(y) to undefined for each symbol y


2. for each statement x = y op z, x = op y , x = y
repeat steps 3, 4, and 5
3. If node(y) is undefined,
• create a leaf for y
• set node(y) to the new node
• do the same for z
4. if <op, node(y), node(z)> doesn't exist, create it and let n point to
that node
5. delete x from the list of labels for node(x)
• append x to the list of labels for n
• set node(x) to n
Directed Acyclic Graph
Application

• It automatically detects common sub-


expression
• We can determine which identifiers have their
value calculated outside and used in the block
• We can determine the statements which
computes values that is used outside the block
Data-flow analysis

• Iteratively propagate basic block information over


the control-flow graph until no changes
• Calculate the final value at the beginning of the
basic block
• Analyze global data-flow information to do code
optimization and a good job of code generation
Notes: Data-flow information can be collected by
setting up and solving systems of equations that
relate data information at various points in a
program flow.
1. Reaching Definitions
Definition d of variable v: a statement d that assigns a value
to v.
Use of variable v: reference to value of v in an expression
evaluation.

Definition d of variable v reaches a point p if there exists a


path from immediately after d to p such that definition d is
not killed along the path.
Definition d is killed along a path between two points if there
exists an assignment to variable v along the path.

37
Example

d reaches u along path2 & d does not reach u along path1

Since there exists a path from d to u along which d is not


killed (i.e., path2), d reaches u.

38
Reaching Definitions Contd.
Unambiguous Definition: X = ….;
Ambiguous Definition: *p = ….; p may point to
X

For computing reaching definitions, typically


we only consider kills
X=..by unambiguous

definitions. *p=..

Does definition of X reach here ? Yes

39
Computing Reaching Definitions
At each program point p, we compute the set
of definitions that reach point p.
Reaching definitions are computed by solving a
system of equations (data flow equations).
d2: X=… d3: X=…

IN[B]
GEN[B] ={d1}
d1: X=…
OUT[B] KILL[B]={d2,d3}

40
Data Flow Equations
IN[B]: Definitions that reach B’s entry.
OUT[B]: Definitions that reach B’s exit.

GEN[B]: Definitions within B that reach the end of B.


KILL[B]: Definitions that never reach the end of B due
to redefinitions of variables in B.

41
Reaching Definitions Contd.
• Forward problem – information flows
forward in the direction of edges.
• May problem – there is a path along which
definition reaches a point but it does not
always reach the point.
Therefore in a May problem the meet
operator is the Union operator.

42
Applications of Reaching Definitions
• Constant
Propagation/folding

• Copy Propagation

43
2. Available Expressions
An expression is generated at a point if it is computed at that
point.
An expression is killed by redefinitions of operands of the
expression.

An expression A+B is available at a point if every path from


the start node to the point evaluates A+B and after the
last evaluation of A+B on each path there is no
redefinition of either A or B (i.e., A+B is not killed).

44
Available Expressions

Available expressions problem computes: at each program


point the set of expressions available at that point.

45
Data Flow Equations
IN[B]: Expressions available at B’s entry.
OUT[B]: Expressions available at B’s exit.

GEN[B]: Expressions computed within B that are


available at the end of B.
KILL[B]: Expressions whose operands are redefined in B.

46
Available Expressions Contd.
• Forward problem – information flows
forward in the direction of edges.
• Must problem – expression is definitely
available at a point along all paths.
Therefore in a Must problem the meet
operator is the Intersection operator.
• Application:

A
47
3. Live Variable Analysis
A path is X-clear is it contains no definition of X.
A variable X is live at point p if there exists a X-clear path
from p to a use of X; otherwise X is dead at p.

Live Variable Analysis


Computes:
At each program point
p identify the set of
variables that are live at p.

48
Data Flow Equations
IN[B]: Variables live at B’s entry.
OUT[B]: Variables live at B’s exit.

GEN[B]: Variables that are used in B prior to their


definition in B.
KILL[B]: Variables definitely assigned value in B before
any use of that variable in B.

49
Live Variables Contd.
• Backward problem – information flows
backward in reverse of the direction of
edges.
• May problem – there exists a path along
which a use is encountered.
Therefore in a May problem the meet
operator is the Union operator.

50
Applications of Live Variables
• Register Allocation

• Dead Code
Elimination

• Code Motion
Out of Loops

51
4. Very Busy Expressions
A expression A+B is very busy at point p if for all paths
starting at p and ending at the end of the program, an
evaluation of A+B appears before any definition of A or B.

Application:
Code Size Reduction

Compute for each program point the set of


very busy expressions at the point.
52
Data Flow Equations
IN[B]: Expressions very busy at B’s entry.
OUT[B]: Expressions very busy at B’s exit.

GEN[B]: Expression computed in B and variables used in


the expression are not redefined in B prior to
expression’s evaluation in B.
KILL[B]: Expressions that use variables that are
redefined in B.

53
Very Busy Expressions Contd.
• Backward problem – information flows
backward in reverse of the direction of
edges.
• Must problem – expressions must be
computed along all paths.
Therefore in a Must problem the meet
operator is the Intersection operator.

54
Summary

May/Union Must/
Intersection
Forward Reaching Available
Definitions Expressions
Backward Live Very Busy
Variables Expressions

55
Use-Def & Def-Use Chains

56
Loops in flow graphs
Dominators:
We say node d of a flow graph dominates node n,
written d dom n, if every path from the initial
node of the flow graph to n goes through d

•Each node dominates itself


•The entry of a loop dominates all nodes in the loop
•The initial node dominates all other nodes
Loops in flow graphs
Example : Finding Dominators

1 dom(1) = {1,2,3,4,5,6,7,8,9,10}
2 It means node 1 dominates to all.
dom(2) = {2}
3 dom(3) = {3,4,5,6,7,8,9,10}
dom(4) = {4,5,6,7,8,9,10}
4 dom(5) = {5}
dom(6) = {6}
5 6
dom(7) = {7,8,9,10}
7 dom(8) = {8,9,10}
dom(9) = {9}
8 dom(10) = {10}

9 10
Loops in flow graphs
Example : Dominator Tree

•Dominator tree is used to present 1


the dominators
2 3

•Initial node is the root


4

•Each node d dominates its


5 6 7
descendants

• Edges in the dominator tree 8


represent immediate dominator
relationships. 9 10
Loops in flow graphs
Definition : Natural loop

Two essential properties of loops are their:


1. A loop must have a single entry point , called header.
2. There must be at least one way to iterate loop or at least
one path back to the header(back edge).

Back edge:
The edges whose heads dominate their tails.
If there exists an edge (b, a) in the CFG where a
dominates b, then, edge (b, a) is a back edge
Loops in flow graphs
Example: Find the natural loops in the CFG
The back edges are (10, 7) , (9, 1), (8, 3)
(7, 4) , (4, 3)

1 A natural loop is associated


2 with each back edge (b, a) which consist
node a plus all nodes dominated by a (a
3
is the entry of the loop) and can reach b
without going through a
4
For back edge (10,7)
5 6
where 7 dominates 10
7 Loop of 107
= {7} + {8,10}
8 = {7,8,10}
10
Where 8 and 10 can reach 10 without
9 going through 7
Reducible Flow Graph
A flow graph is reducible if its edges a can be
partitioned into two disjoint sets:
• Forward edges from an acyclic graph in which
every node can be reached from the initial
node.
• Backedges whose heads (sink) dominate tails
(source).
Any flow graph that cannot be partitioned as
above is a non-reducible or irreducible.
Reducible Flow Graph
Example : non reducible flow graph

Here initial node is one.


This FG has no back edge

1 23 not a back edge


32 not a back edge

Dom(1)= {2,3}
2 3 Dom(2)= {2}
Dom(3)= {3}

23 not a back edge


3 doesn’t dominates 2
32 not a back edge
2 doesn’t dominates 3
Next
Code Generation

You might also like