Skip to content

Commit 5a5e263

Browse files
committed
[lec8] code generation 2024
1 parent cbd4a0e commit 5a5e263

File tree

2 files changed

+162
-25
lines changed

2 files changed

+162
-25
lines changed

notes/compilation.md

Lines changed: 152 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,147 @@ Tasks of the compiler
2222

2323
4. Translate function calls into machine-level calls
2424

25-
Infrastructure of the compiler
26-
------------------------------
25+
### Ad 1. Variable names to addresses
2726

28-
Signature (global symbol table):
29-
- name and type of functions suitable for Jasmin
30-
- Jasmin types:
27+
Jasmin types:
3128
* `I`: `int`
3229
* `D`: `double`
3330
* `V`: `void`
3431
* `Z`: `boolean`
3532

33+
```c
34+
void foo // size=0 max=0
35+
( double x // x:0 size=2 max=2
36+
, int y) { // y:2 size=3 max=3
37+
int i; // i:3 size=4 max=4
38+
{ // newBlock
39+
double y; // y:4 size=6 max=6
40+
bool b; // b:6 size=7 max=7
41+
} // popBlock size=4 max=7
42+
int j; // j:4 size=5 max=7
43+
}
44+
```
45+
```jasmin
46+
.method public static foo(DI)V
47+
.limit locals 7
48+
.end method
49+
```
50+
51+
### Ad 2. Expressions trees to stack instructions
52+
53+
Example:
54+
```c
55+
int main() {
56+
int i; // i:0
57+
double x = 3 * (i = 42) + i++; // x:1
58+
}
59+
```
60+
Translates to JVM:
61+
```scheme
62+
.method public static main()I
63+
.limit stack 4
64+
65+
;; instr ;; expr ;; stack (S) ;; store (V)
66+
iconst_3 ;; 3 ;; 3
67+
bipush 42 ;; 42 ;; 3 . 42
68+
istore_0 ;; i = ;; 3 ;; 0:42
69+
iload_0 ;; i = 42 ;; 3 . 42
70+
imul ;; 3 * (i = 42) ;; 126
71+
iload_0 ;; i ;; 126 . 42
72+
dup ;; ;; 126 . 42 . 42
73+
iconst_1 ;; 1 ;; 126 . 42 . 42 . 1
74+
iadd ;; i + 1 ;; 126 . 42 . 43
75+
istore_0 ;; i++ ;; 126 . 42 ;; 0:43
76+
iadd ;; 3 * (i = 42) + i++ ;; 168
77+
i2d ;; (double) ;; 168.0
78+
dstore_1 ;; x = 3 * (i = 42) + i++ ;; ;; 0:43, 1:168.0
79+
```
80+
Maximum stack size: 4 (32bit words)
81+
82+
JVM instruction small-step semantics (without jumps):
83+
```
84+
I : ⟨V,S⟩ → ⟨V',S'⟩
85+
86+
I : JVM instruction (or instruction sequence)
87+
V / V' : variable store before/after
88+
S / S' : stack before/after
89+
```
90+
91+
Some jump-free instructions:
92+
93+
| I | V | S | V' | S' |
94+
|--------------|-----|---------|----------|-----------------|
95+
| `iconst` _i_ | _V_ | _S_ | _V_ | _S.i_ |
96+
| `bipush` _i_ | _V_ | _S_ | _V_ | _S.i_ |
97+
| `iadd` | _V_ | _S.i.j_ | _V_ | _S.(i+j)_ |
98+
| `imul` | _V_ | _S.i.j_ | _V_ | _S.(i*j)_ |
99+
| `i2d` | _V_ | _S.i_ | _V_ | _S.(double)i_ |
100+
| `dup` | _V_ | _S.i_ | _V_ | _S.i.i_ |
101+
| `istore` _a_ | _V_ | _S.i_ | _V[a:i]_ | _S_ |
102+
| `dstore` _a_ | _V_ | _S.d_ | _V[a:d]_ | _S_ |
103+
| `iload` _a_ | _V_ | _S_ | _V_ | _S.V[a]_ |
104+
| `dload` _a_ | _V_ | _S_ | _V_ | _S.V[a]_ |
105+
106+
107+
Ad 3. Booleans and jumps
108+
------------------------
109+
110+
Example:
111+
```c
112+
bool inside(int i, int j, int k) {
113+
return i <= j && j < k;
114+
}
115+
```
116+
Machines typically do not have boolean operations; use jumps instead.
117+
```scheme
118+
.method public static inside(III)Z
119+
.limit locals 3
120+
.limit stack 2
121+
122+
iload_0 ;; i
123+
iload_1 ;; j
124+
if_icmpgt Lfalse ;; i <= j ;; false if i > j
125+
iload_1 ;; j
126+
iload_2 ;; k
127+
if_icmpge Lfalse ;; j < k ;; false if j >= k
128+
129+
iconst_1 ;; true
130+
goto Ldone
131+
132+
Lfalse:
133+
iconst_0 ;; false
134+
135+
Ldone:
136+
ireturn ;; return
137+
138+
.end method
139+
```
140+
141+
JVM instruction small-step semantics (with jumps):
142+
```
143+
I : ⟨P,V,S⟩ → ⟨P',V',S'⟩
144+
145+
P / P' : code position (program counter) before/after
146+
```
147+
148+
| I | P | V | S | P' | V' | S' | Condition |
149+
|-----------------|-----|-----|---------|-------|-----|-----|-----------|
150+
| `goto` _L_ | _P_ | _V_ | _S_ | _L_ | _V_ | _S_ | |
151+
| `ifeq` _L_ | _P_ | _V_ | _S.i_ | _L_ | _V_ | _S_ | _i = 0_ |
152+
| `ifeq` _L_ | _P_ | _V_ | _S.i_ | _P+1_ | _V_ | _S_ | _i ≠ 0_ |
153+
| `ifne` _L_ | _P_ | _V_ | _S.i_ | _L_ | _V_ | _S_ | _i ≠ 0_ |
154+
| `ifne` _L_ | _P_ | _V_ | _S.i_ | _P+1_ | _V_ | _S_ | _i = 0_ |
155+
| `if_icmpgt` _L_ | _P_ | _V_ | _S.i.j_ | _L_ | _V_ | _S_ | _i > j_ |
156+
| `if_icmpgt` _L_ | _P_ | _V_ | _S.i.j_ | _P+1_ | _V_ | _S_ | _i ≤ j_ |
157+
158+
159+
160+
Infrastructure of the compiler
161+
------------------------------
162+
163+
Signature (global symbol table):
164+
- name and type of functions suitable for Jasmin
165+
36166
Context (local symbol table):
37167
1. allocate local variables (`newLocal`)
38168
2. resolve variable names to addresses (`lookupVar`)
@@ -90,7 +220,6 @@ rest of the stack unchanged.
90220
emit(t-store a) -- either istore or dstore
91221
-- Problem here
92222
```
93-
(We omit `emit` in the following.)
94223

95224
## Compiler correctness
96225

@@ -130,17 +259,30 @@ stack is nil (no change).
130259
compileStm(SInit t x e):
131260
a <- newLocal t x
132261
compileExp(e)
133-
t-store a -- either istore or dstore
262+
emit(t-store a) -- either istore or dstore
134263

135264
compileStm(SExp t e):
136265
compileExp(e)
137-
t-pop -- either pop or pop2
266+
emit(t-pop) -- either pop or pop2
138267

139268
compileStm(SBlock ss):
140269
newBlock
141270
for (s : ss)
142271
compileStm(s)
143272
popBlock
273+
274+
compileStm(SWhile e s): -- s is a SBlock
275+
LStart, LEnd <- newLabel
276+
277+
emit(LStart:)
278+
279+
compileExp(e) -- executing e leaves boolean on stack
280+
emit(ifeq LEnd) -- if "false" end loop
281+
282+
compileStm(s) -- body of loop
283+
emit(goto LStart) -- recheck loop condition
284+
285+
emit(LEnd:)
144286
```
145287

146288
Correctness statement (simplified):
@@ -150,6 +292,8 @@ Correctness statement (simplified):
150292
then compileStm(s) : ⟨V,S⟩ →* ⟨V',S⟩
151293
such that γ' ~ V'.
152294

295+
(We omit `emit` in the following.)
296+
153297
Compiling booleans
154298
------------------
155299

notes/prime.j

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -82,21 +82,25 @@ L1:
8282

8383
iload_0 ;; p
8484
iconst_1
85-
if_icmple L4
85+
if_icmple L2
8686
iconst_2
8787
iload_0
8888
invokestatic prime/divides(II)Z
89-
ifne L4
89+
ifne L2
9090

9191
;; int q = 3;
9292

9393
iconst_3
9494
istore_1
9595

96+
L0:
9697
;; while (q * q <= p)
9798

98-
goto L3
99-
L0:
99+
iload_1
100+
iload_1
101+
imul
102+
iload_0
103+
if_icmpgt L3
100104

101105
;; if (divides (q, p))
102106

@@ -111,29 +115,18 @@ L0:
111115
iconst_2
112116
iadd
113117
istore_1
114-
goto L2
118+
goto L0
115119
L1:
116-
117120
;; return false;
118121

119122
iconst_0
120123
ireturn
121124
L2:
122-
L3:
123-
iload_1
124-
iload_1
125-
imul
126-
iload_0
127-
if_icmple L0
128-
goto L5
129-
L4:
130-
131125
;; return false;
132126

133127
iconst_0
134128
ireturn
135-
L5:
136-
129+
L3:
137130
;; return true;
138131

139132
iconst_1

0 commit comments

Comments
 (0)