Code Generation: - Intermediate Code Generation: - Code Optimization: - Final Code Generation
Code Generation: - Intermediate Code Generation: - Code Optimization: - Final Code Generation
Intermediate code generation: Abstract (machine independent) code. Code optimization: Transformations to the code to improve time/space performance. Final code generation: Emitting machine instructions.
Intermediate Code
Abstract code generated from AST Simplicity and Portability Machine independent code. Enables common optimizations on intermediate code. Machine-dependent code optimizations postponed to last phase.
Intermediate Forms
Stack machine code: Code for a postx stack machine. Two address code: Code of the form add r1 , r2 Three address code: Code of the form add src 1 , src 2 , dest Quadruples and Triples: Representations for three-address code.
Quadruples
Explicit representation of three-address code. Example: a := a + b * -c; Instr Operation Arg 1 Arg 2 Result (0) uminus c t1 (1) mult b t1 t2 (2) add a t2 t3 (3) move t3 a
Triples
Representation of three-address code with implicit destination argument. Example: a := a + b * -c; Instr Operation Arg 1 Arg 2 (0) uminus c (1) mult b (0) (2) add a (1) (3) move a (2)
Intermediate Forms
Choice depends on convenience of further processing Stack code is simplest to generate for expressions. Quadruples are most general, permitting most optimizations including code motion. Triples permit optimizations such as common subexpression elimination, but code motion is dicult.
} E
} E E
if ((p != NULL) && (p->next != q)) { ... then part } else { ... else part }
load(p); null(); neq(); load(p); ildc(1); getfield(); load(q); neq(); and(); jnz elselabel; ... then part elselabel: ... else part
Shortcircuit Code
if ((p != NULL) && (p->next != q)) { ... then part } else { ... else part } load(p); null(); neq(); jnz elselabel; load(p); ildc(1); getfield(); load(q); neq(); jnz elselabel; ... then part elselabel: ... else part
l- and r-Values
i := i + 1; l-value: location where the value of the expression is stored. r-value: actual value of the expression
Computing l-values
E id { E .lval = id.name; E .code = ; } E E 1 [ E 2 ] { E .lval = newtemp(); E .lcode = E 1 .lcode || E 2 .code || E .lval || := || E 1 .lval || + || E 2 .rval } E E 1 . id { // for eld access E .lval = newtemp(); E .lcode = E 1 .lcode || E .lval || := || E 1 .lval || + || id.oset }
E E 1 = E 2 { E .code = E 1 .lcode || E 2 .code || gen(* E 1 .lval := E 2 .rval) E .rval = E 2 .rval } E E 1 [ E 2 ] { E .lval = newtemp(); E .rval = newtemp(); E .lcode = E 1 .lcode || E 2 .code || gen(E .lval := E 1 .lval + E 2 .rval) E .code = E .lcode || gen(E .rval := * E .lval) }
Conditional Statements
E.code
if E , S 1 , S 2
S .code
1
S.end:
Conditional Statements
S if E , S 1 , S 2 { elselabel = newlabel(); endlabel = newlabel(); S.code = E .code || gen(cmp E .temp, 1) || gen(jne elselabel) || S 1 .code || gen(jmp endlabel) || gen(elselabel:) || S 2 .code || gen(endlabel :) }
If Statements: An Alternative
S.begin: E.code
if E , S 1 , S 2
S .code
1 (On end, will go to S.end )
S .begin:
2
S .code
2 (On end, will go to S.end )
S.end:
Continuations
An attribute of a statement that species where control will ow to after the statement is executed. Analogous to the follow sets of grammar symbols. In deterministic languages, there is only one continuation for each statement. Can be generalized to include local variables whose values are needed to execute the following statements: Uniformly captures call, return and exceptions.
Continuations
Each boolean expression has two possible continuations: E .true: where control will go when expression in E evaluates to true. E .false: where control will go when expression in E evaluates to false. Every statement S has one continuation, S.next
} E E 1 or E 2 { E 1 .true = E 2 .true = E .true; E 1 .false = newlabel(); E 2 .false = E .false; E .code = E 1 .code || gen(E 1 .false:) || E 2 .code } E ! E 1 { E 1 .false = E .true; E 1 .true = E .false; } E true { E .code = gen(goto, E .true) }
} S
1. Generate code, leaving holes where continuation values are needed. 2. Fill these holes on the next pass.
movl (r3), @8(r4) (set (mem: SI (plus: SI (reg: SI 4) (const_int 8))) (mem: SI (reg: SI 3)))
cost of machine instructions also specied gcc code generation = selecting a low-cost instruction sequence that has the same semantics as the intermediate code