0% found this document useful (0 votes)
4 views

mod 4-5

Module 4 discusses the code generation process, emphasizing the importance of error-free input, various types of target programs, and memory management challenges. It covers instruction selection, register allocation, and the evaluation order's impact on efficiency, as well as run-time storage management techniques like static and stack allocation. Additionally, it highlights the advantages of intermediate code generation and introduces concepts like next use analysis for optimizing register allocation.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views

mod 4-5

Module 4 discusses the code generation process, emphasizing the importance of error-free input, various types of target programs, and memory management challenges. It covers instruction selection, register allocation, and the evaluation order's impact on efficiency, as well as run-time storage management techniques like static and stack allocation. Additionally, it highlights the advantages of intermediate code generation and introduces concepts like next use analysis for optimizing register allocation.
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 40

Module 4

1. Input to Code Generator


One key challenge here is that the input must be free from syntactic and semantic errors,
as the code generator assumes that proper type-checking and other error checks have
already been handled by the front-end. Handling the input correctly is crucial for
generating the correct target code.

2. Target Program
The target program is the final output of the code generator, which can be in the form
of absolute machine language, relocatable machine language, or assembly language.
Each type of output has its own set of challenges:
 Absolute Machine Language is easy to execute but lacks flexibility because it is
bound to specific memory locations.
 Relocatable Machine Language allows parts of the program to be moved around in
memory, making it suitable for linking multiple modules, but it requires a linking loader
and has some overhead.
 Assembly Language is symbolic and needs an additional step (an assembler) to
convert it into machine code, but it makes the code generation process easier.

3. Memory Management

Memory management in the code generation phase involves mapping variable names
to their corresponding memory locations. The code generator works closely with the
front-end to access the symbol table, where memory addresses for variables are stored.
A major challenge is ensuring that the code generator uses:
Memory efficiently

Avoids memory conflicts

Correctly handles dynamic memory allocation.

4. Instruction selection
Instruction selection is the process of choosing the most suitable machine instructions
to translate intermediate code into executable code. The goal is to optimize the
generated code by selecting instructions that are efficient and appropriate for the target
machine. If the right instructions are not selected, the resulting code can be inefficient
and slow. A code generator might need to decide between different ways of
implementing the same operation, such as using different addressing modes or
optimizing for processor-specific features.

5. Register Allocation
Efficient use of registers is important because registers are faster than memory, and
utilizing them effectively can significantly improve program performance. The
challenge lies in selecting the right variables to store in registers at different points in
the program.
Register allocation involves two stages:
1. Register Allocation: It is selecting which variables will reside in the registers at each
point in the program
2. Register Assignment: Assigning specific registers to those variables selected in
Register Allocation.
The difficulty arises in managing which variables are allocated to registers, especially
when the number of available registers is limited. Poor register allocation can lead to
spills, where data is temporarily stored in memory, causing slower performance.

6. Choosing the order of Allocation


The evaluation order refers to the sequence in which expressions are evaluated in the
generated code. This order can significantly affect the efficiency of the program. For
example, evaluating certain expressions first might require fewer registers or fewer
instructions. The challenge is to determine the optimal order in which to execute
operations so that the program requires fewer resources (like memory or registers) and
runs more efficiently. This is often a complex problem, as finding the best evaluation
order can be computationally expensive, and in some cases, it may require sophisticated
algorithms to find the optimal solution.

Target Machine
Instruction Cost
RUN-TIME STORAGE MANAGEMENT

The information which required during an execution of a procedure is kept in a block of storage
called an activation record. The activation record includes storage for names local to the
procedure.

We can describe address in the target code using the following ways:

1. Static allocation

2. Stack allocation

In static allocation, the position of an activation record is fixed in memory at compile time.

In the stack allocation, for each execution of a procedure a new activation record is pushed
onto the stack. When the activation ends then the record is popped.

For the run-time allocation and deallocation of activation records the following three-address
statements are associated:

1. Call

2. Return
3. Halt

4. Action, a placeholder for other statements

We assume that the run-time memory is divided into areas for:

1. Code

2. Static data

3. Stack

Static allocation:
1. Implementation of call statement:

The following code is needed to implement static allocation:

1. MOV #here + 20, callee.static_area /*it saves return address*/</p>

2. GOTO callee.code_area /* It transfers control to the target code for the called proc
edure*/

Where,

callee.static_area shows the address of the activation record.

callee.code_area shows the address of the first instruction for called procedure.

#here + 20 literal are used to return address of the instruction following GOTO.

2. Implementation of return statement:


The following code is needed to implement return from procedure callee:

1. GOTO * callee.static_area

It is used to transfer the control to the address that is saved at the beginning of the activation
record.

3. Implementation of action statement:

The ACTION instruction is used to implement action statement.

4. Implementation of halt statement:

The HALT statement is the final instruction that is used to return the control to the operating
system.

Stack allocation

Using the relative address, static allocation can become stack allocation for storage in
activation records.
In stack allocation, register is used to store the position of activation record so words in
activation records can be accessed as offsets from the value in this register.
The following code is needed to implement stack allocation:

1. Initialization of stack:

1. MOV #stackstart , SP /*initializes stack*/

2. HALT /*terminate execution*/

2. Implementation of Call statement:

1. ADD #caller.recordsize, SP/* increment stack pointer */

2. MOV #here + 16, *SP /*Save return address */


3. GOTO callee.code_area

Where,

caller.recordsize is the size of the activation record

#here + 16 is the address of the instruction following the GOTO

3. Implementation of Return statement:

1. GOTO *0 ( SP ) /*return to the caller */

2. SUB #caller.recordsize, SP /*decrement SP and restore to previous value */


Basic Block and Flow Control
Next Use
In compiler design, the next use information is a type of data flow analysis that can be used to
optimize the allocation of registers in a computer’s central processing unit (CPU). The goal of
next use analysis is to determine which variables in a program are needed in the immediate
future and should therefore be stored in a register for faster access, rather than in main memory.
A Simple Code Generator
Directed Acyclic Graph
Intermediate Code Generation
Advantages of Intermediate Code Generation

 Easier to Implement: Intermediate code generation can simplify the code generation
process by reducing the complexity of the input code, making it easier to implement.
 Facilitates Code Optimization: Intermediate code generation can enable the use of
various code optimization techniques, leading to improved performance and
efficiency of the generated code.

 Platform Independence: Intermediate code is platform-independent, meaning that it


can be translated into machine code or bytecode for any platform.

Syntax Directed Translation


SDT to build Syntax Tree

SDT for converting infix to postfix expression

SDT to produce three address code


Types of Three address statements
Boolean Expressions
Procedure Calls
MODULE 5
Loop Optimization
Global Data Flow Analysis
Usage Counts in Register Allocation
Source language issues
Storage Organization
Peephole Optimization

You might also like