0% found this document useful (0 votes)
6 views54 pages

CSE-UNIT-5

The document covers runtime storage organization, detailing static and dynamic storage allocation, including stack and heap management. It explains activation records, access links, procedure calls, and the role of code generation in compilers, including instruction selection and register allocation. Additionally, it discusses object code forms and strategies for effective register allocation and assignment in compiler design.

Uploaded by

mohammadrafi7093
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)
6 views54 pages

CSE-UNIT-5

The document covers runtime storage organization, detailing static and dynamic storage allocation, including stack and heap management. It explains activation records, access links, procedure calls, and the role of code generation in compilers, including instruction selection and register allocation. Additionally, it discusses object code forms and strategies for effective register allocation and assignment in compiler design.

Uploaded by

mohammadrafi7093
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/ 54

Unit-5

Syllabus
Run time storage
• The compiler demands for a block of memory to operating system. The
compiler utilizes this block of memory for running/executing the
compiled program. This block of memory is called Run-time storage.
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 organization
Contd.,
• 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
Static vs Dynamic Storage Allocation
Static:
1. It is also called compile-time allocation
2. The decision is made based on the contents of the program; doesn’t depend
on the output.
3. In static allocation, the compiler can determine the amount of storage
required by each data object. Therefore, it becomes easy for a compiler to
find the addresses of these data in the activation record.
4. At compile time the compiler can fill the addresses at which the target code
can find the data it operates on.
Ex: code and static area
Limitations of static allocation
• The static allocation can be done only if the size of data object is known
at compile time.
• Recursive procedures are not supported by this type of allocation.
• The data structures can not be created dynamically.
• The static allocation can not manage the allocation of memory at tun
time.
Contd.,
Dynamic :
It is also known as run-time allocation
Can be decided when the program is running
Ex: stack and head areas.
Stack allocation of space
• Almost all compilers for languages that use procedure, functions, or
methods manage their run-time memory as a stack.
• Whenever a procedure is called, the local variable’s space is pushed
into a stack and popped off from the stack when the procedure
terminates.
Heap Storage
• The most flexible allocation strategy is Heap Allocation.
• Memory allocation and deallocation can occur at any time and in any
location, depending on the user's needs.
• Heap allocation is a technique for dynamically allocating memory to variables
and claiming it back when the variables are no longer used.
• It supports the recursion process.
• If the values of nonlocal variables must be retained even after the activation
record then such a retaining is not possible by stack allocation.
Contd.,
Activation Trees:
• A program is a set of instruction with some operation associated with it.
• The sequence in which the procedure executes is known as activation.
• We also assume that a procedure executes in a sequential manner, and this
sequence is easily represented by a tree known as the activation tree.
Activation tree: activation record
• 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.
General activation record
Activation record components explanation
• 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.
Access links for procedure parameters

• When a procedure is passed to another as a parameter, the calling


procedure does not have any information about the called procedure such
as context of use and also how to set up the access link with its AR.
• 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.
Access links example
Procedure Calls
• The procedure is such an important and frequently used programming
construct that it is imperative for a compiler to generate good code for
procedure calls and returns.

• The run-time routines that handle procedure argument passing, calls and
returns are part of the run-time support package.
SDT for procedure calls
Calling sequences
• When a procedure call occurs then space is allocated for activation
record.
• Evaluate the argument of the called procedure.
• Establish the environment pointers to enable the called procedure to
access data in enclosing blocks.
• Save the state of the calling procedure so that it can resume execution
after the call.
• Also save the return address. It is the address of the location to which
the called routine must transfer after it is finished.
• Finally generate a jump to the beginning of the code for the called
procedure.
Nesting depth
• The nesting depth is the number of statement blocks that are
nested due to the use of control structures (branches, loops).
• The procedure of calculating nesting depth as follows:
The main programs nesting depth is “1”
when a new procedure begins, add ‘1” to the nesting depth
each time
when we exit from a nested procedure, subtract “1” from
depth each time.
Nesting depth example
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 of pointers to activation records, indexed by lexical
nesting depth. The number of display elements can be known at compiler time
• Displays are maintained in registers
• It is stored in static space
Displays- diagrammatic representation
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.
Contd.,
• In the above figure, 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.

• Now if a procedure requires access to data from another procedure, let's say
f2() wants to access some data from f1(), then runtime only searches in
activations from d[i] where i is the nesting depth of f1() and follow the
pointer.
Code generator
• Code generator is used to produce the target code for three-
address statements. It uses registers to store the operands of the
three address statement.
• The code generated by the compiler is an object code of some
lower-level programming language, for example, assembly
language.
Contd.,
Contd.,
Tasks of code generator/ Design issues
The main task of code generator is to produce correct code

• Instruction selection
• Register allocation
• Instruction ordering
1. Instruction selection
• The job of instruction selector is to do a good job overall of choosing which
instructions to implement which operator in the low-level intermediate
representation with.
• Ex:
2. Register Allocation
• Register can be accessed faster than memory.
• The instructions involving operands in register are shorter and
faster than those involving in memory operand.
The following sub problems arise when we use registers:
• Register allocation: In register allocation, we select the set of
variables that will reside in register.
• Register assignment: In Register assignment, we pick the
register that contains variable.
Example
3. Evaluation order
• Order of evaluation of the nodes in an expression DAG or expression
tree can affect the number of registers required to evaluate the
expression.
• Some computation orders require fewer registers to hold
intermediate results than others.
A simple code generator
• Code generation is a process in which a compiler ‘code generator’ converts the
source code into a form that can be executed by a machine.
• The main job is to convert an intermediate representation into a linear
sequence of machine instructions.
• Code generation phase includes: instruction selection
instruction scheduling
register allocation
• A code generator is a compiler that translates the intermediate
representation of the source program into the target program.

• In other words, a code generator translates an abstract syntax tree


into machine-dependent executable code.
Contd.,
• Major issues during code generation lie in deciding the usage of
registers. The following are the four principal ways of registers usage:
1. some/ all the operands of an operation must be in registers in order
to perform an operation
2. Registers are used to hold temporary results of a sub expression
3. Registers are used to hold ‘ global values’
4. Registers are used in run-time storage management.
Contd.,
• The machine instructions are:
LD reg,mem
ST mem,reg
OP reg,reg,reg
Contd.,
2 data structures are used:
• Register Descriptor
• Address Descriptor
Contd.,
1. Register Descriptor: (Initially all registers are empty)
• Register descriptors are data structures that store information about
the registers used in the program.
• This includes the registration number and its name, along with its
type.
• The compiler uses this information when generating machine code
for your program, so it’s important to keep it up-to-date while
writing code!
• The compiler uses the register file to determine what values will be
available for use in your program.
• This is done by walking through each of the registers and
determining if they contain valid data or not.
• If there’s nothing in a register, then it can be used for other
purposes!
Contd.,
2. Address Descriptor:
• An address descriptor is used to represent the memory locations used by a
program.
• Address descriptors are created by the getReg function, which returns a
structure containing information about how to access memory.
• Address descriptors can be created for any instruction in your program’s
code and stored in registers or on the stack;
• however, only one instance of an address descriptor will exist at any given
time (unless another thread is executing).
A code generation Algorithm
• The code generation algorithm is the core of the compiler.
• It sets up register and address descriptors, then generates machine
instructions that give you CPU-level control over your program.
• The algorithm is split into four parts:
1. Register descriptor set-up
2. Basic block generation
3. Instruction generation for operations on registers (e.g., addition)
4. Ending the basic block with a jump statement or return command.
Contd.,
• 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 getreg() to determine the location L where the result


of the computation y op z should be stored.

2. Consult the address descriptor for 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.
Contd.,
3. Check any one of the location of z. 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.
Contd.,
• 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:
Contd.,
Object code forms
• In compiler design, object code is the output of the compilation process.
• It is generated from the source code by the compiler and represents the
low-level instructions that can be executed directly by the computer's
processor.
Contd.,
There are two main forms of object code:
1. Relocatable Object Code:
• This form of object code is not yet linked to any other code or libraries.
• It contains instructions that can be relocated to any memory location by the linker,
which is a program that combines multiple object files into a single executable file.
2. Executable Object Code:
• This form of object code is fully linked and ready to be executed by the computer's
processor.
• It contains all the necessary instructions and data to run the program, as well as any
required library code that was linked in during the compilation process.
Register Allocation and Assignment
• Instruction involving only register operands are shorter and faster than those
involving memory operands.
• This means proper use of register help in generating the good code.
• One approach to register allocation and assignment is to assign specific value
in an object program to certain registers.
• This simplifies the design of a compiler.
Contd.,
Strategies used in register and assignment
1.Global register allocation
2.Usage counts
3.Register assignment for outer loops
4.Register allocation by graph coloring
1. Global register allocation
• Allocation of variables to specific registers that is consistent across the block
boundaries is called global register allocation.
• The global register allocation has a strategy of storing the most frequently used
variables in fixed registers throughout the loop
• Another strategy is to assign some fixed number of global registers to hold the
most active value in each inner loop,
• The registers not already allocated may be used to hold values local to one
block.

Ex: in C, the programmer can do the register allocation by using register


declaration.
2. Usage counts
• The usage count is the count for the use of some variable ‘x’ in some
register used in any basic block.
• The usage count gives the idea about how many units of cost can be
saved by selecting a specific variable for global register allocation
3. Register assignment for outer loops
• Having assigned registers and generated code for inner loops, we may
apply the same idea to progressively loops.
• If an outer loop l1, contains an inner loop L2, the names allocated
registers in L2 need not be allocated registers in L1-L2.
• However, if name ‘x’ is allocated a register in loop L1 but not L2, we
must store ‘x’ on entrance to L2 and load ‘x’ if we leave L2, and enter
a block of L1-L2.
• Similarly, if we choose to allocate ‘x’ a register in L2, but not L1 must
load ‘x’ on entrance to L2 store ‘x’ on exit from L2.
4. Register allocation by graph coloring
• A register is needed for computation but all available registers are in
use, the contents of one of the used registers must be stored into a
memory location in order to free up the register.

• Graph coloring is a simple systematic technique for allocating


registers and managing register spills.

• Graph coloring is a systematic technique for allocating and managing


register spills.
• 2 passes are used
Passes in graph coloring
• In the first pass, the target machine instruction is selected and the names
used in the intermediate code become names of registers and three
address statements become machine instructions
• In the second pass, for each procedure a register interference graph is
constructed in which the nodes are symbolic registers and edge connects
two nodes if one is live at a point where the other is defined
• Color the register-interference graph using k-colors, where k is the number
of assignable registers.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy