0% found this document useful (0 votes)
15 views54 pages

Unit 5

Uploaded by

ritikshah1206
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)
15 views54 pages

Unit 5

Uploaded by

ritikshah1206
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/ 54

Department of CE

CD : COMPILER DESIGN

Code Optimization and Unit no : 5


Code Optimization

Generation and Generation


(01CE0714)

Prof. Dhara Joshi


Outline :
Optimization Techniques
Department of CE
Peephole Optimization
Global Data Flow Analysis
Unit no : 5
Issues in design of Code generators Code Optimization
Basic Block and Flow Graphs and Generation
(01CE0714)
Register Allocation and Assignments
DAG Representation of Basic Block

Prof. Dhara Joshi


 Optimization is the process of transforming a piece of
code to make more efficient (in terms of time or space)
without changing its output or side-effects.
 User can able to see that code runs faster and/or
consumes less memory.

What is Advantages
Optimization  Optimized code has faster execution speed
 Optimized code utilizes the memory efficiently
 Optimized code gives better performance
Optimization
Technique
Function Preserving
 Common Sub Expression Elimination
 Constant Folding
 Copy Propagation
 Dead Code Elimination

Optimization Loop Optimization


Technique  Code Motion
 Strength Reduction
Optimization
Technique
 It means Shifting of computation from run time to
compile time.
 There are two methods
1. Folding : in this technique, the computation of constant
is done at compile time instead of run time.
Compile Example : length = (22/7) * d
Time 2. Constant Propagation : In this technique, the value of
variable is replaced and computation of expression is
Evaluation done at compilation time.
Example : pi=3.14, r=2
Area = pi*r*r  3.14*2*2 (computation is done during
compilation)
 The common subexpression is an expression appearing
repeatedly in the program which is computed previously.
 If the operands of this sub expression do not get changed
at all then result of such sub expression is used instead of
re-computing it each time.
Common Sub
t1 = 4*i t1 = 4*i
Expression
t2 = a[t1] t2 = a[t1]
Elimination
t3 = 4*j t3 = 4*j
t4 = 4*i t4 = 4*i
t5= b[t4] + 1 t5 = b[t1] + 1
It means used of one variable instead of another.
Example

A = PI

Copy Area = A * r * r Area = PI *r *r


propagation
 If variables used in a computation within a loop are not
altered within the loop, the calculation can be performed
outside of the loop and the results used within the loop.
While (i <= limit-2) n = limit-2
{ While (i <= n)
-------- {
Code Motion -------- --------
} --------
}
 Strength of certain operators are higher than others.
 Replaces less efficient instructions with more efficient ones.
For example, in array subscripting, an add instruction
replaces a multiply instruction.
 Example
Reduction in for(i=1;i<=50;i++) temp=7
Strength { for(i=1;i<=50;i++)
count = i*7; {
} count= temp;
temp = temp + 7;
}
 The variable is said to be Dead at a point in a program, if
the value contained into it is never been used.
 Eliminated code that can not be reached or where the
results are not subsequently used.
 Example :

Dead Code int i=0,x;

Elimination If (i==1)
{
x=x+i;
}
 It is a simple and effective technique for locally improving
target code.
 This technique is applied to improve the performance of
the target program by examining the short sequence of
target instruction (called peephole or window) and
replacing these instructions by shorter or faster sequence
Peephole whenever possible.
Optimization  Peephole is a small, moving window on the target
program.
 Goals :
 Improve Performance
 Reduce code size
 Redundant Load and Store can be eliminated.
 Example
MOV R0 , x
MOV x , R0
Redundant
Instruction  We can eliminate second instruction.
Elimination
 Unnecessary jumps can be eliminated in either the
intermediate code or the target code by the following
types of peephole optimization.
Goto L1 Goto L2
------ ------
L1 : Goto L2 L1 : Goto L2
Flow of
Control
 If there are no jump to L1 then we can eliminate L1:Goto
Optimization L2

If a<b goto L1 If a<b goto L2


----- ------
L1 : goto L2 L1 : goto L2
#define debug 0
If(debug) {
Print debugging information
}
In the intermediate representation the if-statement may be
translated as:
Unreachable If debug=1 goto L1
Code Goto L2
L1: print debugging information
L2 :
 Peephole optimization is an effective technique for
algebraic specification.
 The statements such as
x = x + 0 or x=x*1
can be eliminated by peephole optimization.

Algebraic
Specification
 Certain machine instructions are cheaper than other.
 In order to improve the performance of the intermediate
code we can replace these instructions by equivalent
cheaper instructions.
 For example, x^2 can be computed easily by x*x, instead
of using exponential function.
Reduction in
Strength
 The target instructions have equivalent machine
instructions for performing some operations.
 Hence we can replace these target instructions by
equivalent machine instruction in order to improve the
efficiency.
 Example : Some machines have auto-increment and auto-
Machine decrement addressing modes.
Idioms  These modes can be used in code for the statements :
i=i+1 or i=i-1.
 In order to do code optimization and a good job of
code generation , a compiler needs to collect
information about the program as a whole and to
distribute this information to each block in the flow
graph.
Global Data  Data flow equations are the equations representing
Flow Analysis the expressions that are appearing in the flow
graph.
 Data flow information can be collected by setting up
and solving systems of equations that relate
information at various point in a program.
 A typical equation has the form
Out[S] = gen[S] ꓴ (in[S] – kill[S])
And can be read as
Global Data “the information at the end of a statement is either
Flow Analysis generated within the statement, or enters at the
beginning and is not killed as control flows through
the statement”.
 The details of how data-flow analysis are set up and solved
depend on three factors.
1. The notion of generating and killing depend on the
desired information. i.e. for some problem, instead of
proceeding along with the flow of control and defining
Global Data out[S] in terms of in[S], we need to proceed backwards
and defines in[S] in terms of out[S].
Flow Analysis
2. Since data flows along control paths, data-flow analysis
is affected by the control constructs in a program.
3. There are subtleties that go along with such statements
as procedure calls, assignment through pointer and even
assignments to array variables.
 A program point containing the definition is called
Definition Point.
 A program point at which a reference to a data item
is made is called reference point.
 A program point at which some evaluating
expression is given is called evaluation point.
Data Flow
Properties W1 : x=3 Definition
point

W2 : y=x Reference
point

W3 : z = x * y Evaluation
point
1. The expression x+y is said to be available at its evaluation
point
2. Neither of two operands get modified before their use.
Reaching Definition:

The definition D1 is reaching definition for block B2,


Available
But the definition D1 isn’t reaching for block B3,
Expression
Because it is killed by definition D2 in block B2.
 A live variable x is live at point p, if there is path from p to
the exit, along which the value of x is used before its
redefined.
 Otherwise the variable is said to be dead at the point.

Live Variable Busy Expression:

 An expression e is said to be busy expression along some


path pi…pj if an evaluation of e exists along some path
pi…pj and no definition of any operand exist before its
evaluation along path.
 The final phase of compilation process is code
generation.
 It takes an intermediate representation of the
source program as input and produces an
equivalent target program as output.
Role of Code  Main task of Code Generator:
Generator  Instruction selection
 Register allocation and assignment
 Instruction ordering
 Instruction selection:
 Choose appropriate target-machine instructions to
implement the IR statements.
Code  Register allocation and assignment:
Generator  Decide what values to keep in which registers.
 Instruction ordering:
 Decide in what order to schedule the execution of
instructions.
Target code should have following property:
 Correctness
Code  High quality
Generator  Efficient use of resources of target code
 Quick code generation
Issues in Code Generation
Issues in design of code generation are:
 Input to the code generator
 Target program
Issues in  Memory management
Code  Instruction selection
Generation  Register allocation
 Choice of evaluation order
 Approaches to code generation
 Input to the code generator consists of the intermediate
representation of the source program.
 There are several types for the intermediate language,
 Quadruples
Input to the  syntax trees Or DAGs.
code  postfix notation
generator  The detection of semantic error should be done before
submitting the input to the code generator.
 The code generation phase requires complete error free
intermediate code as an input.
 The output of the code generator is the target program.
 The output may take on a variety of forms:
1. Absolute machine language (executable code)
Language has the advantage that it can be placed in a fixed location in
memory and immediately executed. (executable)
2. Relocatable machine language (Object files or linker)
Target Producing a relocatable machine language program as output is that the
Program subroutine can be compiled separately. A set of relocatable object
modules can be linked together and loaded for execution by a linking
loader. (object model / ‘.o’ file)
3. Assembly language
Producing an assembly language program as output makes the process
of code generation somewhat easier .We can generate symbolic
instructions and use the macro facilities of the assembler to help
generate code.
 This refers to use of malloc/free, new/delete, and related
issues.
 Mapping names in the source program to addresses of data
objects in run time memory is done cooperatively by the
Memory front end and the code generator.
Management  We assume that a name in a three-address statement refers
to a symbol table entry for the name.

 From the symbol table information, a relative address can be


determined for the name in a data area.
 If we do not care about the efficiency of the target program, instruction
selection is straightforward. It requires special handling. For example, the
sequence of statements
 a := b + c
 d := a + e
 would be translated into

Instruction  MOV b, R0

Selection  ADD c, R0
 MOV R0, a
 MOV a, R0
 ADD e, R0
 MOV R0, d
 Here the fourth statement is redundant, so we can eliminate that
statement.
 Instructions containing register operands are usually shorter
and faster than that of using in memory or involving
operands in memory.
 The use of registers is often subdivided into two sub
problems:
1. Register allocation: we select the set of variables that will
reside in registers at a point in the program.
Register
2. Register assignment: select a specific register that a
Allocation variable reside in.

Complications imposed by the hardware architecture:


 Finding an optimal assignment of registers to variables is
difficult, even with single register value.
 Mathematically the problem is NP-complete.
 T=A+B
 T=T*C
 T=T/D
Register
Allocation  Load R1, A

(Example)  Add R1, B


 Mul R1, C
 Division R1, D
 Store T,R1
 The order in which computations are performed can affect the
efficiency of the target code.

Choice of  Some computation orders require fewer registers to hold


intermediate results than others.
evaluation  Picking a best order is another difficult, NP-complete problem.
 When instructions are independent, their evaluation order can
be changed.
a + b – (c + d) * e

MOV a, R0
T1 = a + b
ADD b, R0
T2 = c + d
MOV R0, T1
T3 = e * t2
Choice of T4 = T1 – T3
MOV c, R1
MOV c, R0
evaluation ADD d, R1
ADD d, R0
(Example) reorder MOV e, R0
MOV e, R1
MUL R1, R0
T2 = c + d MUL R0, R1
MOV T1, R1
T3 = e * T2 MOV a, R0
SUB R0, R1
T1 = a + b ADD b, R0
MOV R1, T4
T4 = T1 – T3 SUB R1, R0
MOV R0, T4
 The most important criterion for a code generator is that it
produces correct code.
Approaches  Correctness takes on special significance because of the number
to code of special cases that code generator might face.

generator  Given the premium on correctness, designing a code generator


so it can be easily implemented, tested, and maintained is an
important design goal.
 A basic block is sequence of 3-address statements where
control enters at the beginning and leaves only at the end
without any jumps or halts.
 In order to find the basic blocks, we need to find the leaders
in the program. Then a basic block will start from one leader
to the next leader but not including next leader.

Basic Blocks Identifying leaders in basic block:


1. 1st statement is leader.
2. Statement that is target of conditional or unconditional
statement is a leader.
 if () goto 100 (Line number 100 is a leader)
 goto 200 (Line number 200 is a leader)
3. Statement that follows immediately a conditional or
unconditional statement is a leader.
 Program in HLL: Output of ICG
fact(x) (3-address code)
{
1) f = 1;
int f = 1; 2) i = 2;
Identifying for(i = 2; i <= x; i++) 3) if (i > x) go to 9
4) t1 = f * i;
leaders in f = f * i;
5) f = t1;
Basic Block return f; 6) t2 = i + 1;
} 7) i = t2;
8) goto(3);
9) goto calling
program
Output of ICG
(3-address code)

Leader 1) f = 1;
Block 1
2) i = 2;

Leader 3) if (i > x) go to 9 Block 2


Partition into
4) t1 = f * i;
Basic Blocks Leader
5) f = t1;
6) t2 = i + 1; Block 3
7) i = t2;
8) goto(3);

Leader 9) goto calling Block 4


program
 A flow graph is a graphical representation of a sequence of
instructions with control flow edges.
 A flow graph can be defined at the intermediate code level or
target code level.
 A control flow graph (CFG) is a directed graph with basic blocks Bi
as vertices and with edges Bi -> Bj if Bj can be executed
Flow Graphs immediately after Bi

Successor and Predecessor Blocks:


 Suppose the CFG has an edge B1 -> B2
 Basic block B1 is a predecessor of B2
 Basic block B2 is a successor of B1
Register Allocation
and
Assignment
 Efficient utilization of registers is important in
generating good code.
 There are four strategies for deciding what values
Register in a program should reside in a registers and which
Allocation register each value should reside.
and  Strategies are:
Assignment  Global Register Allocation
 Usage Count
 Register Assignment for Outer Loop
 Register Allocation for Graph Coloring
Strategies adopted while doing the global register
allocation are:
 The global register allocation has a strategy of storing the
most frequently used variables in fixed registers throughout
the loop.
 Another strategy is to assign some fixed number of global
registers to hold the most active values in each inner loop.
Global  The registers are not already allocated may be used to hold
Register values local to one block.
Allocation  In certain languages like C or Bliss programmer can do the
register allocation by using register declaration to keep
certain values in register for the duration of the procedure.
 Example:
{
register int x;
}
 The usage count is the count for the use of some variable x in
some register used in any basic block.
 The usage count gives the idea about how many units of cost
can be saved by selecting a specific variable for global register
allocation.
Usage Count  The approximate formula for usage count for the Loop L in
some basic block B can be given as,
σblock B in L (use(x,B) + 2∗ live(x,B))
 Where use(x,B) is number of times x used in block B prior to
any definition of x live(x,B) =1 if x is live on exit from B;
otherwise live(x)=0.
 Consider that there are two loops L1 is outer loop and L2 is an
inner loop, and allocation of variable a is to be done to some
register. The approximate scenario is as given below,

Register
Assignment
for Outer Following criteria should be adopted for register assignment for
Loop outer loop,
 If a is allocated in loop L2 then it should not be allocated in L1 - L2.
 If a is allocated in L1 and it is not allocated in L2 then store a on
entrance to L2 and load a while leaving L2.
 If a is allocated in L2 and not in L1 then load a on entrance of L2
and store a on exit from L2.
 The graph coloring works in two passes. The working is as given
below,
 In the first pass the specific machine instruction is selected for
register allocation. For each variable a symbolic register is
allocated.
 In the second pass the register inference graph is prepared.
Register  In register inference graph each node is a symbolic registers and
Allocation an edge connects two nodes where one is live at a point where
other is defined.
for Graph  Then a graph coloring technique is applied for this register
Coloring inference graph using k- color.
 The k-colors can be assumed to be number of assignable registers.
 In graph coloring technique no two adjacent nodes can have same
color. Hence in register inference graph using such graph coloring
principle each node (actually a variable) is assigned the symbolic
registers so that no two symbolic registers can interfere with each
other with assigned physical registers.
DAG Representation
of Basic Block
 We assume the three address statement could of following types,
Case (i) x:=y op z
Case (ii)x:=op y
Case (iii) x:=y
 With the help of following steps the DAG can be constructed.
 Step 1: If y is undefined then create node(y). Similarly if z is
Algorithm for undefined create a node(z)
Constructing  Step 2:
DAG  Case(i) create a node(op) whose left child is node(y) and
node(z) will be the right child. Also check for any common sub
expressions.
 Case(ii) determine whether is a node labeled op, such node
will have a child node(y).
 Case(iii) node n win be node(y).
 Step 3: Delete x from list of identifiers for node(x). Append x to
the list of attached identifiers for node n found in 2.
DAG
Representation
of Basic Block
The DAGs are used in:
 Determining the common sub-expressions.
 Determining which names are used inside the block and
Applications computed outside the block.

of DAG  Determining which statements of the block could have their


computed value outside the block.
 Simplifying the list of quadruples by eliminating the common sub-
expressions and not performing the assignment of the form x:=y
unless and until it is a must.
Thanks
Prof. Dhara Joshi

You might also like