UNIT-5 Notes
UNIT-5 Notes
UNIT-5 Notes
UNIT-V
Code Generation: Issues in the Design of a Code Generator, The Target Language,
addresses in the Target Code, Basic Blocks and Flow graphs, Optimization of Basic Blocks,
Peephole Optimization, Register Allocation and Assignment.
Machine-Independent Optimizations: The Principal Sources of Optimizations,
Introduction to Data-Flow Analysis.
CODE GENERATION:
The final phase of a compiler is code generator. Code generation is the process of
creating machine language
It receives an intermediate representation (IR) from front end of compiler along with
supplementary information in symbol table and produces a semantically equivalent
target program/object code.
• Instruction ordering
Evaluation order is an important factor in generating an efficient target code.
Some orders require a smaller number of registers to hold intermediate results
than the other orders.
• Picking up the best order is difficult.
• Picking a best order is another NP- Complete
• Mostly, the order in which the three-address code is generated, same order is
followed.
Register R R 0
Example: t1 = a * 5
t2 = t1 + 7
t3 = t2 – 5
t4 = t1+ t3
t5 = t2 + b
So, the intermediate code is portioned into basic blocks. Each basic blocks become
the nodes of a flow graph.
Partitioning Algorithm:
Any given program can be partitioned into blocks using the following two steps
Step-2: Basic block is formed starting at the leader and ends just before the next
leader statement.
Example:
Blocks: Each block contains statements from the leader to just before the next leader.
• Usually, we add Entry and Exit blocks also.
Block1: 1st statement
Block2: 2nd statement
Block3: statements from 3 to 9
Block4: statements 10, 11
Block5: 12th statement
Block6: 13th statement
FLOW GRAPH:
Once an intermediate-code program is partitioned into basic blocks, we represent
the flow of control between them by a flow graph.
• A flow graph is a directed graph in which the flow control information is added
to the basic blocks.
• The nodes of the flow graph are the basic blocks.
There is an edge from block B to block C if the first instruction in block C immediately
follow the last instruction in block B.
Example for Glow Graph:
Compute the basic blocks for the given three address statements and draw flow
graph
(1) PROD = 0
(2) I = 1
(3) T2 = addr(A) – 4
(4) T4 = addr(B) – 4
(5) T1 = 4 x I
(6) T3 = T2[T1]
(7) T5 = T4[T1]
(8) T6 = T3 x T5
(9) PROD = PROD + T6
(10) I = I + 1
(11) IF I <=20 GOTO (5)
Solution-
● PROD = 0 is a leader since first statement of the code is a leader.
● T1 = 4 x I is a leader since target of the conditional goto statement is a leader.
goto L1
...
Ll: goto L2
goto L2
...
Ll: goto L2
o
• Algebraic simplifications and reduction in strength
o x = x + 0, x = x * 1, x2 <=> x * x,
• Use of machine idioms
o Autoincrement and Autodecrement
Efficient allocation of register is important for generating good code. There are four
strategies for deciding what values in a program should reside in a register and
which register each value should reside.
1. Global Register Allocation
2. Usage Counts
3. Register Assignment for Outer Loops
4. Register Allocation by Graph Coloring
1. Global Register Allocation:
Simple code generation algorithm does local (block based) register allocation. This
resulted that all live variables be stored at the end of block. To save some of these
stores and their corresponding loads, we might arrange to assign registers to
frequently used variables and keep these registers consistent across block boundaries
(globally)
• Frequently used variables are stored in fixed registers.
• So, assign some fixed registers to hold most active variables in each inner
loop.
nodes are symbolic registers, and an edge connects two nodes if one is live at the
point where the second is defined.
MACHINE-INDEPENDENT OPTIMIZATIONS:
Code Optimization is an approach to enhance the performance of the code. The code
optimization in the synthesis phase is a program transformation technique, which tries
to improve the intermediate code by making it consume fewer resources (i.e., CPU,
Memory, registers) so that faster-running machine code is generated. Code optimizing
process should meet the following objectives :
• The optimization must be correct, it must not, in any way, change the
meaning of the program.
• Optimization should increase the speed and performance of the program.
• The compilation time must be kept reasonable.
• The optimization process should not delay the overall compiling process.
A) Constant Folding-
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.
1. It involves eliminating the common sub expressions.
2. The redundant expressions are eliminated to avoid their re-computation.
3. 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-
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;
} }
5. Strength Reduction-
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.
Data flow analysis refers to a body of techniques that derive information about the
flow of data along program execution paths.
Analysis that determines the information regarding definition and use of data in
program. It is useful in global optimization of code.
Basic Terminology:
• Definition Point: place/line in which a variable is defined.
• Reference Point: place/line in which a variable is referred.
• Evaluation Point: place/line in which operations (arithmetic) is performed.
B2 y=x+L
1
p = L1 * 3 B3