@samitouri / QOS-React / commits / 74e6ffc4a2

Leave SSA form

Alternative approach to #750. We now store the original identifier on the Phi node, then rewrite every BasicBlock's identifiers to reference the original id instead of the SSA'd id. This solves the shadowing problem and also lets us omit adding copies of instructions.

Lauren Tan committed Nov 9, 2022 at 15:12 UTC 74e6ffc4a2e0a99bd6e2cdbc9a05c4d481c58dd0
23 files changed +295 -184
compiler/forget/src/HIR/EnterSSA.ts
+1
@@ -121,6 +121,7 @@ class SSABuilder {
121 const phi: Phi = {
122 kind: "Phi",
123 id: newId,
124 + oldId,
125 operands: predDefs,
126 };
127
compiler/forget/src/HIR/HIR.ts
+1
@@ -193,6 +193,7 @@ export type InstructionValue =
193 export type Phi = {
194 kind: "Phi";
195 id: Identifier;
196 + oldId: Identifier;
197 operands: Map<BasicBlock, Identifier>;
198 };
199
compiler/forget/src/HIR/LeaveSSA.ts new
+50
@@ -0,0 +1,50 @@
1 +import { invariant } from "../CompilerError";
2 +import { HIRFunction, Identifier, Place } from "./HIR";
3 +import { eachInstructionOperand, eachTerminalOperand } from "./visitors";
4 +
5 +export default function leaveSSA(fn: HIRFunction) {
6 + const ir = fn.body;
7 + const entryBlock = ir.blocks.get(ir.entry);
8 + invariant(entryBlock, "expected to find the entry basic block");
9 + const originalIdMap = new Map<
10 + /* SSA'd id */ Identifier,
11 + /* original id*/ Identifier
12 + >();
13 +
14 + for (const [, block] of ir.blocks) {
15 + for (const phi of block.phis) {
16 + originalIdMap.set(phi.id, phi.oldId);
17 + for (const [, ssaId] of phi.operands) {
18 + originalIdMap.set(ssaId, phi.oldId);
19 + }
20 + }
21 + block.phis.clear();
22 + }
23 +
24 + if (originalIdMap.size === 0) {
25 + return;
26 + }
27 +
28 + function tryRewrite(place: Place) {
29 + const originalId = originalIdMap.get(place.identifier);
30 + if (originalId != null) {
31 + place.identifier = originalId;
32 + }
33 + }
34 +
35 + for (const [, block] of ir.blocks) {
36 + for (const instr of block.instructions) {
37 + // LValues also need to be rewritten as they might be declaring or reassigning an identifier
38 + // that was previously SSA'd.
39 + if (instr.lvalue != null) {
40 + tryRewrite(instr.lvalue.place);
41 + }
42 + for (const place of eachInstructionOperand(instr)) {
43 + tryRewrite(place);
44 + }
45 + }
46 + for (const place of eachTerminalOperand(block.terminal)) {
47 + tryRewrite(place);
48 + }
49 + }
50 +}
compiler/forget/src/__tests__/fixtures/hir/component.expect.md
+3 -4
@@ -52,16 +52,15 @@ bb3:
52 If (read $36) then:bb8 else:bb9
53 bb8:
54 predecessor blocks: bb3
55 - [9] Const mutate $37 = read $36
55 + [9] Const mutate $13 = read $36
56 Goto bb7
57 bb9:
58 predecessor blocks: bb3
59 - [10] Const mutate $39 = Call mutate seen$30.has(mutate item$10)
59 + [10] Const mutate $13 = Call mutate seen$30.has(mutate item$10)
60 Goto bb7
61 bb7:
62 predecessor blocks: bb8 bb9
63 - $40: phi(bb8: $37, bb9: $39)
64 - If (read $40) then:bb1 else:bb4
63 + If (read $13) then:bb1 else:bb4
64 bb4:
65 predecessor blocks: bb7
66 [11] Call mutate seen$30.add(mutate item$10)
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md
+12 -13
@@ -32,19 +32,18 @@ bb0:
32 If (read cond$8) then:bb2 else:bb3
33 bb2:
34 predecessor blocks: bb0
35 - [4] Reassign mutate a$11 = read x$9
35 + [4] Reassign mutate a$4 = read x$9
36 Goto bb1
37 bb3:
38 predecessor blocks: bb0
39 - [5] Reassign mutate a$12 = Array []
39 + [5] Reassign mutate a$4 = Array []
40 Goto bb1
41 bb1:
42 predecessor blocks: bb2 bb3
43 - a$14: phi(bb2: a$11, bb3: a$12)
44 - [6] Call read useFreeze$5(freeze a$14)
45 - [7] Call read useFreeze$5(read a$14)
46 - [8] Call mutate call$6(read a$14)
47 - Return read a$14
43 + [6] Call read useFreeze$5(freeze a$4)
44 + [7] Call read useFreeze$5(read a$4)
45 + [8] Call mutate call$6(read a$4)
46 + Return read a$4
47 ```
48
49 ## Code
@@ -55,15 +54,15 @@ function Component$0(props$7) {
54 const x$9 = props$7.x;
55 let a$10 = undefined;
56 bb1: if (cond$8) {
58 - a$11 = x$9;
57 + a$4 = x$9;
58 } else {
60 - a$12 = [];
59 + a$4 = [];
60 }
61
63 - useFreeze$5(a$14);
64 - useFreeze$5(a$14);
65 - call$6(a$14);
66 - return a$14;
62 + useFreeze$5(a$4);
63 + useFreeze$5(a$4);
64 + call$6(a$4);
65 + return a$4;
66 }
67
68 ```
compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md
+12 -15
@@ -27,16 +27,15 @@ bb0:
27 If (read $5) then:bb2 else:bb3
28 bb2:
29 predecessor blocks: bb0
30 - [2] Const mutate $6 = Call mutate g$4()
30 + [2] Const mutate $3 = Call mutate g$4()
31 Goto bb1
32 bb3:
33 predecessor blocks: bb0
34 - [3] Const mutate $7 = read $5
34 + [3] Const mutate $3 = read $5
35 Goto bb1
36 bb1:
37 predecessor blocks: bb2 bb3
38 - $8: phi(bb2: $6, bb3: $7)
39 - Return freeze $8
38 + Return freeze $3
39 ```
40
41 ## Code
@@ -46,7 +45,7 @@ function And$0() {
45 bb1: if (f$1()) {
46 } else {
47 }
49 - return t8;
48 + return f$1();
49 }
50
51 ```
@@ -58,16 +57,15 @@ bb0:
57 If (read $5) then:bb2 else:bb3
58 bb2:
59 predecessor blocks: bb0
61 - [2] Const mutate $6 = read $5
60 + [2] Const mutate $3 = read $5
61 Goto bb1
62 bb3:
63 predecessor blocks: bb0
65 - [3] Const mutate $7 = Call mutate g$4()
64 + [3] Const mutate $3 = Call mutate g$4()
65 Goto bb1
66 bb1:
67 predecessor blocks: bb2 bb3
69 - $8: phi(bb2: $6, bb3: $7)
70 - Return freeze $8
68 + Return freeze $3
69 ```
70
71 ## Code
@@ -77,7 +75,7 @@ function Or$0() {
75 bb1: if (f$1()) {
76 } else {
77 }
80 - return t8;
78 + return g$4();
79 }
80
81 ```
@@ -91,16 +89,15 @@ bb0:
89 If (read $11) then:bb2 else:bb3
90 bb2:
91 predecessor blocks: bb0
94 - [4] Const mutate $12 = read $9
92 + [4] Const mutate $6 = read $9
93 Goto bb1
94 bb3:
95 predecessor blocks: bb0
98 - [5] Const mutate $13 = Call mutate g$7()
96 + [5] Const mutate $6 = Call mutate g$7()
97 Goto bb1
98 bb1:
99 predecessor blocks: bb2 bb3
102 - $14: phi(bb2: $12, bb3: $13)
103 - Return freeze $14
100 + Return freeze $6
101 ```
102
103 ## Code
@@ -110,7 +107,7 @@ function QuestionQuestion$0(props$8) {
107 bb1: if (f$2() != null) {
108 } else {
109 }
113 - return t14;
110 + return g$7();
111 }
112
113 ```
compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md
+20 -28
@@ -73,49 +73,41 @@ function cond$0(x$2) {
73
74 ```
75 bb0:
76 - [1] Let mutate a$13 = Object { }
77 - [2] Let mutate b$14 = Object { }
78 - [3] Let mutate c$15 = Object { }
79 - [4] Let mutate d$16 = Object { }
76 + [1] Let mutate a$2 = Object { }
77 + [2] Let mutate b$3 = Object { }
78 + [3] Let mutate c$4 = Object { }
79 + [4] Let mutate d$5 = Object { }
80 Goto bb1
81 bb1:
82 predecessor blocks: bb0 bb3
83 - a$18: phi(bb0: a$13, bb3: a$21)
84 - b$20: phi(bb0: b$14, bb3: b$23)
85 - c$22: phi(bb0: c$15, bb3: c$25)
86 - d$24: phi(bb0: d$16, bb3: d$26)
83 [5] Const mutate $17 = true
84 If (read $17) then:bb3 else:bb2
85 bb3:
86 predecessor blocks: bb1
91 - [6] Let mutate z$19 = read a$18
92 - [7] Reassign mutate a$21[7:12] = read b$20
93 - [8] Reassign mutate b$23[8:11] = read c$22
94 - [9] Reassign mutate c$25 = read d$24
95 - [10] Reassign mutate d$26 = read z$19
96 - [11] Call mutate mutate$7(mutate a$21, mutate b$23)
97 - [12] Const mutate $29 = Call mutate cond$8(mutate a$21)
87 + [6] Let mutate z$19 = read a$2
88 + [7] Reassign mutate a$2 = read b$3
89 + [8] Reassign mutate b$3 = read c$4
90 + [9] Reassign mutate c$4 = read d$5
91 + [10] Reassign mutate d$5 = read z$19
92 + [11] Call mutate mutate$7(mutate a$2, mutate b$3)
93 + [12] Const mutate $29 = Call mutate cond$8(mutate a$2)
94 If (read $29) then:bb2 else:bb1
95 bb2:
96 predecessor blocks: bb3 bb1
101 - a$30: phi(bb3: a$21, bb1: a$18)
102 - b$31: phi(bb3: b$23, bb1: b$20)
103 - c$32: phi(bb3: c$25, bb1: c$22)
104 - d$33[-1:14]: phi(bb3: d$26, bb1: d$24)
105 - If (read a$30) then:bb7 else:bb7
97 + If (read a$2) then:bb7 else:bb7
98 bb7:
99 predecessor blocks: bb2
108 - If (read b$31) then:bb9 else:bb9
100 + If (read b$3) then:bb9 else:bb9
101 bb9:
102 predecessor blocks: bb7
111 - If (read c$32) then:bb11 else:bb11
103 + If (read c$4) then:bb11 else:bb11
104 bb11:
105 predecessor blocks: bb9
114 - If (read d$33) then:bb13 else:bb13
106 + If (read d$5) then:bb13 else:bb13
107 bb13:
108 predecessor blocks: bb11
109 [13] Const mutate $34 = null
118 - [14] Call mutate mutate$7(mutate d$33, read $34)
110 + [14] Call mutate mutate$7(mutate d$5, read $34)
111 Return
112 ```
113
@@ -123,10 +115,10 @@ bb13:
115
116 ```javascript
117 function Component$0(props$12) {
126 - let a$13 = {};
127 - let b$14 = {};
128 - let c$15 = {};
129 - let d$16 = {};
118 + let a$2 = {};
119 + let b$3 = {};
120 + let c$4 = {};
121 + let d$5 = {};
122 }
123
124 ```
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+12 -13
@@ -23,20 +23,19 @@ function Component(props) {
23
24 ```
25 bb0:
26 - [1] Let mutate x$7[1:2] = Array []
27 - [2] Call mutate x$7.push(read props$6.p0)
28 - [3] Let mutate y$8 = read x$7
26 + [1] Let mutate x$2 = Array []
27 + [2] Call mutate x$2.push(read props$6.p0)
28 + [3] Let mutate y$8 = read x$2
29 If (read props$6.p1) then:bb2 else:bb1
30 bb2:
31 predecessor blocks: bb0
32 - [4] Reassign mutate x$9 = Array []
32 + [4] Reassign mutate x$2 = Array []
33 Goto bb1
34 bb1:
35 predecessor blocks: bb2 bb0
36 - x$11: phi(bb2: x$9, bb0: x$7)
37 - [5] Let mutate _$12 = JSX <read Component$0 x={freeze x$11} ></read Component$0>
36 + [5] Let mutate _$12 = JSX <read Component$0 x={freeze x$2} ></read Component$0>
37 [6] Call read y$8.push(read props$6.p2)
39 - [7] Const mutate $15 = JSX <read Component$0 x={read x$11} y={read y$8} ></read Component$0>
38 + [7] Const mutate $15 = JSX <read Component$0 x={read x$2} y={read y$8} ></read Component$0>
39 Return read $15
40 ```
41
@@ -44,17 +43,17 @@ bb1:
43
44 ```javascript
45 function Component$0(props$6) {
47 - let x$7 = [];
48 - x$7.push(props$6.p0);
49 - let y$8 = x$7;
46 + let x$2 = [];
47 + x$2.push(props$6.p0);
48 + let y$8 = x$2;
49 bb1: if (props$6.p1) {
51 - x$9 = [];
50 + x$2 = [];
51 }
52
54 - let _$12 = <Component$0 x={x$11}></Component$0>;
53 + let _$12 = <Component$0 x={x$2}></Component$0>;
54
55 y$8.push(props$6.p2);
57 - return <Component$0 x={x$11} y={y$8}></Component$0>;
56 + return <Component$0 x={x$2} y={y$8}></Component$0>;
57 }
58
59 ```
compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md
+12 -13
@@ -50,31 +50,30 @@ bb2:
50 Default: bb4
51 bb8:
52 predecessor blocks: bb2
53 - [5] Reassign mutate x$11 = read props$6.v0
53 + [5] Reassign mutate x$2 = read props$6.v0
54 Goto bb1
55 bb6:
56 predecessor blocks: bb2
57 - [6] Reassign mutate x$12 = read props$6.v1
57 + [6] Reassign mutate x$2 = read props$6.v1
58 Goto bb1
59 bb4:
60 predecessor blocks: bb2
61 - [7] Reassign mutate x$13 = read props$6.v2
61 + [7] Reassign mutate x$2 = read props$6.v2
62 Goto bb1
63 bb10:
64 predecessor blocks: bb0
65 If (read props$6.cond2) then:bb12 else:bb13
66 bb12:
67 predecessor blocks: bb10
68 - [8] Reassign mutate x$14 = read props$6.b
68 + [8] Reassign mutate x$2 = read props$6.b
69 Goto bb1
70 bb13:
71 predecessor blocks: bb10
72 - [9] Reassign mutate x$15 = read props$6.c
72 + [9] Reassign mutate x$2 = read props$6.c
73 Goto bb1
74 bb1:
75 predecessor blocks: bb8 bb6 bb4 bb12 bb13
76 - x$16: phi(bb8: x$11, bb6: x$12, bb4: x$13, bb12: x$14, bb13: x$15)
77 - [10] read x$16
76 + [10] read x$2
77 Return
78 ```
79
@@ -86,12 +85,12 @@ function Component$0(props$6) {
85 bb1: if (props$6.cond) {
86 switch (props$6.test) {
87 case 0: {
89 - x$11 = props$6.v0;
88 + x$2 = props$6.v0;
89 break bb1;
90 }
91
92 case 1: {
94 - x$12 = props$6.v1;
93 + x$2 = props$6.v1;
94 break bb1;
95 }
96
@@ -99,18 +98,18 @@ function Component$0(props$6) {
98 }
99
100 default: {
102 - x$13 = props$6.v2;
101 + x$2 = props$6.v2;
102 }
103 }
104 } else {
105 if (props$6.cond2) {
107 - x$14 = props$6.b;
106 + x$2 = props$6.b;
107 } else {
109 - x$15 = props$6.c;
108 + x$2 = props$6.c;
109 }
110 }
111
113 - x$16;
112 + x$2;
113 return;
114 }
115
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md
+8 -10
@@ -21,29 +21,27 @@ function foo() {
21
22 ```
23 bb0:
24 - [1] Let mutate x$7 = 1
24 + [1] Let mutate x$1 = 1
25 [2] Let mutate y$8 = 2
26 [3] Const mutate $9 = 2
27 [4] Const mutate $10 = Binary read y$8 === read $9
28 If (read $10) then:bb2 else:bb1
29 bb2:
30 predecessor blocks: bb0
31 - [5] Reassign mutate x$11 = 3
31 + [5] Reassign mutate x$1 = 3
32 Goto bb1
33 bb1:
34 predecessor blocks: bb2 bb0
35 - x$17: phi(bb2: x$11, bb0: x$7)
35 [6] Const mutate $12 = 3
36 [7] Const mutate $14 = Binary read y$8 === read $12
37 If (read $14) then:bb4 else:bb3
38 bb4:
39 predecessor blocks: bb1
41 - [8] Reassign mutate x$15 = 5
40 + [8] Reassign mutate x$1 = 5
41 Goto bb3
42 bb3:
43 predecessor blocks: bb4 bb1
45 - x$16: phi(bb4: x$15, bb1: x$17)
46 - [9] Reassign mutate y$18 = read x$16
44 + [9] Reassign mutate y$18 = read x$1
45 Return
46 ```
47
@@ -51,17 +49,17 @@ bb3:
49
50 ```javascript
51 function foo$0() {
54 - let x$7 = 1;
52 + let x$1 = 1;
53 let y$8 = 2;
54 bb1: if (y$8 === 2) {
57 - x$11 = 3;
55 + x$1 = 3;
56 }
57
58 bb3: if (y$8 === 3) {
61 - x$15 = 5;
59 + x$1 = 5;
60 }
61
64 - y$18 = x$16;
62 + y$18 = x$1;
63 return;
64 }
65
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md
+6 -7
@@ -18,19 +18,18 @@ function foo() {
18
19 ```
20 bb0:
21 - [1] Let mutate x$5 = 1
21 + [1] Let mutate x$1 = 1
22 [2] Let mutate y$6 = 2
23 [3] Const mutate $7 = 2
24 [4] Const mutate $8 = Binary read y$6 === read $7
25 If (read $8) then:bb2 else:bb1
26 bb2:
27 predecessor blocks: bb0
28 - [5] Reassign mutate x$9 = 3
28 + [5] Reassign mutate x$1 = 3
29 Goto bb1
30 bb1:
31 predecessor blocks: bb2 bb0
32 - x$10: phi(bb2: x$9, bb0: x$5)
33 - [6] Reassign mutate y$11 = read x$10
32 + [6] Reassign mutate y$11 = read x$1
33 Return
34 ```
35
@@ -38,13 +37,13 @@ bb1:
37
38 ```javascript
39 function foo$0() {
41 - let x$5 = 1;
40 + let x$1 = 1;
41 let y$6 = 2;
42 bb1: if (y$6 === 2) {
44 - x$9 = 3;
43 + x$1 = 3;
44 }
45
47 - y$11 = x$10;
46 + y$11 = x$1;
47 return;
48 }
49
compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md
+5 -6
@@ -16,29 +16,28 @@ function foo() {
16
17 ```
18 bb0:
19 - [1] Let mutate x$5 = 0
19 + [1] Let mutate x$1 = 0
20 Goto bb1
21 bb1:
22 predecessor blocks: bb0 bb4
23 - x$7: phi(bb0: x$5, bb4: x$10)
23 [2] Const mutate $6 = 10
25 - [3] Const mutate $8 = Binary read x$7 < read $6
24 + [3] Const mutate $8 = Binary read x$1 < read $6
25 If (read $8) then:bb4 else:bb2
26 bb4:
27 predecessor blocks: bb1
28 [4] Const mutate $9 = 1
30 - [5] Reassign mutate x$10 = Binary read x$7 + read $9
29 + [5] Reassign mutate x$1 = Binary read x$1 + read $9
30 Goto bb1
31 bb2:
32 predecessor blocks: bb1
34 - Return read x$7
33 + Return read x$1
34 ```
35
36 ## Code
37
38 ```javascript
39 function foo$0() {
41 - let x$5 = 0;
40 + let x$1 = 0;
41 }
42
43 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md
+13 -15
@@ -22,24 +22,22 @@ function foo() {
22
23 ```
24 bb0:
25 - [1] Let mutate x$6 = 1
26 - [2] Let mutate y$7 = 2
25 + [1] Let mutate x$1 = 1
26 + [2] Let mutate y$2 = 2
27 [3] Const mutate $8 = 1
28 - [4] Const mutate $9 = Binary read x$6 > read $8
28 + [4] Const mutate $9 = Binary read x$1 > read $8
29 If (read $9) then:bb2 else:bb3
30 bb2:
31 predecessor blocks: bb0
32 - [5] Reassign mutate x$10 = 2
32 + [5] Reassign mutate x$1 = 2
33 Goto bb1
34 bb3:
35 predecessor blocks: bb0
36 - [6] Reassign mutate y$11 = 3
36 + [6] Reassign mutate y$2 = 3
37 Goto bb1
38 bb1:
39 predecessor blocks: bb2 bb3
40 - x$12: phi(bb2: x$10, bb3: x$6)
41 - y$13: phi(bb2: y$7, bb3: y$11)
42 - [7] Let mutate t$14 = Object { x: read x$12, y: read y$13 }
40 + [7] Let mutate t$14 = Object { x: read x$1, y: read y$2 }
41 Return freeze t$14
42 ```
43
@@ -47,17 +45,17 @@ bb1:
45
46 ```javascript
47 function foo$0() {
50 - let x$6 = 1;
51 - let y$7 = 2;
52 - bb1: if (x$6 > 1) {
53 - x$10 = 2;
48 + let x$1 = 1;
49 + let y$2 = 2;
50 + bb1: if (x$1 > 1) {
51 + x$1 = 2;
52 } else {
55 - y$11 = 3;
53 + y$2 = 3;
54 }
55
56 let t$14 = {
59 - x: x$12,
60 - y: y$13,
57 + x: x$1,
58 + y: y$2,
59 };
60 return t$14;
61 }
compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md
+8 -9
@@ -17,30 +17,29 @@ function foo() {
17
18 ```
19 bb0:
20 - [1] Let mutate x$4 = 1
20 + [1] Let mutate x$1 = 1
21 [2] Const mutate $5 = 1
22 - [3] Const mutate $6 = Binary read x$4 === read $5
22 + [3] Const mutate $6 = Binary read x$1 === read $5
23 If (read $6) then:bb2 else:bb1
24 bb2:
25 predecessor blocks: bb0
26 - [4] Reassign mutate x$7 = 2
26 + [4] Reassign mutate x$1 = 2
27 Goto bb1
28 bb1:
29 predecessor blocks: bb2 bb0
30 - x$8: phi(bb2: x$7, bb0: x$4)
31 - Return read x$8
30 + Return read x$1
31 ```
32
33 ## Code
34
35 ```javascript
36 function foo$0() {
38 - let x$4 = 1;
39 - bb1: if (x$4 === 1) {
40 - x$7 = 2;
37 + let x$1 = 1;
38 + bb1: if (x$1 === 1) {
39 + x$1 = 2;
40 }
41
43 - return x$8;
42 + return x$1;
43 }
44
45 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md new
+73
@@ -0,0 +1,73 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function log() {}
6 +
7 +function Foo(cond) {
8 + let str = "";
9 + if (cond) {
10 + let str = "other test";
11 + log(str);
12 + } else {
13 + str = "fallthrough test";
14 + }
15 + log(str);
16 +}
17 +
18 +```
19 +
20 +## HIR
21 +
22 +```
23 +bb0:
24 + Return
25 +```
26 +
27 +## Code
28 +
29 +```javascript
30 +function log$0() {
31 + return;
32 +}
33 +
34 +```
35 +## HIR
36 +
37 +```
38 +bb0:
39 + [1] Let mutate str$2 = ""
40 + If (read cond$5) then:bb2 else:bb3
41 +bb2:
42 + predecessor blocks: bb0
43 + [2] Let mutate str$7 = "other test"
44 + [3] Call mutate log$4(read str$7)
45 + Goto bb1
46 +bb3:
47 + predecessor blocks: bb0
48 + [4] Reassign mutate str$2 = "fallthrough test"
49 + Goto bb1
50 +bb1:
51 + predecessor blocks: bb2 bb3
52 + [5] Call mutate log$4(read str$2)
53 + Return
54 +```
55 +
56 +## Code
57 +
58 +```javascript
59 +function Foo$0(cond$5) {
60 + let str$2 = "";
61 + bb1: if (cond$5) {
62 + let str$7 = "other test";
63 + log$4(str$7);
64 + } else {
65 + str$2 = "fallthrough test";
66 + }
67 +
68 + log$4(str$2);
69 + return;
70 +}
71 +
72 +```
73 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.js new
+12
@@ -0,0 +1,12 @@
1 +function log() {}
2 +
3 +function Foo(cond) {
4 + let str = "";
5 + if (cond) {
6 + let str = "other test";
7 + log(str);
8 + } else {
9 + str = "fallthrough test";
10 + }
11 + log(str);
12 +}
compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md
+6 -7
@@ -26,16 +26,15 @@ bb0:
26 If (read $7) then:bb2 else:bb3
27 bb2:
28 predecessor blocks: bb0
29 - [4] Reassign mutate y$8 = 1
29 + [4] Reassign mutate y$1 = 1
30 Goto bb1
31 bb3:
32 predecessor blocks: bb0
33 - [5] Reassign mutate y$9 = 2
33 + [5] Reassign mutate y$1 = 2
34 Goto bb1
35 bb1:
36 predecessor blocks: bb2 bb3
37 - y$10: phi(bb2: y$8, bb3: y$9)
38 - [6] Let mutate x$11 = read y$10
37 + [6] Let mutate x$11 = read y$1
38 Return
39 ```
40
@@ -45,12 +44,12 @@ bb1:
44 function foo$0() {
45 let y$5 = 2;
46 bb1: if (y$5 > 1) {
48 - y$8 = 1;
47 + y$1 = 1;
48 } else {
50 - y$9 = 2;
49 + y$1 = 2;
50 }
51
53 - let x$11 = y$10;
52 + let x$11 = y$1;
53 return;
54 }
55
compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md
+8 -9
@@ -40,22 +40,21 @@ bb0:
40 bb5:
41 predecessor blocks: bb0
42 [6] Const mutate $15 = 1
43 - [7] Reassign mutate x$16 = Binary read x$10 + read $15
43 + [7] Reassign mutate x$1 = Binary read x$10 + read $15
44 Goto bb1
45 bb3:
46 predecessor blocks: bb0
47 [8] Const mutate $17 = 2
48 - [9] Reassign mutate x$18 = Binary read x$10 + read $17
48 + [9] Reassign mutate x$1 = Binary read x$10 + read $17
49 Goto bb1
50 bb2:
51 predecessor blocks: bb0
52 [10] Const mutate $19 = 3
53 - [11] Reassign mutate x$20 = Binary read x$10 + read $19
53 + [11] Reassign mutate x$1 = Binary read x$10 + read $19
54 Goto bb1
55 bb1:
56 predecessor blocks: bb5 bb3 bb2
57 - x$21: phi(bb5: x$16, bb3: x$18, bb2: x$20)
58 - [12] Let mutate y$22 = read x$21
57 + [12] Let mutate y$22 = read x$1
58 Return
59 ```
60
@@ -66,21 +65,21 @@ function foo$0() {
65 let x$10 = 1;
66 bb1: switch (x$10) {
67 case x$10 === 1: {
69 - x$16 = x$10 + 1;
68 + x$1 = x$10 + 1;
69 break bb1;
70 }
71
72 case x$10 === 2: {
74 - x$18 = x$10 + 2;
73 + x$1 = x$10 + 2;
74 break bb1;
75 }
76
77 default: {
79 - x$20 = x$10 + 3;
78 + x$1 = x$10 + 3;
79 }
80 }
81
83 - let y$22 = x$21;
82 + let y$22 = x$1;
83 return;
84 }
85
compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md
+8 -9
@@ -16,30 +16,29 @@ function foo() {
16
17 ```
18 bb0:
19 - [1] Let mutate x$4 = 1
19 + [1] Let mutate x$1 = 1
20 [2] Const mutate $5 = 1
21 - [3] Const mutate $6 = Binary read x$4 === read $5
21 + [3] Const mutate $6 = Binary read x$1 === read $5
22 If (read $6) then:bb2 else:bb1
23 bb2:
24 predecessor blocks: bb0
25 - [4] Reassign mutate x$7 = 2
25 + [4] Reassign mutate x$1 = 2
26 Goto bb1
27 bb1:
28 predecessor blocks: bb2 bb0
29 - x$8: phi(bb2: x$7, bb0: x$4)
30 - Throw read x$8
29 + Throw read x$1
30 ```
31
32 ## Code
33
34 ```javascript
35 function foo$0() {
37 - let x$4 = 1;
38 - bb1: if (x$4 === 1) {
39 - x$7 = 2;
36 + let x$1 = 1;
37 + bb1: if (x$1 === 1) {
38 + x$1 = 2;
39 }
40
42 - throw x$8;
41 + throw x$1;
42 }
43
44 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md
+5 -6
@@ -17,29 +17,28 @@ function foo() {
17
18 ```
19 bb0:
20 - [1] Let mutate x$5 = 1
20 + [1] Let mutate x$1 = 1
21 Goto bb1
22 bb1:
23 predecessor blocks: bb0 bb3
24 - x$7: phi(bb0: x$5, bb3: x$10)
24 [2] Const mutate $6 = 10
26 - [3] Const mutate $8 = Binary read x$7 < read $6
25 + [3] Const mutate $8 = Binary read x$1 < read $6
26 If (read $8) then:bb3 else:bb2
27 bb3:
28 predecessor blocks: bb1
29 [4] Const mutate $9 = 1
31 - [5] Reassign mutate x$10 = Binary read x$7 + read $9
30 + [5] Reassign mutate x$1 = Binary read x$1 + read $9
31 Goto bb1
32 bb2:
33 predecessor blocks: bb1
35 - Return read x$7
34 + Return read x$1
35 ```
36
37 ## Code
38
39 ```javascript
40 function foo$0() {
42 - let x$5 = 1;
41 + let x$1 = 1;
42 }
43
44 ```
compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md
+10 -11
@@ -33,7 +33,7 @@ function Component(props) {
33 ```
34 bb0:
35 [1] Let mutate x$10[1:6] = Array []
36 - [2] Let mutate y$11 = undefined
36 + [2] Let mutate y$3 = undefined
37 [3] Const mutate $12 = false
38 [4] Const mutate $13 = true
39 [5] Const mutate $14 = 1
@@ -45,18 +45,17 @@ bb0:
45 bb6:
46 predecessor blocks: bb0
47 [6] Call mutate x$10.push(read props$9.p2)
48 - [7] Reassign mutate y$15 = Array []
48 + [7] Reassign mutate y$3 = Array []
49 Goto bb1
50 bb2:
51 predecessor blocks: bb0
52 - [8] Reassign mutate y$16 = read x$10
52 + [8] Reassign mutate y$3 = read x$10
53 Goto bb1
54 bb1:
55 predecessor blocks: bb0 bb6 bb2
56 - y$20: phi(bb0: y$11, bb6: y$15, bb2: y$16)
56 [9] Const mutate child$19 = JSX <read Component$0 data={freeze x$10} ></read Component$0>
58 - [10] Call read y$20.push(read props$9.p4)
59 - [11] Const mutate $22 = JSX <read Component$0 data={freeze y$20} >{read child$19}</read Component$0>
57 + [10] Call read y$3.push(read props$9.p4)
58 + [11] Const mutate $22 = JSX <read Component$0 data={freeze y$3} >{read child$19}</read Component$0>
59 Return read $22
60 ```
61
@@ -65,7 +64,7 @@ bb1:
64 ```javascript
65 function Component$0(props$9) {
66 let x$10 = [];
68 - let y$11 = undefined;
67 + let y$3 = undefined;
68 bb1: switch (props$9.p0) {
69 case 1: {
70 break bb1;
@@ -73,7 +72,7 @@ function Component$0(props$9) {
72
73 case true: {
74 x$10.push(props$9.p2);
76 - y$15 = [];
75 + y$3 = [];
76 break bb1;
77 }
78
@@ -82,13 +81,13 @@ function Component$0(props$9) {
81 }
82
83 case false: {
85 - y$16 = x$10;
84 + y$3 = x$10;
85 }
86 }
87
88 const child$19 = <Component$0 data={x$10}></Component$0>;
90 - y$20.push(props$9.p4);
91 - return <Component$0 data={y$20}>{child$19}</Component$0>;
89 + y$3.push(props$9.p4);
90 + return <Component$0 data={y$3}>{child$19}</Component$0>;
91 }
92
93 ```
compiler/forget/src/__tests__/fixtures/hir/switch.expect.md
+8 -9
@@ -29,7 +29,7 @@ function Component(props) {
29 ```
30 bb0:
31 [1] Let mutate x$9[1:6] = Array []
32 - [2] Let mutate y$10 = undefined
32 + [2] Let mutate y$3 = undefined
33 [3] Const mutate $11 = false
34 [4] Const mutate $12 = true
35 Switch (read props$8.p0)
@@ -44,14 +44,13 @@ bb4:
44 Goto bb2
45 bb2:
46 predecessor blocks: bb4 bb0
47 - [8] Reassign mutate y$15 = read x$9
47 + [8] Reassign mutate y$3 = read x$9
48 Goto bb1
49 bb1:
50 predecessor blocks: bb2 bb0
51 - y$20: phi(bb2: y$15, bb0: y$10)
51 [9] Const mutate child$19 = JSX <read Component$0 data={freeze x$9} ></read Component$0>
53 - [10] Call read y$20.push(read props$8.p4)
54 - [11] Const mutate $23 = JSX <read Component$0 data={read y$20} >{read child$19}</read Component$0>
52 + [10] Call read y$3.push(read props$8.p4)
53 + [11] Const mutate $23 = JSX <read Component$0 data={read y$3} >{read child$19}</read Component$0>
54 Return read $23
55 ```
56
@@ -60,7 +59,7 @@ bb1:
59 ```javascript
60 function Component$0(props$8) {
61 let x$9 = [];
63 - let y$10 = undefined;
62 + let y$3 = undefined;
63 bb1: switch (props$8.p0) {
64 case true: {
65 x$9.push(props$8.p2);
@@ -69,13 +68,13 @@ function Component$0(props$8) {
68 }
69
70 case false: {
72 - y$15 = x$9;
71 + y$3 = x$9;
72 }
73 }
74
75 const child$19 = <Component$0 data={x$9}></Component$0>;
77 - y$20.push(props$8.p4);
78 - return <Component$0 data={y$20}>{child$19}</Component$0>;
76 + y$3.push(props$8.p4);
77 + return <Component$0 data={y$3}>{child$19}</Component$0>;
78 }
79
80 ```
compiler/forget/src/__tests__/hir-test.ts
+2
@@ -22,6 +22,7 @@ import { HIRFunction } from "../HIR/HIR";
22 import { Environment } from "../HIR/HIRBuilder";
23 import { inferMutableRanges } from "../HIR/InferMutableLifetimes";
24 import inferReferenceEffects from "../HIR/InferReferenceEffects";
25 +import leaveSSA from "../HIR/LeaveSSA";
26 import printHIR from "../HIR/PrintHIR";
27 import generateTestsFromFixtures from "./test-utils/generateTestsFromFixtures";
28
@@ -68,6 +69,7 @@ describe("React Forget (HIR version)", () => {
69 eliminateRedundantPhi(ir);
70 inferReferenceEffects(ir);
71 inferMutableRanges(ir);
72 + leaveSSA(ir);
73 // const lifetimeGraph = buildDefUseGraph(ir);
74 const textHIR = printHIR(ir.body);
75 // const textLifetimeGraph = printGraph(lifetimeGraph);