[ssa] Run SSA in RPO traversal
This prevents us from looking up state in blocks that have not been visited.
Sathya Gunasekaran committed
Oct 27, 2022 at 16:43 UTC
fd6cb34843f0c3d4b71ca354352fa7156584403b
9 files changed
+69
-75
compiler/forget/src/HIR/SSAify.ts
+6
-12
@@ -165,11 +165,11 @@ class SSABuilder {
165
166
export default function buildSSA(func: HIRFunction, env: Environment) {
167
const builder = new SSABuilder(env);
168
- function visit(blockId: BlockId) {
169
- const block = func.body.blocks.get(blockId)!;
170
- if (builder.visitedBlocks.has(block)) {
171
- return;
172
- }
168
+ for (const [blockId, block] of func.body.blocks) {
169
+ invariant(
170
+ !builder.visitedBlocks.has(block),
171
+ `found a cycle! visiting bb${block.id} again`
172
+ );
173
builder.visitedBlocks.add(block);
174
175
builder.startBlock(block);
@@ -208,13 +208,7 @@ export default function buildSSA(func: HIRFunction, env: Environment) {
208
builder.fixIncompletePhis(output);
209
}
210
}
211
-
212
- for (const output of outputs) {
213
- visit(output);
214
- }
211
}
216
-
217
- visit(func.body.entry);
212
}
213
214
function rewriteUsesAndCollectOutputs(
@@ -245,7 +239,7 @@ function rewriteUsesAndCollectOutputs(
239
case "switch": {
240
const { cases } = terminal;
241
terminal.test = builder.getPlace(terminal.test);
248
- for (const case_ of [...cases].reverse()) {
242
+ for (const case_ of [...cases]) {
243
if (case_.test) {
244
case_.test = builder.getPlace(case_.test);
245
}
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md
+13
-13
@@ -28,23 +28,23 @@ bb0:
28
If (read $10) then:bb2 else:bb1
29
bb2:
30
predecessor blocks: bb0
31
- Reassign mutate x$18 = 3
31
+ Reassign mutate x$11 = 3
32
Goto bb1
33
bb1:
34
predecessor blocks: bb0 bb2
35
- y$12: phi(bb0: y$8, bb2: y$8)
36
- x$17: phi(bb0: x$7, bb2: x$18)
37
- Const mutate $11 = 3
38
- Const mutate $13 = Binary read y$12 === read $11
39
- If (read $13) then:bb4 else:bb3
35
+ y$13: phi(bb0: y$8, bb2: y$8)
36
+ x$17: phi(bb0: x$7, bb2: x$11)
37
+ Const mutate $12 = 3
38
+ Const mutate $14 = Binary read y$13 === read $12
39
+ If (read $14) then:bb4 else:bb3
40
bb4:
41
predecessor blocks: bb1
42
- Reassign mutate x$16 = 5
42
+ Reassign mutate x$15 = 5
43
Goto bb3
44
bb3:
45
predecessor blocks: bb1 bb4
46
- x$14: phi(bb1: x$17, bb4: x$16)
47
- Reassign mutate y$15 = read x$14
46
+ x$16: phi(bb1: x$17, bb4: x$15)
47
+ Reassign mutate y$18 = read x$16
48
Return
49
```
50
@@ -55,16 +55,16 @@ function foo$0() {
55
let x$7 = 1;
56
let y$8 = 2;
57
if (y$8 === 2) {
58
- x$18 = 3;
58
+ x$11 = 3;
59
("<<TODO: handle complex control flow in codegen>>");
60
}
61
62
- if (y$12 === 3) {
63
- x$16 = 5;
62
+ if (y$13 === 3) {
63
+ x$15 = 5;
64
("<<TODO: handle complex control flow in codegen>>");
65
}
66
67
- y$15 = x$14;
67
+ y$18 = x$16;
68
return;
69
}
70
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md
+5
-5
@@ -25,12 +25,12 @@ bb0:
25
If (read $8) then:bb2 else:bb1
26
bb2:
27
predecessor blocks: bb0
28
- Reassign mutate x$11 = 3
28
+ Reassign mutate x$9 = 3
29
Goto bb1
30
bb1:
31
predecessor blocks: bb0 bb2
32
- x$9: phi(bb0: x$5, bb2: x$11)
33
- Reassign mutate y$10 = read x$9
32
+ x$10: phi(bb0: x$5, bb2: x$9)
33
+ Reassign mutate y$11 = read x$10
34
Return
35
```
36
@@ -41,11 +41,11 @@ function foo$0() {
41
let x$5 = 1;
42
let y$6 = 2;
43
if (y$6 === 2) {
44
- x$11 = 3;
44
+ x$9 = 3;
45
("<<TODO: handle complex control flow in codegen>>");
46
}
47
48
- y$10 = x$9;
48
+ y$11 = x$10;
49
return;
50
}
51
compiler/forget/src/__tests__/fixtures/hir/ssa-if-else.expect.md
+4
-4
@@ -24,11 +24,11 @@ bb0:
24
If (read y$6) then:bb2 else:bb3
25
bb2:
26
predecessor blocks: bb0
27
- Let mutate z$8 = Binary read x$5 + read y$6
27
+ Let mutate z$7 = Binary read x$5 + read y$6
28
Goto bb1
29
bb3:
30
predecessor blocks: bb0
31
- Let mutate z$7 = read x$5
31
+ Let mutate z$8 = read x$5
32
Goto bb1
33
bb1:
34
predecessor blocks: bb3 bb2
@@ -42,10 +42,10 @@ function foo$0() {
42
let x$5 = 1;
43
let y$6 = 2;
44
if (y$6) {
45
- let z$8 = x$5 + y$6;
45
+ let z$7 = x$5 + y$6;
46
("<<TODO: handle complex control flow in codegen>>");
47
} else {
48
- let z$7 = x$5;
48
+ let z$8 = x$5;
49
("<<TODO: handle complex control flow in codegen>>");
50
}
51
compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md
+12
-12
@@ -29,18 +29,18 @@ bb0:
29
If (read $9) then:bb2 else:bb3
30
bb2:
31
predecessor blocks: bb0
32
- Reassign mutate x$14 = 2
32
+ Reassign mutate x$10 = 2
33
Goto bb1
34
bb3:
35
predecessor blocks: bb0
36
- Reassign mutate y$10 = 3
36
+ Reassign mutate y$11 = 3
37
Goto bb1
38
bb1:
39
predecessor blocks: bb3 bb2
40
- x$11: phi(bb3: x$6, bb2: x$14)
41
- y$12: phi(bb3: y$10, bb2: y$7)
42
- Let mutate t$13 = Object { x: read x$11, y: read y$12 }
43
- Return freeze t$13
40
+ x$12: phi(bb3: x$6, bb2: x$10)
41
+ y$13: phi(bb3: y$11, bb2: y$7)
42
+ Let mutate t$14 = Object { x: read x$12, y: read y$13 }
43
+ Return freeze t$14
44
```
45
46
## Code
@@ -50,18 +50,18 @@ function foo$0() {
50
let x$6 = 1;
51
let y$7 = 2;
52
if (x$6 > 1) {
53
- x$14 = 2;
53
+ x$10 = 2;
54
("<<TODO: handle complex control flow in codegen>>");
55
} else {
56
- y$10 = 3;
56
+ y$11 = 3;
57
("<<TODO: handle complex control flow in codegen>>");
58
}
59
60
- let t$13 = {
61
- x: x$11,
62
- y: y$12,
60
+ let t$14 = {
61
+ x: x$12,
62
+ y: y$13,
63
};
64
- return t$13;
64
+ return t$14;
65
}
66
67
```
compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md
+5
-5
@@ -23,12 +23,12 @@ bb0:
23
If (read $6) then:bb2 else:bb1
24
bb2:
25
predecessor blocks: bb0
26
- Reassign mutate x$8 = 2
26
+ Reassign mutate x$7 = 2
27
Goto bb1
28
bb1:
29
predecessor blocks: bb0 bb2
30
- x$7: phi(bb0: x$4, bb2: x$8)
31
- Return read x$7
30
+ x$8: phi(bb0: x$4, bb2: x$7)
31
+ Return read x$8
32
```
33
34
## Code
@@ -37,11 +37,11 @@ bb1:
37
function foo$0() {
38
let x$4 = 1;
39
if (x$4 === 1) {
40
- x$8 = 2;
40
+ x$7 = 2;
41
("<<TODO: handle complex control flow in codegen>>");
42
}
43
44
- return x$7;
44
+ return x$8;
45
}
46
47
```
compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md
+7
-7
@@ -26,16 +26,16 @@ bb0:
26
If (read $7) then:bb2 else:bb3
27
bb2:
28
predecessor blocks: bb0
29
- Reassign mutate y$11 = 1
29
+ Reassign mutate y$8 = 1
30
Goto bb1
31
bb3:
32
predecessor blocks: bb0
33
- Reassign mutate y$8 = 2
33
+ Reassign mutate y$9 = 2
34
Goto bb1
35
bb1:
36
predecessor blocks: bb3 bb2
37
- y$9: phi(bb3: y$8, bb2: y$11)
38
- Let mutate x$10 = read y$9
37
+ y$10: phi(bb3: y$9, bb2: y$8)
38
+ Let mutate x$11 = read y$10
39
Return
40
```
41
@@ -45,14 +45,14 @@ bb1:
45
function foo$0() {
46
let y$5 = 2;
47
if (y$5 > 1) {
48
- y$11 = 1;
48
+ y$8 = 1;
49
("<<TODO: handle complex control flow in codegen>>");
50
} else {
51
- y$8 = 2;
51
+ y$9 = 2;
52
("<<TODO: handle complex control flow in codegen>>");
53
}
54
55
- let x$10 = y$9;
55
+ let x$11 = y$10;
56
return;
57
}
58
compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md
+12
-12
@@ -39,23 +39,23 @@ bb0:
39
Default: bb2
40
bb5:
41
predecessor blocks: bb0
42
- Const mutate $21 = 1
43
- Reassign mutate x$22 = Binary read x$10 + read $21
42
+ Const mutate $15 = 1
43
+ Reassign mutate x$16 = Binary read x$10 + read $15
44
Goto bb1
45
bb3:
46
predecessor blocks: bb0
47
- Const mutate $19 = 2
48
- Reassign mutate x$20 = Binary read x$10 + read $19
47
+ Const mutate $17 = 2
48
+ Reassign mutate x$18 = Binary read x$10 + read $17
49
Goto bb1
50
bb2:
51
predecessor blocks: bb0
52
- Const mutate $15 = 3
53
- Reassign mutate x$16 = Binary read x$10 + read $15
52
+ Const mutate $19 = 3
53
+ Reassign mutate x$20 = Binary read x$10 + read $19
54
Goto bb1
55
bb1:
56
predecessor blocks: bb5 bb3 bb2
57
- x$17: phi(bb5: x$22, bb3: x$20, bb2: x$16)
58
- Let mutate y$18 = read x$17
57
+ x$21: phi(bb5: x$16, bb3: x$18, bb2: x$20)
58
+ Let mutate y$22 = read x$21
59
Return
60
```
61
@@ -66,22 +66,22 @@ function foo$0() {
66
let x$10 = 1;
67
switch (x$10) {
68
case x$10 === 1: {
69
- x$22 = x$10 + 1;
69
+ x$16 = x$10 + 1;
70
("<<TODO: handle complex control flow in codegen>>");
71
}
72
73
case x$10 === 2: {
74
- x$20 = x$10 + 2;
74
+ x$18 = x$10 + 2;
75
("<<TODO: handle complex control flow in codegen>>");
76
}
77
78
default: {
79
- x$16 = x$10 + 3;
79
+ x$20 = x$10 + 3;
80
("<<TODO: handle complex control flow in codegen>>");
81
}
82
}
83
84
- let y$18 = x$17;
84
+ let y$22 = x$21;
85
return;
86
}
87
compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md
+5
-5
@@ -22,12 +22,12 @@ bb0:
22
If (read $6) then:bb2 else:bb1
23
bb2:
24
predecessor blocks: bb0
25
- Reassign mutate x$8 = 2
25
+ Reassign mutate x$7 = 2
26
Goto bb1
27
bb1:
28
predecessor blocks: bb0 bb2
29
- x$7: phi(bb0: x$4, bb2: x$8)
30
- Throw read x$7
29
+ x$8: phi(bb0: x$4, bb2: x$7)
30
+ Throw read x$8
31
```
32
33
## Code
@@ -36,11 +36,11 @@ bb1:
36
function foo$0() {
37
let x$4 = 1;
38
if (x$4 === 1) {
39
- x$8 = 2;
39
+ x$7 = 2;
40
("<<TODO: handle complex control flow in codegen>>");
41
}
42
43
- throw x$7;
43
+ throw x$8;
44
}
45
46
```