0% found this document useful (0 votes)
5 views57 pages

Unit IV

The document discusses run-time storage organization, including static, stack, and heap allocation strategies, and their advantages and disadvantages. It also covers activation records, access to nonlocal names, and various code optimization techniques such as dead code elimination and loop optimization. Additionally, it explains the importance of maintaining semantic equivalence while improving execution efficiency in programs.

Uploaded by

1432ultragamer
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)
5 views57 pages

Unit IV

The document discusses run-time storage organization, including static, stack, and heap allocation strategies, and their advantages and disadvantages. It also covers activation records, access to nonlocal names, and various code optimization techniques such as dead code elimination and loop optimization. Additionally, it explains the importance of maintaining semantic equivalence while improving execution efficiency in programs.

Uploaded by

1432ultragamer
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/ 57

Run-time Storage

Storage organization, storage allocation strategies, scope access to non local


names.
Run-Time Storage Organization
Code
Memory locations for code are
determined at compile time.

Static Data Locations of static data can also be


determined at compile time.
Stack
Data objects allocated at run-time.
(Activation Records)

Other dynamically allocated data


Heap
objects at run-time. (For example,
malloc area in C).
Run-Time Storage Organization
• When the target program executes then it runs in its own logical address space in which the
value of each program has a location.
• The logical address space is shared among the compiler, operating system and target
machine for management and organization. The operating system is used to map the logical
address into physical address which is usually spread throughout the memory.
• Runtime storage comes into blocks, where a byte is used to show the smallest unit of
addressable memory. Using the four bytes a machine word can form. Object of multibyte is
stored in consecutive bytes and gives the first byte address.
• Run-time storage can be subdivide to hold the different components of an executing
program:
1. Generated executable code
2. Static data objects
3. Dynamic data-object- heap
4. Automatic data objects- stack

3
Activation Records
• Information needed by a single execution of a procedure is managed using a
contiguous block of storage called activation record.
• An activation record is allocated when a procedure is entered, and it is de-
allocated when that procedure exited.
• Size of each field can be determined at compile time (Although actual
location of the activation record is determined at run-time).
– Except that if the procedure has a local variable and its size depends on a
parameter, its size is determined at the run time.

4
Activation Records (cont.)
The returned value of the called procedure is returned
return value in this field to the calling procedure. In practice, we may
use a machine register for the return value.
actual parameters The field for actual parameters is used by the calling
procedure to supply parameters to the called procedure.
optional control link The optional control link points to the activation record
of the caller.
optional access link
The optional access link is used to refer to nonlocal data
held in other activation records.
saved machine status
The field for saved machine status holds information about
the state of the machine before the procedure is called.
local data
The field of local data holds data that local to an execution
temporaries of a procedure..
Temporay variables is stored in the field of temporaries.

5
Storage Allocation Strategies

• There are mainly three types of Storage Allocation Strategies:


1. Static Allocation
2. Stack Allocation
3. Heap Allocation

6
Storage Allocation Strategies
1. Static Allocation
• Static allocation lays out or assigns the storage for all the data objects at the compile time. In static
allocation names are bound to storage. The address of these identifiers will be the same throughout. The
memory will be allocated in a static location once it is created at compile time. C and C++ use static
allocation.
• Ex:
int number = 1;
static int digit = 1;
Advantages of Static Allocation
• It is easy to understand.
• The memory is allocated once only at compile time and remains the same throughout the program completion.
• Memory allocation is done before the program starts taking memory only on compile time.
Disadvantages of Static Allocation
• Not highly scalable.
• Static storage allocation is not very efficient.
• The size of the data must be known at the compile time

7
Storage Allocation Strategies

2. Stack allocation is used for local variables and function calls. Memory is allocated when a function is
invoked, and the corresponding memory is released when the function exits. It uses a LIFO (Last In, First Out)
structure, with each function call creating a new stack frame.
• Allocation is done at runtime, but the size of the data is known at compile time.
• Memory for local variables and function parameters is stored in a stack frame.
• Stack grows and shrinks dynamically with function calls.
• Ex:
void sum(int a, int b){int ans = a+b;cout<<ans;}
// when we call the sum function in the example above,
memory will be allotted for the variable ans
Advantages:
• Automatic memory management (memory is freed when functions return).
• Efficient in terms of allocation and deallocation.
Disadvantages:
• Limited in size, as stack space is finite.
• Does not allow allocation of large or dynamic-sized data structures.
Storage Allocation Strategies
3. Heap Allocation
• Heap allocation is used for dynamically allocated memory, where the size and lifetime of the memory are
not known until runtime. Memory is allocated on the heap and can be freed when it is no longer needed.
• Dynamic memory allocation and deallocation.
• Allows allocation of memory whose size may not be known at compile time.
• Managed manually or through garbage collection.
Example: Memory allocated using malloc() in C, or new in C++/Java.

Advantages:
• Flexible, as it allows dynamic memory allocation and resizing.
• Can allocate large data structures that do not fit in the stack.
Disadvantages:
• Slower compared to stack allocation due to the need for managing memory fragmentation.
• Potential for memory leaks if not deallocated properly.

9
Access to Nonlocal Names
• Scope rules of a language determine the treatment of references to nonlocal names.
• Scope Rules:
– Lexical Scope (Static Scope)
• Determines the declaration that applies to a name by examining the program text
alone at compile-time.
• Most-closely nested rule is used.
• Pascal, C, ..
– Dynamic Scope
• Determines the declaration that applies to a name at run-time.
• Lisp, APL, ...

10
Lexical Scope
• The scope of a declaration in a block-structured language is given by the mostly closed
rule.
• Each procedure (block) will have its own activation record.
– procedure
– begin-end blocks
• (treated same as procedure without creating most part of its activation record)

• A procedure may access to a nonlocal name using:


– access links in activation records, or
– displays (an efficient way to access to nonlocal names)

11
Access Links
• Access Links in one activation record are links that are used to refer to the non-local
data in other activation records and provide access to it. A chain of access links is
formed on the top of the stack and represents the program's scope or static structure.

12
Displays
• One of the issues of the access links is that if there are many nested calls of functions,
there will be a very long chain of access links that we must follow to reach the non-local
data we need. To solve this, we make the use of displays.
• Displays are auxiliary arrays that contain a pointer for every nesting depth. At any point,
d[i] is the pointer to the activation record which is the highest in the stack for a
procedure which is at depth i.

We assume that each function f1(),f2(), f3(), and f4() lies


at different depths. d[1] holds the pointer to the
activation record for f1(), the only one for that depth.
Similarly, there are pointers for each depth.

13
Code Optimization

1
Motivation

• To produce target programs with high


execution efficiency.

• Constraints:
 Maintain semantic equivalence with source
program.

 Improve a program without changing the


algorithm. 2
Principal Sources of
Optimization

3
Compile-Time Evaluation
◼ Expressions whose values can be pre-
computed at the compilation time
◼ Two ways:
 Constant folding
 Constant propagation

4
Compile-Time Evaluation
◼ Constant folding: Evaluation of an
expression with constant operands to
replace the expression with single value
◼ Example:
area := (22.0/7.0) * r ** 2

area := 3.14286 * r ** 2

5
Compile-Time Evaluation
◼ Constant Propagation: Replace a
variable with constant which has been
assigned to it earlier.
◼ Example:
pi := 3.14286
area = pi * r ** 2
area = 3.14286 * r ** 2

6
Common Sub-expression
Evaluation
◼ Identify common sub-expression present in different
expression, compute once, and use the result in all the
places.
 The definition of the variables involved should not change

Example:
a := b * c temp := b * c
… a := temp
… …
x := b * c + 5 x := temp + 5

7
Common Subexpression Elimination
t1 = a + b
c=a+b c = t1
d=m*n t2 = m * n
e=b+d d = t2
f=a+b t3 = b + d
g=-b e = t3
h=b+a f = t1
a=j+a g = -b
k=m*n h = t1 /* commutative */
j=b+d a=j+a
a=-b k = t2
if m * n go to L j = t3
a = -b
if t2 go to L

the table contains quintuples:


(pos, opd1, opr, opd2, tmp)
8
Code Motion
◼ Moving code from one part of the program
to other without modifying the algorithm
 Reduce size of the program
 Reduce execution frequency of the code
subjected to movement

9
Code Motion
1. Code Space reduction: Similar to common
sub-expression elimination but with the
objective to reduce code size.
Example: Code hoisting
temp : = x ** 2
if (a< b) then if (a< b) then
z := x ** 2 z := temp
else else
y := x ** 2 + 10 y := temp + 10

“x ** 2“ is computed once in both cases, but the code size in the


second case reduces.
10
Code Motion
2 Execution frequency reduction: reduce execution
frequency of partially available expressions
(expressions available atleast in one path)

Example:
if (a<b) then if (a<b) then
z=x*2 temp = x * 2
z = temp
else else
y = 10 y = 10
temp = x * 2
g=x*2 g = temp;

11
Code Motion
◼Move expression out of a loop if the
evaluation does not change inside the
loop.
Example:
while ( i < (max-2) ) …
Equivalent to:
t := max - 2
while ( i < t ) …

12
Strength Reduction
◼ Replacement of an operator with a less costly one.
Example:
temp = 5;
for i=1 to 10 do for i=1 to 10 do
… …
x=i*5 x = temp
… …
temp = temp + 5
end end

13
Dead Code Elimination
◼ Dead Code are portion of the program which will
not be executed in any path of the program.
 Can be removed
◼ Examples:
 No control flows into a basic block
 A variable is dead at a point -> its value is not used
anywhere in the program
 An assignment is dead -> assignment assigns a value
to a dead variable

14
Dead Code Elimination

i=0
if(i==1)// dead code since the condition will never be satisfied
{
a=x+5;
}

15
Copy Propagation
◼ f := g are called copy statements or copies
◼ Use of g for f, whenever possible after copy
statement

Example:
x[i] = a; x[i] = a;
sum = x[i] + a; sum = a + a;

◼ May not appear to be code improvement, but


opens up scope for other optimizations.

16
Loop Optimization

• Loop invariant method


• Strength reduction
• Loop Unrolling
• Loop Fusion
Loop-invariant method
(Hoisting)

while(i<=max-1) n=max-1;
{ while(i<=n)
sum=sum+a[i]; {
i=i+1; sum=sum+a[i];
} i=i+1;
}
Loop-invariant method
(Hoisting)
Strength reduction

➢ Strength of certain operators are higher than others.


Ex * higher than +

for(i=1;i<=50;i++) temp=7;
{ for(i=1;i<=50;i++)
count = i * 7; {
} count = temp;
temp = temp + 7;
}
Loop Unrolling

• Some loops have such a small body that most of the time is
spent incrementing the loop-counter variable and testing
the loop-exit condition.

• We can make these loops more efficient by unrolling them,


putting two or more copies of the loop body in a row.

for (i = 0; i < 100; i += 2)


for (i = 0; i < 100; i++) {
g (); g ();
g ();
}
Loop Unrolling
Loop Fusion

➢ Some adjacent loops can be fused into one loop to reduce loop
overhead and improve run-time performance.

for (i = 0; i < 300; i++)


for (i = 0; i < 300; i++)
{
a[i] = a[i] + 3;
a[i] = a[i] + 3;
b[i] = b[i] + 4;
for (i = 0; i < 300; i++)
}
b[i] = b[i] + 4;

➢ Note:
▪ Loop fusion is not commonly supported by C compilers.

▪ Although loop fusion reduces loop overhead, it does not always improve
run-time performance, and may reduce run-time performance.
Optimization of Basic Blocks
 Partition the intermediate code into basic blocks.

 Basic blocks are maximal sequences of consecutive intermediate


code with

 The flow of control can only enter the basic block through the
first instruction in the block

 Control will the block without halting or branching, except


possibly at the last instruction in the block.
Examples:
Example:

(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)
Algorithm for Partitioning into Basic
Blocks
 Determine the set of leaders, the first statements of basic blocks
 The first statement is a leader

 Any statement which is the target of a conditional or


unconditional goto is a leader

 Any statement which immediately follows a conditional or


unconditional goto is a leader.

 A leader and all statements which follow it upto but not including
the next leader (or the end of the procedure), is the basic block
corresponding to that leader.
Algorithm for Partitioning into Basic
Blocks (Example)
1) r = 1 There are six basic blocks for the above-
2) c = 1 given code, which are:
3) t1 = 10 * r •B1 for statement 1
4) t2 = t1 + c •B2 for statement 2
5) t3 = 8 * t2 •B3 for statements 3-9
6) t4 = t3 - 88 •B4 for statements 10-11
7) a[t4] = 0.0 •B5 for statement 12
8) c = c + 1 •B6 for statements 13-17.
9) if c <= 10 goto (3)
10) r = r + 1
11) if r <= 10 goto (2)
12) r = 1
13) t5 = c - 1
14) t6 = 88 * t5
15) a[t6] = 1.0
16) r = r + 1
17) if r <= 10 goto (13)
Example of a Control 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)
Basic Blocks & Flow Graphs

i=1
L3: if i > 1 goto L1
a=2
b=3
goto L2
L1: a = 1
b=4
L2: c = a + b
i=i+1
goto L3
Optimizing of basic blocks

• The optimization can be applied on source based scope


of the operation.

• Local Scope : Optimization inside a block of statements.

• Global Scope : Optimization throughout the program or


within some functions.
• Performed using data flow analysis
Local Optimizations

• Algebraic Transformations.

• Local common sub expression elimination.

• Dead code (instructions that compute a value that is


never used) elimination.

• Reordering statements that do not depend on one


another.

• Renaming of Temporary variables


Algebraic Simplification

Some statements can be deleted


x := x + 0
x := x * 1
Some statements can be simplified
 x := x * 0 x := 0
 y := y ** 2 y := y * y
 x := x * 8 x := x << 3
(on some machines << is faster than *; but not on all!)
 x := x * 15 t := x << 4; x := t – x
 a = b*c + b*d; a=b*(c+d)

You might also like