Upload
annabel-knight
View
225
Download
0
Embed Size (px)
DESCRIPTION
c Chuen-Liang Chen, NTUCS&IE / 299 Introduction (2/2) optimized code difficult to achieve (even define) alternatives left to code optimizer (global optimization) heuristics (local optimization) –within a basic block problems (at least) instruction selection addressing mode selection register allocation
Citation preview
c
Chuen-Liang Chen, NTUCS&IE / 1
CODE GENERATION
Chuen-Liang Chen
Department of Computer Scienceand Information EngineeringNational Taiwan University
Taipei, TAIWAN
c
Chuen-Liang Chen, NTUCS&IE / 2
Introduction (1/2)simplest -- macro expansion
expand each intermediate tuple into an equivalent sequence of target machine instructions
example(*,B,C,T1) (+,E,A,T6) ( Load B, R1 ) ( Load E, R1 )(*,D,E,T2) (+,T6,C,T7) ( * C, R1 ) ( + A, R1 )(+,T1,T2,T3) (:=,T7,F) ( Load D, R2 ) ( + C, R1 )(:=,T3,A) ( * E, R2 ) ( Store F, R1 )(+,D,E,T8) ( + R2, R1 )(-,D,B,T4) (:=,T8,A) ( Store A, R1 ) ( Load D, R1 )(+,C,T4,T5) ( + E, R1 )(:=,T5,D) ( Load D, R1 ) ( Store A, R1 )( - B, R1 )( Load C, R2 )( + R1, R2 )( Store D, R2 )– assuming : cost = 2 for (LOAD,S,R), (STORE,S,R), (OP,S,R)
cost = 1 for (OP,R,R)– total cost = 34– not optimized, e.g., swapping C and T4
c
Chuen-Liang Chen, NTUCS&IE / 3
Introduction (2/2)
optimized code difficult to achieve (even define)
alternatives left to code optimizer (global optimization) heuristics (local optimization)
– within a basic block
problems (at least) instruction selection addressing mode selection register allocation
c
Chuen-Liang Chen, NTUCS&IE / 4
Live or dead
function( space, time ) space -- variable, register time -- execution sequence
Live -- whose value will be used later Dead -- whose value is useless later determination -- by a backward pass usage -- e.g., to free a dead register is
cheaper than to free a live register
example of Live / Dead( *, B, C, T1 )( *, D, E, T2 )( +, T1, T2, T3 )( :=, T3, A )( -, D, B, T4 )( +, C, T4, T5 )( :=, T5, D )( +, E, A, T6 )( +, T6, C, T7 )( :=, T7, F )( +, D, E, T8 )( :=, T8, A )
c
Chuen-Liang Chen, NTUCS&IE / 5
Example code generation (1/5)Generate code for integer add: (+,A,B,C)
Possible operand modes for A and B are:(1) Literal (stored in value field)(2) Indexed (stored in adr field as (Reg,Displacement) pair; indirect=F)(3) Indirect (stored in adr field as (Reg,Displacement) pair, indirect=T)(4) Live register (stored in Reg field)(5) Dead register (stored in Reg field)
Possible operand modes for C are:(1) Indexed (stored in adr field as (Reg,Displacement) pair, indirect=F)(2) Indirect (stored in adr field as (Reg,Displacement) pair, indirect=T)(3) Live register (stored in Reg field)(4) Unassigned register (stored in Reg field, when assigned)
(a) Swap operands (knowing addition is commutative)
if (B.mode == DEAD_REGISTER || A.mode == LITERAL)Swap A and B; /* This may save a load or store since addition overwrites the first operand. */
c
Chuen-Liang Chen, NTUCS&IE / 6
Example code generation (2/5)(b) “Target” the result of the addition directly into C (if possible).
switch (C.mode) {case LIVE_REGISTER: Target = C.reg; break;case UNASSIGNED_REGISTER:
if (A.mode == DEAD_REGISTER)C.reg = A.reg; /* Compute into A's reg, then assign it to C. */
elseAssign a register to C.reg;
C.mode = LIVE_REGISTER;Target = C.reg;break;
case INDIRECT:case INDEXED:
if (A.mode == DEAD_REGISTER)Target = A.reg;
elseTarget = v2;/* vi is the i-th volatile register. */
break;}
c
Chuen-Liang Chen, NTUCS&IE / 7
Example code generation (3/5)
(c) Map operand B to right operand of add instruction (the "Source")
if (B.mode == INDIRECT) {/* Use indexing to simulate indirection. */generate(LOAD,B.adr,v1,“”);/* v1 is a volatile register. */B.mode = INDEXED;B.adr = (address) { .reg = v1;
.displacement = 0; );}Source = B;
c
Chuen-Liang Chen, NTUCS&IE / 8
Example code generation (4/5)
(d) Now generate the add instruction
switch (A.mode) {/* “Fold” the addition. */case LITERAL: generate(LOAD,#(A.val+B.val),Target,“”);break;/* Load operand A (if necessary). */case INDEXED: generate(LOAD,A.adr,Target,“”); break;case LIVE_REGISTER: generate(LOAD,A.reg,Target,“”); break;case INDIRECT: generate(LOAD,A.adr,v2,“”);t.reg = v2; t.displacement = 0;generate(LOAD,t,Target,“”); break;case DEAD_REGISTER: if (Target != A.reg) generate(LOAD,A.reg,Target,“”); break;}generate(ADD,Source,Target,“”);
c
Chuen-Liang Chen, NTUCS&IE / 9
Example code generation (5/5)
(e) Store result into C (if necessary)
if (C.mode == INDEXED)generate(STORE,C.adr,Target,“”);
else if (C.mode == INDIRECT) {generate(LOAD,C.adr,v3,“”);t.reg = v3; t.displacement = 0;generate(STORE,t,Target,“”);
}
c
Chuen-Liang Chen, NTUCS&IE / 10
Register tracking (1/8)
associating more than one variables to a register when they have the same value
LOAD -- when valuable STORE -- postponed as late as possible status of value on register
Live or Dead Store or NotStore
extra-cost to free a register = associated variables V costV 0 -- ( D, NS ) or ( D, S ) 2 -- ( L, NS ) 4 -- ( L, S )
c
Chuen-Liang Chen, NTUCS&IE / 11
Register tracking (2/8)
procedure
Assignment (:=,X,Y):if (X is not already in a register)
Call get_reg() and generate a load of Xif (Y, after this tuple, has a status of (D,S) )
generate(STORE,Y,Reg,“”)else
Append Y to Reg's association list with a status of (L,S)/* The generation of the STORE instruction has been postponed */
c
Chuen-Liang Chen, NTUCS&IE / 12
Register tracking (3/8)machine_reg get_reg(void){
/ * Any register already allocated to the current tuple is NOT AVAILABLE * for allocation during this call. */if (there exists some register R with cost(R) == 0)
Choose Relse {
C = 2;while (TRUE) {
if (there exists at least one register with cost == C) {Choose that register, R, with cost C that has the most distant next
reference to an associated variable or temporarybreak;
}C += 2;
}for each associated variables or temporaries V with status == (L,S) or (D,S)
generate(STORE,V,R,“”);}return R;
}
c
Chuen-Liang Chen, NTUCS&IE / 13
Register tracking (4/8)(OP,U,V,W) where OP is noncommutative:
if (U is not in some register, R1)Call get_reg()generate(LOAD,U,R1,“”);
else /* R1's current value will be destroyed */for each associated variables or temporaries X with status == (L,S) or (D,S)
generate(STORE,X,R1,“”);if (V is in a register, R2)
/* including the possibility that U == V */generate(OP,R2,R1,“”)
else if (get_reg_cost() > 0 || V is dead after this tuple)generate(OP,V,R1,“”)
else {/* Invest 1 unit of cost so that V is in a register for later use */R2 = get_reg()generate(Load,V,R2,“”)generate(OP,R2,R1,“”)
}Update R1's association list to include W only.
c
Chuen-Liang Chen, NTUCS&IE / 14
Register tracking (5/8)
(OP,U,V,W) where OP is commutative:if (cost((OP,U,V,W)) <= cost((OP,V,U,W)))
generate(OP,U,V,W);/* using noncommutative code generator */
elsegenerate(OP,V,U,W);/* using noncommutative code generator */
with
cost((OP,U,V,W)) = (U is in a register ? 0 : get_reg_cost() + 2)/* Cost to load U into R1 */
+ cost(R1) /* Cost of losing U */+ (V is in a register || U == V ? 1 : 2)
/* Cost of reg-to-reg vs. storage-to-reg */
c
Chuen-Liang Chen, NTUCS&IE / 15
Register tracking (6/8)
Tuple Code Register AssociationsR1 R2 R3 R4
( *, B, C, T1 )Cost(*,B,C,T1) = 2+2+2Cost(*,C,B,T1) = 2+2+2
( Load B, R1 )( Load C, R2 )( * R2, R1 )
B(L,NS)B(L,NS)T1(L,S)
C(L,NS)C(L,NS)
( *, D, E, T2 )Cost(*,D,E,T2) = 2+2+2Cost(*,E,D,T2) = 2+2+2
( Load D, R3 )( Load E, R4 )( * R4, R3 )
T1(L,S)T1(L,S)T1(L,S)
C(L,NS)C(L,NS)C(L,NS)
D(L,NS)D(L,NS)T2(L,S)
E(L,NS)E(L,NS)
( +, T1, T2, T3 )Cost(+,T1,T2,T3)=0+0+1Cost(+,T2,T1,T3)=0+0+1
( + R3, R1 )-- (D,NS) associations-- can be immediately-- removed
T3(L,S) C(L,NS) T2(D,NS) E(L,NS)
( :=, T3, A ) -- The store is deferred A(L,S),T3 C(L,NS) E(L,NS)
( -, D, B, T4 ) ( Load D, R3 )( - B, R3 )
A(L,S)A(L,S)
C(L,NS)C(L,NS)
D(D,NS)T4(L,S)
E(L,NS)E(L,NS)
example
c
Chuen-Liang Chen, NTUCS&IE / 16
Register tracking (7/8)
Tuple Code Register AssociationsR1 R2 R3 R4
A(L,S) C(L,NS) T4(L,S) E(L,NS)
( +, C, T4, T5 )Cost(+,C,T4,T5) = 0+2+1Cost(+,T4,C,T5) = 0+0+1
( + R2, R3 ) A(L,S) C(L,NS) T5(L,S) E(L,NS)
( :=, T5, D ) -- Store is deferred A(L,S) C(L,NS) D(L,S),T5 E(L,NS)
( +, E, A, T6 )Cost(+,E,A,T6) = 0+2+1Cost(+,A,E,T6) = 0+0+1
( + R4, R1 ) T6(L,S) C(L,NS) D(L,S) E(L,NS)
( +, T6, C, T7 )Cost(+,T6,C,T7) = 0+0+1Cost(+,C,T6,T7) = 0+0+1
( + R2, R1 ) T7(L,S) C(D,NS) D(L,S) E(L,NS)
( :=, T7, F ) ( Store F, R1 )-- Do store since F is-- not live in this block
T7(D,NS) D(L,S) E(L,NS)
c
Chuen-Liang Chen, NTUCS&IE / 17
Register tracking (8/8)
Tuple Code Register AssociationsR1 R2 R3 R4
D(L,S) E(L,NS)
( +, D, E, T8 )Cost(+,D,E,T8) = 0+0+1Cost(+,E,D,T8) = 0+0+1
( Store D, R3 )-- Store is unavoidable
( + R4, R3 )
D(L,NS)
T8(L,S)
E(L,NS)
E(D,NS)
( :=, T8, A ) ( Store A, R3 )-- Store is unaoidable
T8(D,NS)
cost = 25
c
Chuen-Liang Chen, NTUCS&IE / 18
(in, input, output), M: machine code, A: Assembly, Pc: P-code, Pa: Pascal
Pascal’s P-code (1/4)
Fibonaccigenerator
(A, , *)
hardward
Assembler(M, A, M)
P-codeinterpreter(A, Pc, *)
P-code interpreter(M, Pc, *)
Fibonaccigenerator
(M, , *)
1,1,2,3,5,8,...
c
Chuen-Liang Chen, NTUCS&IE / 19
(in, input, output), M: machine code, A: Assembly, Pc: P-code, Pa: Pascal
Pascal’s P-code (2/4)
Fibonaccigenerator(Pc, , *)
1,1,2,3,5,8,...
Fibonaccigenerator(Pa, , *)
hardward
Assembler(M, A, M)
Pascalcompiler
(Pc, Pa, Pc)
Pascalcompiler
(Pa, Pa, Pc)P-code
interpreter(A, Pc, *)
P-code interpreter(M, Pc, *)
c
Chuen-Liang Chen, NTUCS&IE / 20
(in, input, output), M: machine code, A: Assembly, Pc: P-code, Pa: Pascal
Pascal’s P-code (3/4)
hardward
Assembler(M, A, M)
Pascalcompiler
(Pc, Pa, Pc)
Pascalcompiler
(Pa, Pa, Pc)P-code
interpreter(A, Pc, *)
Pascalcompiler’
(Pa, Pa, M)
P-code interpreter(M, Pc, *)
Pascalcompiler’
(Pc, Pa, M)Fibonaccigenerator
(M, , *)
1,1,2,3,5,8,...
Fibonaccigenerator(Pa, , *)
c
Chuen-Liang Chen, NTUCS&IE / 21
(in, input, output), M: machine code, A: Assembly, Pc: P-code, Pa: Pascal
Pascal’s P-code (4/4)
hardward
Assembler(M, A, M)
Pascalcompiler
(Pc, Pa, Pc)
Pascalcompiler
(Pa, Pa, Pc)P-code
interpreter(A, Pc, *)
Pascalcompiler’
(Pa, Pa, M)
P-code interpreter(M, Pc, *)
Pascalcompiler’
(Pc, Pa, M)Pascal
compiler’(M, Pa, M)
Fibonaccigenerator
(M, , *)
1,1,2,3,5,8,...
Fibonaccigenerator(Pa, , *)
c
Chuen-Liang Chen, NTUCS&IE / 22
(in, input, output), M: machine code, C: C or C++, B: byteCode, J: java
javac.exe = java.exe + sun.tools.javac.Main()
Java’s byteCode (1/2)
1,1,2,3,5,8,...
Fibonaccigenerator
(J, , *)
hardward
cc(M, C, M)
Javacompiler(B, J, B)
Javacompiler(J, J, B)
Java VM,byteCodeinterpreter
[m. indep][m. dep]
(C, B, *)
API[m. indep][m. dep]
(C) (J)
byteCode interpreter(java.exe + *.dll)
(M, B, *)
API (B)
Fibonaccigenerator
(B, , *)
c
Chuen-Liang Chen, NTUCS&IE / 23
(in, input, output), M: machine code, C: C or C++, B: byteCode, J: java
javac.exe = java.exe + sun.tools.javac.Main()
Java’s byteCode (2/2)
hardward
cc(M, C, M)
Javacompiler(B, J, B)
Javacompiler(J, J, B)
Java VM,byteCodeinterpreter
[m. indep][m. dep]
(C, B, *)
API[m. indep][m. dep]
(C) (J)
byteCode interpreter(java.exe + *.dll)
(M, B, *)Fibonaccigenerator
(M, , *)
1,1,2,3,5,8,...
API (B)
Fibonaccigenerator
(B, , *)
Fibonaccigenerator
(J, , *)
J IT
c
Chuen-Liang Chen, NTUCS&IE / 24
QUIZQUIZ
QUIZ: Term ProjectQUIZ: Term Project