Introduction To Compilers: Jun.-Prof. Dr. Christian Plessl Custom Computing University of Paderborn
Introduction To Compilers: Jun.-Prof. Dr. Christian Plessl Custom Computing University of Paderborn
SS 2012
Jun.-Prof. Dr. Christian Plessl
Custom Computing
University of Paderborn
Version 1.1.2 2012-05-01
Outline
compiler structure, intermediate code
code generation
code optimization
retargetable compiler
Translation Process
skeletal source program
preprocessor
source program
compiler
assembler program
assembler
relocatable machine code
linker / loader
library
Compiler Phases
source program
lexical analysis
analysis
syntactic analysis
semantic analysis
symbol table
intermediate code generat.
error handling
code optimization
code generation
synthesis
target program
4
syntactic analysis
parsing symbol sequences and construction of sentences
sentences are described by a context-free grammar
!A Identifier := E
E E + E | E * E | Identifier | Number
semantic analysis
make sure the program parts "reasonably" fit together,
e.g. implicit type conversions
optimization
goals for GP processors: fast code, fast translation
goals for specialized processors: fast code, short code (low memory
requirements), low power consumption
both intermediate and target code can be optimized
code generation
translate intermediate representation into assembler code for target
architecture
apply target specific optimizations
6
Example (1)
source program
lexical analysis
assignment symbol
id1 :=
id2 +
identifiers
operators
id3
*
60
number
Example (2)
syntactic analysis
semantic analysis
:=
id1
:=
id1
+
id2
id2
*
id3
60
*
id3
IntToReal
60
Example (3)
intermediate code generat.
tmp1 := IntToReal(60)
tmp2 := id3*tmp1
tmp3 := id2+tmp2
id1 := tmp3
code optimization
tmp1 := id3 * 60.0
id1 := id2 + tmp1
code generation
ld.s
li.s
mul.s
ld.s
add.s
st.s
$f1,
$f2,
$f2,
$f1,
$f2,
$f2,
id3
60.0
$f2, $f1
id2
$f2, $f1
id1
9
syntax tree
:=
+
*
*
-
*
e
d
10
assignment instructions
x := y op z
x := op y
x := y
goto L
if x relop y goto L
x := y[i]
x[i] := y
subroutines
x := &y
y := *x
*x := y
param x
x = call p,n
return y
11
t1 := c - d
t2 := e * t1
t3 := b * t1
t4 := t2 + t3
a := t4
t4
a
t3
t2
*
t1
b
e
c
12
13
t1
t2
t3
t4
if
:=
:=
:=
:=
t4
c - d
e * t1
b * t1
t2 + t3
< 10 goto L
14
15
i := 0
t2 := 0
t2 := t2 + i
i := i + 1
if i < 10 goto L
x := t2
i < 10
i >= 10
16
17
Example (1)
C program
3 address code
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
prod := 0
i := 0
t1 := 4 * i
t2 := a[t1]
t3 := 4 * i
t4 := b[t3]
t5 := t2 * t4
t6 := prod + t5
prod := t6
t7 := i + 1
i := t7
if i < 20 goto (3)
18
Example (2)
basic blocks
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
prod := 0
B1
i := 0
t1 := 4 * i
B2
t2 := a[t1]
t3 := 4 * i
t4 := b[t3]
t5 := t2 * t4
t6 := prod + t5
prod := t6
t7 := i + 1
i := t7
if i < 20 goto (3)
B1
B2
19
Example (3)
basic block B2
DAG for B2
t6, prod
+
t1 := 4 * i
t2 := a[t1]
t3 := 4 * i
t4 := b[t3]
t5 := t2 * t4
t6 := prod + t5
prod := t6
t7 := i + 1
i := t7
if i < 20 goto (3)
prod0
t5
t2
t4
[]
[]
<
t1, t3
*
b
t7, i
20
a
4
i0
1
20
21
Code Generation
requirements
correct code
efficient code
fast code generation
binding:
register binding (register allocation, register assignment)
instruction selection
scheduling:
instruction sequencing
22
Register Binding
goal: efficient use of registers
minimize number of LOAD/STORE instructions (RISC)
instructions with register operands are generally shorter and faster
than instructions with memory operands (CISC)
23
Instruction Selection
naive approach
use code pattern for each 3 address instruction
x := y + z
u := x - w
problems
lw
lw
add
sw
$r1,
$r2,
$r1,
$r1,
y
z
$r1, $r2
x
lw
lw
sub
sw
$r1,
$r2,
$r1,
$r1,
x
w
$r1, $r2
u
24
t4
t1
t3
t2
t3
t1
t4
:=
:=
:=
:=
c + d
e - t2
a + b
t1 - t3
t1
t2
t3
t4
:=
:=
:=
:=
a + b
c + d
e - t2
t1 - t3
t2
b e
+
c
25
:=
:=
:=
:=
t1
t2
t3
t4
c + d
e - t2
a + b
t1 - t3
:=
:=
:=
:=
a + b
c + d
e - t2
t1 - t3
MOV
ADD
MOV
SUB
MOV
ADD
SUB
MOV
c, R0
d, R0
e, R1
R0, R1
a, R0
b, R0
R1, R0
R0, t4
R1:R1:R1:e
R1:t3
R1:t3
R1:t3
26
:=
:=
:=
:=
c + d
e - t2
a + b
t1 - t3
t1
t2
t3
t4
:=
:=
:=
:=
a + b
c + d
e - t2
t1 - t3
MOV
ADD
MOV
ADD
MOV
MOV
SUB
MOV
SUB
MOV
a, R0
b, R0
c, R1
d, R1
R0, t1
e, R0
R1, R0
t1, R1
R0, R1
R1, t4
t1 and t2 are used below red line (register needs to be temporarily saved to memory,
this is denoted as register spill)
27
28
Code Optimization
transformations on the intermediate code and on the
target code
peephole optimization
small window (peephole) is moved over the code
several passes, because an optimization can generate new optimization
opportunities
local optimization
transformations inside basic blocks
global optimization
transformations across several basic blocks
29
lw $r1, a
sw $r1, a
(1)
lw $r1, a
algebraic simplifications
x := y + 0*(z**4/(y-1));
x := x * 1;
x := x + 0;
x := y;
delete
30
x := y << 3;
x := y**2;
x := y * y;
31
Local Optimizations
common sub-expression elimination
(1)
(2)
(3)
(4)
a
b
c
d
:=
:=
:=
:=
b
a
b
a
+
+
-
c
d
c
d
(1)
(2)
(3)
(4)
a
b
c
d
:=
:=
:=
:=
b + c
a - d
b + c
b
variable renaming
t := b + c
u := b + c
instruction interchange
t1 := b + c
t2 := x + y
t2 := x + y
t1 := b + c
32
copy propagation
(1)
(2)
(3)
(4)
x := t1
a[t2] := t3
a[t4] := x
goto L
(1)
(2)
(3)
(4)
x := t1
a[t2] := t3
a[t4] := t1
goto L
33
goto L1
.
goto L2
(1)
(2) L1
goto L2
.
goto L2
if L1 is not reachable:
delete (2) (dead code elimination)
34
(1)
(2)
(3)
(4)
j := n
j := j - 1
t4 := 4 * j
t5 := a[t4]
if t5 > v goto (1)
(1)
(2)
(3)
(4)
j := n
t4 := 4 * j
j := j - 1
t4 := t4 - 4
t5 := a[t4]
if t5 > v goto (1)
35
36
Retargetable Compiler
portable compiler
developer retargetable
code generation by tree pattern matching
compiler-compiler
user retargetable (semi-automatic)
compiler is generated from a description of the target architecture
(processor model)
37
example:
pattern { action }
reg i
reg i
{ ADD Rj, Ri }
reg j
(1)
reg i
(4)
mem
(2) reg i
reg i
mem a { MOV a, Ri }
(5) reg i
(3)
mem
:= { MOV Ri, a }
mem a
reg i
reg j
reg j
39
(7) reg i
+ { ADD Rj, Ri }
reg i
(6) reg i
reg j
+ { ADD c(Rj), Ri }
reg i
ind
(8) reg i
+
const c
reg j
+ { INC Ri }
reg i
const 1
40
:=
+
ind
+
+
const _a
mem b
const 1
ind
reg SP
const _i
+
reg SP
41
0x000
0x100
42
0x104
0x108
0xF00
0xF04
0xF08
a[0]
0xF0C
0xF10
11
a[1]
0xF14
a[2]
0xF1B
a[3]
_i=0x8
_a=0xC
heap memory
stack memory
42
:=
+
ind
+
(1) { MOV #_a, R0 }
const _a
mem b
const 1
ind
reg SP
const _i
+
reg SP
43
:=
+
ind
+
reg 0
mem b
const 1
ind
reg SP
const _i
+
reg SP
44
a[i] := b + 1
ind
reg 0
mem b
const 1
ind
+
const _i
reg SP
45
:=
+
ind
reg 0
mem b
const 1
(2) { MOV b, R1 }
46
:=
+
ind
reg 0
reg 1
const 1
(8) { INC R1 }
47
:=
ind
reg 1
reg 0
(4) { MOV R1, *R0 }
MOV
ADD
ADD
MOV
INC
MOV
#_a, R0
SP, R0
_i(SP), R0
b, R1
R1
R1, *R0
48
Compiler Compiler
front-end
back-end
source
program
(DFL)
parsing,
flow graph
generation
pattern
matching
processor
model
(HDL)
instruction
set
extraction
pattern
matcher
generator
optimization
executable
code
49
xx011zz
control bits
xx
reg
acc
01
pattern
zz
reg
reg
+
acc
reg
50
Changes
v1.1.2 (2012-05-01)
tree pattern matching: show DAG to be matched before explanation
v1.1.1 (2012-04-27)
fixed semantic of ADD R0,R1 operation on slide 26 and added a new slide
27 for illustrating the differences between the generated code
move "control flow optimization" to slide 27 because it is not a local but a
global optimization
v1.1.0 (2012-04-24)
updated for SS2012, minor corrections
v1.0.3 (2010-05-05)
fix minor typos in explanation of a[i]= b + 1 memory layout description
v1.0.2 (2010-05-02)
add discussion of how a[i]= b + 1 is stored in memory
v1.0.1 (2010-04-27)
slide 11: clarified that call instruction in 3 addr code returns a value
51