CD Unit 5-1
CD Unit 5-1
Run-Time Environments:
The compiler demands for a block of memory to operating system. The compiler utilizes this
block of memory for executing the compiled program. This block of memory is called run time
storage.
Storage organization:
The runtime storage is sub divided into :
1. Code Area.
2. Static data Area.
3. Stack Area.
4. Heap Area.
Code Area: holds the instructions to be executed, which is static & size is determined at compile
time.
Heap Area: allocated memory dynamically on demand for various purposes, dynamically
allocated like malloc()
Stack Area: store the return address, dynamic variables & local variables declared inside the
function, size is determined only during the runtime
Static data: holds the global data and any other data that could be determined at compile time.
There are three different storage allocation strategies based on this division of runtime storage.
The strategies are:
1. Static allocation: the static allocation is for all the data objects at compile time.
2. Stack allocation: in the stack is used to manage the runtime storage.
3. Heap allocation: in heap allocation the heap is used to manage the dynamic memory
allocation.
Static Allocation
The size of data objects is known at compile time. The names of these objects are bound to
storage at compile time only and such an allocation of data objects is done by static time.
The binding of name with the amount of memory allocated do not change at runtime. Hence
the name of this allocation is static allocation.
In static the compiler determine the storage required by each data object, then compiler find
the addresses of these data in the activation record.
At compile time it fills the addresses at which the target code can find the data operates on it.
FORTRAN uses the static allocation strategy.
Stack Allocation
Stack allocation strategy is in which the storage is organized as stack. This stack is also
called control stack.
When Activation begins the activation records are pushed on to the stack when it completes
activation records are popped off from the stack.
The local data is stored in the activation record. The data structure is can be created
dynamically for stack allocation.
Heap Allocation
The heap allocation allocates the continuous block of memory when required for storage of the
activation records or other data objects. This allocated memory can be de-allocated when
activation ends. This de-allocation space can be further re-used by heap manager.
Temporaries – It hold temporary values, such as the result of mathematical calculation, a buffer
value or so on.
Local data – It belongs to the procedure where the control is currently located.
Saved machine status- It provides information about the state of a machine just before the point
where the procedure is called.
Access link – It is used to locate remotely available data. This field is optional. Control link – It
points to the activation record of the procedure which called it, ie the caller. This field is
optional. This link is also known as dynamic link.
Return value – It holds any valued returned by the called procedure. These values can also be
placed in a register depending on the requirements.
Actual parameters – These are used by the calling procedures.
Heap Management
Heap is the unused memory space available for allocation dynamically.
It is used for data that lives indefinitely, and is freed only explicitly.
The existence of such data is independent of the procedure that created it.
Heap storage allocation supports the recursion process
Memory manager is used to keep account of the free space available in the heap area. Its functions
include,
1. Allocation: The procedure allocated in the storage during the execution.
2. De-allocation: The procedure leaves the storage after completion of the execution.
The properties of an efficient memory manager include:
a. space efficiency
b. program efficiency
c. low overhead
CODE OPTIMIZATION
The code produced by the straight forward compiling algorithms can often be made to run faster
or take less space, or both. This improvement is achieved by program transformations that are
traditionally called optimizations. Compilers that apply code- improving transformations are
called optimizing compilers.
Optimizations are classified into two categories. They are
Machine independent optimizations:
Machine independent optimizations are program transformations that improve the target code
with-out taking into consideration any properties of the target machine.
Machine dependent optimizations:
Machine dependent optimizations are based on register allocation and utilization of special
machine instruction sequences.
The Principal Sources of Optimization
The following are the principle sources of optimization techniques or function preserving
transformations:
a) Elimination of common subexpression
b) Copy propagation
c) Dead code elimination
d) Constant folding
e) Loop optimizations
Elimination of common sub expression
• Common sub expressions can be either eliminated locally or globally.
• Local common sub expressions can be identified in a basic block.
• Hence first step to eliminate local common sub expressions is to construct a basic block.
• Then the common sub expressions in a basic block can be deleted by constructing a
directed acyclic graph (DAG).
• For example, x = a + b * ( a + b ) + c + d
The following is the basic block.
t1 = a + b
t2 = a + b
t3 = t1 * t2
t4 = t3 + c
t5 = t4 + d
x = t5
The local common sub expression in the above basic block are t1 = a + b t2 = a + b
Hence these local common sub expressions can be eliminated. The block obtained after
eliminating local common sub expression is shown below.
a:=b+c
b:=a-d
c:=b+c
d:=a-d
In the above expression, the second and forth expression computed the same expression. So the
block can be transformed as follows:
a:=b+c
b:=a-d
c:=b+c
d:=b
Dead-code elimination
o It is possible that a program contains a large amount of dead code.
o This can be caused when once declared and defined once and forget to remove them in
this case they serve no purpose.
o Suppose the statement x:= y + z appears in a block and x is dead symbol that means it
will never subsequently used. Then without changing the value of the basic block you can
safely remove this statement.
Renaming temporary variables
A statement t:= b + c can be changed to u:= b + c where t is a temporary variable and u is a new
temporary variable. All the instance of t can be replaced with the u without changing the basic
block value.
Interchange of statement
Suppose a block has the following two adjacent statements:
t1 : = b + c
t2 : = x + y
These two statements can be interchanged without affecting the value of block when value of t1
does not affect the value of t2.
2. Algebraic Transformations
In the algebraic transformation, we can change the set of expression into an algebraically
equivalent set. Thus the expression x:= x + 0 or x:= x *1 can be eliminated from a basic block
without changing the set of expression.
Peephole Optimization
Peephole optimization is simple but effective method used to locally improve the target code
by examining a short sequence of target instructions known as peephole and then replace these
instructions by a shorter and/or faster sequence of instructions whenever required.
The following are peephole optimization techniques:
1. Elimination of redundant instructions.
2. Optimization of flow of control or elimination of unreachable code.
3. Algebraic simplifications.
4. Strength reduction.
Elimination of redundant instructions:-
o This includes elimination of redundant load and store instructions.
o For example, MOV R1 A
MOV A R1
• Here first instruction is storing the value of A into register R1 and second instruction is
loading R1 value into A.
• These two instructions are redundant so eliminate instruction (2) because whenever
instruction (2) is executed after (1), it is ensured that the register R1 contains A value.
Optimization of flow of control or elimination of unreachable code:-
• An unlabeled instruction that immediately follows an unconditional jump can be
removed.
• For example, i = j if k = 2 goto L1 goto L2 L1: k is good L2:
Here L1 immediately follows unconditional jump statement goto L2. Then the code after
elimination of unreachable code is i = j if k ≠ 2 goto L2 k is good
L2:
Algebraic simplifications:-
• Algebraic identities that occur frequently and which is worth considering them can be
simplified.
• For example, X = X * 1 or X = 0 + X is often produced by straight forwards intermediate
code generation algorithms. Hence they can be eliminated easily through peephole
optimization.
Strength reduction:-
• Replace expensive statements by a cheaper one.
For example, X2 is expensive operation. Hence replace this by X * X which is cheaper one.
Flow graphs
• Flow graphs are used to represent the basic blocks and their relationship by a directed graph.
• There exists an edge from block 1 to block2 if it is possible for the first instruction in block2
to immediately flow to the last instruction in block1.
For example, Let us write the flow graph for the following basic blocks.
It is a flow sensitive (sensitive to the control flow in a function) and Intra-procedural analysis
Data flow analysis abstraction:
For each point in the program, combines information of all the instances of the same program
point.
Reaching Definitions
• Every assignment is a definition
A definition d reaches a point p if there exists path from the point immediately following d to p
such that d is not killed (overwritten) along that path.
Data Flow Properties
Available Expression – A expression is said to be available at a program point x if along paths
its reaching to x. A Expression is available at its evaluation point.
An expression a+b is said to be available if none of the operands gets modified before their
use.
Example:
Advantage:
It is used to eliminate common sub expressions.
Advantage
It is used in constant and variable propagation.
Live variable – A variable is said to be live at some point p if from p to end the variable is
used before it is redefined else it becomes dead.
Example: