A code generator is an important phase of a compiler that converts intermediate code, such as three-address code, into target code that can be executed by the target machine. It selects suitable machine instructions and uses registers and memory locations to represent the operations.
In this chapter, you will learn what a code generator is, how it translates three-address statements into target code, and how register and address descriptors are used during code generation.
A code generator is a compiler component that produces target code from an intermediate representation of the source program.
The target code may be assembly code, machine code, or another low-level representation depending on the compiler and target machine.
The code generator must consider factors such as:
For example, consider the following three-address statement:
x := y + z
A possible sequence of target instructions is:
MOV R0, y ADD R0, z MOV x, R0 Here, R0 is used to hold the intermediate result of y + z.
During code generation, the compiler maintains information about where values are currently stored. Two important data structures used for this purpose are register descriptors and address descriptors.
A register descriptor keeps track of the value currently stored in each machine register.
For example:
Register Contents R0 y + z R1 empty R2 x
Initially, the registers may be considered empty. As instructions are generated, the descriptor is updated to reflect the values stored in each register.
An address descriptor keeps track of the locations where the current value of a name can be found at runtime.
For example, if the value of x is currently available in register R0 and memory location x, the address descriptor can represent:
x → {R0, memory[x]}The compiler uses this information to avoid unnecessary loads and stores.
The algorithm takes a sequence of three-address statements as input. For each three address statement of the form a:= b op c perform the various actions. These are as follows:
The assignment statement d:= (a-b) + (a-c) + (a-c) can be translated into the following sequence of three address code:
Code sequence for the example is as follows:
| Statement | Code Generated | Register descriptor Register empty | Address descriptor |
|---|---|---|---|
| t:= a - b | MOV a, R0 SUB b, R0 | R0 contains t | t in R0 |
| u:= a - c | MOV a, R1 SUB c, R1 | R0 contains t R1 contains u | t in R0 u in R1 |
| v:= t + u | ADD R1, R0 | R0 contains v R1 contains u | u in R1 v in R1 |
| d:= v + u | ADD R1, R0 MOV R0, d | R0 contains d | d in R0 d in R0 and memory |
We request you to subscribe our newsletter for upcoming updates.