1.5 KiB
Code Generation 2
Stack Machine
Consider two instructions
push iadd i
It is not efficient because all stack is considered as memory (which is slower than register).
Utilizing Register Files
Keep the top of the stack in a register, so add requires only a single memory access.
acc <- ipush accpopadd
Code Generation From Stack Machine
Assume that stack grows towards lower addresses.
MIPS
32 regs
$sp, $a0, $t1
lwaddswaddilimv
Converting Stack to MIPS ISA
acc <- ili $a0 i
Optimizing
no
Branch
beq $1 $2 lbl
b lbl
Function
At Caller Side:
- saves the
$fpto the stack - saves the actual params in reverse order
- saves the return address to
$ra
At Callee Side:
- set
$fpto$sp - the callee saves the return address
- ...
Temp Var
Many various intermediate vars should be stored in the AR. But compiler can statically know how many temporary variables there are.
Let NT(e) is defined recursively by:
NT(e1 + e2) = \max (NT(e1), NT(e2) + 1)
for example:
CG using NT
add new args to the cgen(e, nt)
reduce number of decrease $sp (addi $sp $sp -4)
Intermediate Representation (IR)
Before: Each Languages need respective, different Optimizer.
Now: Common IR optimizer.
IR is language-independent and machine-independent optimization.
High-Level Assembly
It uses unlimited number of registers. It uses assembly-like control structures (jmp and lbl). opcodes but some are higher level
igen(e, t)