Note: This is an outline of what I intend to say on the lecture.
It is not a definition of the course content,
and it does not replace the textbook.
Today:
Some rests from lecture 11 about intermediate code generation (ASU 8.2).
Code generation.
ASU 9.1-9.4, 9.12. (KP chapter 7.)
8. Intermediate code generation
...
8.2 Declarations
Declarations in a procedure
When you find a declaration of a variable, put it in the symbol table.
Symbol table interface: enter_variable(name, type, offset), maybe width
Keep track of offset!
Keeping track of scope information
New symbol table interface:
- make_table(previous_table)
- enter_variable(table, name, type, offset)
- add_width(table, width)
- enter_procedure(table, name, newtable)
ASU Fig 8.12. Symbol tables during compilation of the program in ASU Fig 7.22:
During processing, keep a stack of symbol tables:
-
When the compiler enters a procedure:
make a new symbol table, and push it on the stack
-
When the compiler leaves a procedure:
pop the symbol table from the stack, but don't destroy it!
Fields names in records (or members in a class!)
Use a separate symbol table for each record type:
stp = make_table(nil); // when entering the declaration
Then use it just as with variables declared in a procedure:
enter_variable(stp, name, type, offset)
8.3 - 8.7
Skip the rest of chapter 8.
9. Code generation
Input: intermediate code, often three-address code,
but can also be e. g. syntax trees.
Several types of target code:
- Not common:
Absolute machine code (no linking, no libraries, no separate compilation)
- Relocatable machine code
- Assembly language
What the code generator does:
- Memory management = where to put the variables = mapping source-program names to memory addresses (Oh, and labels too!)
- Instruction choice
- Register allocation
From KP page 146, about code generation:
9.1 Issues in the design of a code generator
Instruction selection
Example 1, a three-address instruction:
Use a template:
MOV y,R0 -- Load y into register R0
ADD z,R0 -- Add z to register R0
MOV R0,x -- Store R0 into x
|
Example 2, more three-address instructions:
Using the same template:
MOV b,R0
ADD c,R0
MOV R0,a
MOV a,R0
ADD e,R0
MOV R0,d
|
Unneccessary instruction(s).
Example 3, a three-address instruction:
Use a template:
MOV a,R0
ADD #1,R0 -- Add "immediate" constant 1 to R0
MOV R0,a
|
Better:
9.2 The target machine
Several types of target machines:
- Stack machines. Often a virtual machine, no registers.
- Register machines. Real hardware. Two types:
- RISC (ex: Sparc)
- CISC (ex: Pentium)
From KP page 143, about register machines:
9.3 Run-time storage management
Activation records, as in
lecture 8.
Here they show the actual target-machine instructions to:
-
allocate activation records on the stack by incrementing the stack pointer register
-
store the return address in the activation record
-
jump to the procedure, using a direct goto
(ex: GOTO 300)
-
return, using an indirect goto to the address saved in the activation record
(ex: GOTO *0(SP))
9.4 Basic blocks and flow graphs
Basic blocks are used for optimization.
Example: Finding "heavily trafficed" parts of the program,
and use registers for variables used there.
Terms:
From KP page 119:
Terms:
- define = set the value!
- use
- live
Transformations on basic blocks:
- Common subexpression elimination
a = b + c;
b = a - d;
c = b + c;
d = a - d;
|
|
->
|
a = b + c;
b = a - d;
c = b + c;
d = b;
|
|
- Dead-code elimination
if x is dead!
- Renaming temporary variables
normal-form block: never re-use temporary variables
- Interchange of statements
- Algebraic transformations
a = a + 0;
b = b * 1;
c = d ** 2;
|
|
->
|
|
Terms:
- Loop = "strongly connected", one entry point
- Inner loop = no other loops inside it
9.5 - 9.12
Skip the rest of chapter 9.
Thomas Padron-McCarthy
(Thomas.Padron-McCarthy@tech.oru.se)
February 26, 2003