Professional Documents
Culture Documents
Runtime Environments
The program consists of names for procedures, identifiers etc., that require
mapping with the actual memory location at runtime.
Runtime environment is a state of the target machine, which may include
software libraries, environment variables, etc., to provide services to the
processes running in the system.
1.Storage organization
Runtime storage can be subdivided to hold :
● Memory allocation and deallocation can be done at any time and at any
place depending on the requirement of the user.
Activation record
● Stack is used for managing procedure calls
● Storage is organized as a stack and a new activation record is pushed on
the stack whenever a function is called and popped when the function
call ends .
● The information needed during an execution of a procedure is kept on a
block of storage called activation record.
● Locals are contained in activation records so they are bound to fresh
storage in each activation.
2
Fig: Activation Record
local data: field for local data.
saved machine status: holds information about machine status before
procedure call.
access link or static link : to access non local data.
control link or dynamic link :points to activation record of caller.
actual parameters: field to hold actual parameters.
returned value: field for holding value to be returned.
3
Procedure Calls
Calling Sequences
A return sequence is similar code to restore the state of the machine so the
calling procedure can continue its execution after the call.
Call Sequence
Caller evaluates the actual parameters
Caller stores return address and other values (control link) into callee’s
activation record
Callee saves register values and other status information
Callee initializes its local data and begins execution.
Return Sequence
• Callee places a return value next to activation record of caller
• Restores registers using information in status field
• Branch to return address
• Caller copies return value into its own activation record
4
Displays
Fig: display
● Use one array access to find the activation record containing X. if the
most-closely nested declaration of X is at nesting depth I, the d[i] points
to the activation record containing the location for X
BASIC BLOCKS
• A basic block is a sequence of consecutive statements in which control
enters at the beginning and leaves at the end without halt or possibility of
branching except at the end.
5
Optimization of basic blocks
4.1 DAG representation of Basic Block:-
6
Algorithm for Construction of DAG - for x := y op z.
• If node(y) is undefined, create a leaf labeled y and let node(y) be this leaf. If
node(z) is undefined, create a leaf labeled z and let node(z) be that leaf
• Determine if there is a node labeled op, whose left child is node(y) and its
right child is node(z). If not, create such a node. Let n be the node found or
created.
Applications of DAG:
7
4.2 Finding local common sub expressions
8
The Use of algebraic identities
Fl
ow Graphs
• Once an intermediate-code program is partitioned into basic blocks, we
represent the flow of control between them by a flow graph.
• The nodes of the flow graph are the basic blocks
• There is an edge from B1 to B2iff B2 immediately follows B1 in some execution
sequence
– B2 immediately follows B1 in program text
• B1 is a predecessor of B2, B2 is a successor of B1
Generate the flow graph for the following program for finding dot product of
two arrays x and y of length 20
prod = 0;
i = 1;
do
{
prod = prod + a[i] * b[i];
i=i+1;
}while ( i<=20 );
9
Flow graph can be constructed by first converting program into three
address code
10
Data Flow Analysis
● Data-flow analysis is a technique for gathering information about the
possible set of values calculated at various points in a computer
program. A program's control flow graph (CFG) is used to determine
those parts of a program to which a particular value assigned to a
variable might propagate.
Basic Terminologies –
11
7.2 Data Flow Analysis Schema
● A control-flow graph
12
IN[B] and OUT[B] = input and output of basic block B
Transfer function for block B i.e Out[B] = Gen[B] U (in[B]-Kill[B]
Meet operation (U):
IN[B] = out[P1 ] U out[P2 ] U ... U out[Pn ], where p1 , ..., pn are all the
predecessors of B
GEN[B] = Set of definition generated from basic block B
KILL[B] =set of definitions killed by defs in B
IN[Entry] = φ, OUT[Entry] = φ,
13
7.2.2 Live Variable Analysis
. A variable v is live at point p if
– the value of v is used along some path in the flow graph starting at p.
Fig: Example1
14
OUT[
B] = IN[S1 ] U IN[S2 ] U ... U IN[Sn ], where s1 , ..., sn are all successors of B
Advantage –
1. Live Variable analysis is useful for register allocation.
2. It is used in dead code elimination.
15
Available Expression Computation Example 2
16
7.2.4 Busy Expressions
An expression E is very busy at Point P if no matter what path is taken from P,
the expression E is evaluated before any of its operands are defined.
Example: An expression a+b is very busy at a point P if a+b is evaluated on all paths from P to
EXIT and there is no definition of a or b on a path between P and an evaluation of a+b
PEEPHOLE OPTIMIZATION
Peephole is machine dependent optimization. Peephole optimization is a type of Code
Optimization performed on a small part of the code. It is performed on a very small set of
instructions in a segment of code.
A simple but effective technique for improving the target code is peephole optimization,
a method for trying to improve 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 characteristic of
peephole optimization that each improvement may spawn opportunities for additional
improvements.
17
→Redundant-instructions elimination
→Flow-of-control optimizations
→Algebraic simplifications
→Use of machine idioms
→Unreachable
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:
One obvious peephole optimization is to eliminate jumps over jumps .Thus no matter what
the value of debug; (a) can be replaced by:
18
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 statements 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
….
by the sequence
goto L2
….
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
….
can be replaced by
If a < b goto L2
….
L1: goto L2
19
Finally, suppose there is only one jump to L1 and L1 is preceded by an unconditional
goto. Then the sequence
goto L1
L1: if a < b goto L2 (f) L3:
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:
There is no end to the amount of algebraic simplification that can be attempted through
peephole optimization. Only a few algebraic identities occur frequently enough that it is worth
considering implementing them. For example, statements such as
x := x+0 or
x := x * 1
are often produced by straightforward intermediate code-generation algorithms, and they can be
eliminated easily through peephole optimization.
Reduction in Strength:
20
2
X → X*X
The target machine may have hardware instructions to implement certain specific
operations efficiently. For example, some machines have auto-increment and auto-decrement
addressing modes. These add or subtract one from an operand before or after using its value. The
use of these modes greatly improves the quality of code when pushing or popping a stack, as in
parameter passing. These modes can also be used in code for statements like i : =i+1.
i:=i+1 → i++
i:=i-1 → i- -
21