Unit 4
Unit 4
Actual parameters
Returned values
Control link(Dynamic Link)
Access link(Static Link )
Saved machine status
Local data
Temporaries
Activation Records
A run-time stack known as a control stack manages the procedure calls and returns.
The control stack stores the activation record of each live activation. The top of the
stack will hold the latest activation record.
The content of the activation record is given below. This record may vary according to
the implemented languages.
Temporaries: The values which arise from the evaluation of expression will be held
by temporaries.
Local data: The data belonging to the execution of the procedure is stored in local data.
Saved machine status: The status of the machine that might contain register, program
counter before the call to the procedure is stored in saved machine status.
Access link: The data's information outside the local scope is stored in the access link.
Control link: The activation record of the caller is pointed by the control link.
Returned values: It represents the space for the return value of the called function if
any.
Actual parameter: It represents the actual parameters used by the calling procedure.
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 1
4.2 ACCESS TO NON-LOCAL NAMES:
In some cases, when a procedure refer to variables that are not local to it, then such
variables are called non-local variables
There are two types of scope rules, for the non-local names. They are
Static scope
Dynamic scope
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 2
Example: obtain the static scope of the declarations made in the following piece of
code.
Access Link:
Access links are the pointers used in the implementation of lexical scope which is
obtained by using pointer to each activation record. If procedure p is nested within a
procedure q then access link of p points to access link or most recent activation record
of procedure q
Displays:
If access links are used in the search, then the search can be slow So, optimization is
used to access an activation record from the direct location of the variable without any
search. Display is a global array d of pointers to activation records, indexed by lexical
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 3
nesting depth. The number of display elements can be known at compiler time d[i] is
an array element which points to the most recent activation of the block at nesting depth
(or lexical level).
Example:
Static Allocation
In this allocation scheme, the compilation data is bound to a fixed location in the
memory and it does not change when the program executes. As the memory
requirement and storage locations are known in advance, runtime support package for
memory allocation and de-allocation is not required.
Stack Allocation
Procedure calls and their activations are managed by means of stack memory allocation.
It works in last-in-first-out (LIFO) method and this allocation strategy is very useful for
recursive procedure calls.
Heap Allocation
Variables local to a procedure are allocated and de-allocated only at runtime. Heap
allocation is used to dynamically allocate memory to the variables and claim it back
when the variables are no more required.
Except statically allocated memory area, both stack and heap memory can grow and
shrink dynamically and unexpectedly. Therefore, they cannot be provided with a fixed.
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 4
As shown in the image above, the text part of the code is allocated a fixed amount of
memory. Stack and heap memory are arranged at the extremes of total memory
allocated to the program
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 5
GC does not always know when to process within virtual memory environments
of modern desktop computers.
The GC process interacts poorly with cache and virtual memory systems,
resulting in performance-tuning difficulties.
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 6
4.7 ISSUES IN THE DESIGN OF A CODE GENERATOR
Code generator converts the intermediate representation of source code into a form that
can be readily executed by the machine. A code generator is expected to generate the
correct code. Designing of code generator should be done in such a way so that it can
be easily implemented, tested and maintained.
Target program –
The target program is the output of the code generator. The output may be absolute
machine language, relocatable machine language, assembly language.
Absolute machine language as output has advantages that it can be placed in a fixed
memory location and can be immediately executed.
Relocatable machine language as an output allows subprograms and subroutines to
be compiled separately. Relocatable object modules can be linked together and
loaded by linking loader. But there is added expense of linking and loading.
Assembly language as output makes the code generation easier. We can generate
symbolic instructions and use macro-facilities of assembler in generating code.
And we need an additional assembly step after code generation.
Memory Management –
Mapping the names in the source program to the addresses of data objects is done by
the front end and the code generator. A name in the three address statements refers to
the symbol table entry for name. Then from the symbol table entry, a relative address
can be determined for the name.
Instruction selection –
Selecting the best instructions will improve the efficiency of the program. It includes
the instructions that should be complete and uniform. Instruction speeds and machine
idioms also plays a major role when efficiency is considered. But if we do not care
about the efficiency of the target program then instruction selection is straight-forward.
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 7
For example, the respective three-address statements would be translated into the latter
code sequence as shown below:
P:=Q+R
S:=P+T
MOV Q, R0
ADD R, R0
MOV R0, P
MOV P, R0
ADD T, R0
MOV R0, S
Here the fourth statement is redundant as the value of the P is loaded again in that
statement that just has been stored in the previous statement. It leads to an inefficient
code sequence. A given intermediate representation can be translated into many code
sequences, with significant cost differences between the different implementations. A
prior knowledge of instruction cost is needed in order to design good sequences, but
accurate cost information is difficult to predict.
Evaluation order –
The code generator decides the order in which the instruction will be executed. The
order of computations affects the efficiency of the target code. Among many
computational orders, some will require only fewer registers to hold the intermediate
results. However, picking the best order in the general case is a difficult NP-complete
problem.
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 8
Approaches to code generation issues: Code generator must always generate the correct
code. It is essential because of the number of special cases that a code generator might
face. Some of the design goals of code generator are:
Correct
Easily maintainable
Testable
Efficient
Method: First identify the leader in the code. The rules for finding leaders are as
follows:
The first statement is a leader.
Statement L is a leader if there is an conditional or unconditional goto statement
like: if....goto L or goto L
Instruction L is a leader if it immediately follows a goto or conditional goto
statement like: if goto B or goto B
Each leader’s basic block will have all the instructions from the leader itself until the
instruction, which is just before the starting of the next leader.
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 9
end
while i <= 10
end
Sol:
Step1: Three Address Code
(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<=10 goto (3)
prod := 0
i := 1 B1
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
B2
(11) i := t7
(12) if i<=10 goto (3)
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 10
Flow Graph
Flow graph is a directed graph. It contains the flow of control information for the set of
basic block. A control flow graph is used to depict that how the program control is being
parsed among the blocks. It is useful in the loop optimization.
Flow graph for the vector dot product is given as follows:
There are two type of basic block optimization. These are as follows:
1. Structure-Preserving Transformations
2. Algebraic Transformations
1. Structure-Preserving Transformations
The primary Structure-Preserving Transformation on basic blocks are as follows:
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 11
Common sub-expression elimination:
Suppose we have two expressions that compute the same values. In that case, we need
to eliminate one of the expressions. This method is known as the common sub-
expression elimination method.
Example:
p=a+b
q=c–d
r = x+ y
s=c-d
This example shows that the second and fourth statements compute the same
expression: c - d. So the basic block can be transformed as follows:
p=a+b
q=c-d
r=x+y
s=q
2. Algebraic Transformations:
We can also optimized the basic blocks using algebraic identities. For example, we may
apply arithmetic identities, such as
Local reduction in strength is also another kind of algebraic transformation. In this
optimization, a more expensive operator is replaced by a cheaper one.
x^2 Instead of x*x
2*x Instead of x+x
x/2 Instead of x * 0.5
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 12
4.10 A SIMPLE CODE GENERATOR
A code generator generates target code for a sequence of three- address statements
and
effectively uses registers to store operands of the statements.
For example: consider the three-address statement a := b+c It can have the
following sequence of codes:
A code-generation algorithm:
The algorithm takes as input a sequence of three-address statements constituting a basic
block. For each three-address statement of the form x : = y op z, perform the following
actions:
1. Invoke a function get reg to determine the location L where the result of the
computation y op z should be stored.
2. Consult the address descriptor for y to determine y’, the current location of y. Prefer
the register for y’ if the value of y is currently both in memory and a register. If the
value of y is not already in L, generate the instruction MOV y’ , L to place a copy
of y in L
3. Generate the instruction OP z’ , L where z’ is a current location of z. Prefer a
register to a memory location if z is in both. Update the address descriptor of x to
indicate that x is in location L. If x is in L, update its descriptor and remove x from
all other descriptors.
4. If the current values of y or z have no next uses, are not live on exit from the block,
and are in registers, alter the register descriptor to indicate that, after execution of
x : = y op z , those registers will no longer contain y or z
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 13
• The assignment d : = (a-b) + (a-c) + (a-c) might be translated into the following three-
address code sequence:
Code sequence for the example is:
Advantage
Heavily used values reside in registers
Disadvantage
Does not consider non-uniform distribution of uses
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 14
To find out the live range(s) of each variable and the area(s) where the variable is
used/defined global allocation is needed. Cost of spilling will depend on frequencies
and locations of uses.
A simple but effective technique for improving the target code is peephole optimization,
a method for trying to improving the performance of the target program by examining
a short sequence of target instructions (called the peephole) and replacing these
instructions by a shorter or faster sequence, whenever possible.
The peephole is a small, moving window on the target program. The code in the
peephole need not be contiguous, although some implementations do require this. It is
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 15
characteristic of peephole optimization that each improvement may spawn
opportunities for additional improvements.
we can delete instructions (2) because whenever (2) is executed. (1) will ensure
that the value of a is already in register R0.If (2) had a label we could not be sure that
(1) was always executed immediately before (2) and so we could not remove (2).
Unreachable Code:
#define debug 0
….
If ( debug ) {
Print debugging information
}
In the intermediate representations the if-statement may be translated as:
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 16
One obvious peephole optimization is to eliminate jumps over jumps .Thus no
matter what the value of debug; (a) can be replaced by:
If debug ≠1 goto L2
Print debugging information
L2: …………………………… (b)
If debug ≠0 goto L2
Print debugging information
L2: …………………………… (c)
As the argument of the statement of (c) evaluates to a constant true it can be replaced
By goto L2. Then all the statement that print debugging aids are manifestly
unreachable and can be eliminated one at a time.
Flows-Of-Control Optimizations:
The unnecessary jumps can be eliminated in either the intermediate code or the
target code by the following types of peephole optimizations. We can replace the jump
sequence
goto L1
….
L1: goto L2
If there are now no jumps to L1, then it may be possible to eliminate the statement
L1:goto L2 provided it is preceded by an unconditional jump .Similarly, the
sequence
if a < b goto L1
….
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 17
can be replaced by
If a < b goto L2
….
L1: goto L2
goto L1
may be replaced by
If a < b goto L2
goto L3
…….
L3:
While the number of instructions in(e) and (f) is the same, we sometimes skip
the unconditional jump in (f), but never in (e).Thus (f) is superior to (e) in execution
time
Algebraic Simplification:
Reduction in Strength:
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 18
Reduction in strength replaces expensive operations by equivalent cheaper ones
on the target machine. Certain machine instructions are considerably cheaper than
others and can often be used as special cases of more expensive operators.
X2 → X*X
i:=i+1 → i++
i:=i-1 → i- -
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 19
t4:= t1 + t3
For the expression (a+b) + (e+(c-d)), a DAG can be constructed for the above sequence
as shown below
The code is thus generated by translating the three address code line by line
MOV a, R0
ADD b, R0
MOV c, R1
SUB d, R1
MOV R0, t t1:= a+b
MOV e, R0 R1 has c-d
ADD R0, R1 /* R1 contains e + (c – d)*/
MOV t1, R0 /R0 contains a + b*/
ADD R1, R0
MOV R0, t4
Now, if the ordering sequence of the three address code is changed
t2:= c - d
t3:= e + t2
t1:= a + b
t4:= t1 + t3
Then, an improved code is obtained as:
MOV c, R0
SUB D, R0
MOV e, R1
ADD R0, R1
MOV a, R0
ADD b, R0
ADD R1, R0
MOV R0, t4
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 20
Heuristic Ordering
The algorithm displayed below is for heuristic ordering. It lists the nodes of a DAG
such that the node’s reverse listing results in the computation order.
{
While unlisted interior nodes remain
do
{
select an unlisted node n, all of whose parents have been listed;
List n;
While the leftmost child ‘m’ of ‘n’ has no unlisted parents and is not a leaf
do
{
/*since na was just listed, surely m is not yet listed*/
}
{
list m
n =m;
}
}
order = reverse of the order of listing of nodes
}
Labeling Algorithm
Labeling algorithm deals with the tree representation of a sequence of three address
statements
It could similarly be made to work if the intermediate code structure was a parse tree.
This algorithm has two parts:
The first part labels each node of the tree from the bottom up, with an integer that
denotes the minimum number of registers required to evaluate the tree, and with no
storing of intermediate results
The second part of the algorithm is a tree traversal that travels the tree in an order
governed by the computed labels in the first part, and which generates the code during
the tree traversal
if n is a leaf then
if n is leftmost child of its parents then
Label(n) = 1
else label(n) = 0
else
{
/*n is an interior node*/
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 21
let n1, n2, …..,nk be the children of ordered by label,
so label(n1) >= label(n2) >= … >= label(nk);
label(n) = max (label (ni) + i – 1)
}
Method:
Step 1:
If y is undefined then create node(y).
If z is undefined, create node(z) for case(i).
Step 2:
For the case(i), create a node(OP) whose left child is node(y) and right child is
node(z). (Checking for common sub expression). Let n be this node.
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 22
For case(ii), determine whether there is node(OP) with one child node(y). If not
create such a node.
For case(iii), node n will be node(y).
Step 3:
Delete x from the list of identifiers for node(x). Append x to the list of attached
identifiers for the node n found in step 2 and set node(x) to n.
Example: Consider the block of three- address statements in Fig
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 23
Application of DAGs:
1. We can automatically detect common sub expressions.
2. We can determine which identifiers have their values used in the block.
3. We can determine which statements compute values that could be used outside the
block.
CLASS NOTES - COMPILER DESIGN UNIT-IV MRS KANDE ARCHANA ASSISTANT PROFESSOR MRIET III-II B TECH 24