@samitouri / QOS-React-2 / commits / 584eff2d38

[hir] Handle simple aliases when inferring mutable lifetimes (#794)

Sathya Gunasekaran committed Nov 21, 2022 at 18:35 UTC 584eff2d38670dcfb98d947b3db39dfb06f6cabb
14 files changed +458 -125
compiler/forget/src/HIR/InferMutableLifetimes.ts
+59 -1
@@ -7,7 +7,8 @@
7
8 import invariant from "invariant";
9 import { assertExhaustive } from "../Common/utils";
10 -import { Effect, HIRFunction, Instruction, Place } from "./HIR";
10 +import DisjointSet from "./DisjointSet";
11 +import { Effect, HIRFunction, Identifier, Instruction, Place } from "./HIR";
12 import { printInstruction, printPlace } from "./PrintHIR";
13 import { eachInstructionOperand } from "./visitors";
14
@@ -76,6 +77,8 @@ function inferPlace(place: Place, instr: Instruction) {
77 }
78
79 export function inferMutableRanges(func: HIRFunction) {
80 + const aliases = new DisjointSet<Identifier>();
81 +
82 for (const [_, block] of func.body.blocks) {
83 for (const phi of block.phis) {
84 let start = Number.MAX_SAFE_INTEGER;
@@ -100,6 +103,20 @@ export function inferMutableRanges(func: HIRFunction) {
103 }
104
105 if (instr.lvalue !== null) {
106 + if (instr.value.kind === "Identifier") {
107 + // TODO(gsn): Handle complex aliasing.
108 + if (
109 + instr.value.memberPath === null &&
110 + instr.lvalue.place.memberPath === null
111 + ) {
112 + // direct aliasing: `a = b`;
113 + aliases.union([
114 + instr.lvalue.place.identifier,
115 + instr.value.identifier,
116 + ]);
117 + }
118 + }
119 +
120 if (instr.lvalue.place.memberPath === null) {
121 const lvalueId = instr.lvalue.place.identifier;
122
@@ -116,4 +133,45 @@ export function inferMutableRanges(func: HIRFunction) {
133 }
134 }
135 }
136 +
137 + const aliasIds: Map<Identifier, number> = new Map();
138 + // Store the mutable range and set of identifiers for each scope
139 + const aliasIndentifiers: Map<
140 + number,
141 + { end: number; identifiers: Set<Identifier> }
142 + > = new Map();
143 +
144 + aliases.forEach((identifier, groupIdentifier) => {
145 + let aliasId = aliasIds.get(groupIdentifier);
146 + if (aliasId == null) {
147 + aliasId = aliasIds.size;
148 + aliasIds.set(groupIdentifier, aliasId);
149 + }
150 +
151 + let alias = aliasIndentifiers.get(aliasId);
152 + if (alias === undefined) {
153 + alias = {
154 + end: identifier.mutableRange.end,
155 + identifiers: new Set(),
156 + };
157 + aliasIndentifiers.set(aliasId, alias);
158 + } else {
159 + alias.end = Math.max(alias.end, identifier.mutableRange.end);
160 + }
161 + alias.identifiers.add(identifier);
162 + });
163 +
164 + for (const [_, alias] of aliasIndentifiers) {
165 + // Update mutableRange.end only if the identifiers have actually been
166 + // mutated.
167 + const haveIdentifiersBeenMutated = [...alias.identifiers].some(
168 + (id) => id.mutableRange.end > id.mutableRange.start
169 + );
170 +
171 + if (haveIdentifiersBeenMutated) {
172 + for (const identifier of alias.identifiers) {
173 + identifier.mutableRange.end = alias.end;
174 + }
175 + }
176 + }
177 }
compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md new
+148
@@ -0,0 +1,148 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function foo(cond) {
6 + let a = {};
7 + let b = {};
8 + let c = {};
9 + while (cond) {
10 + let z = a;
11 + a = b;
12 + b = c;
13 + c = z;
14 + mutate(a, b);
15 + }
16 + a;
17 + b;
18 + c;
19 + return a;
20 +}
21 +
22 +function mutate(x, y) {}
23 +
24 +```
25 +
26 +## HIR
27 +
28 +```
29 +bb0:
30 + [1] Let mutate a$2_@0[0:8] = Object { }
31 + [2] Let mutate b$3_@0[0:8] = Object { }
32 + [3] Let mutate c$4_@0[0:8] = Object { }
33 + While test=bb1 loop=bb3 fallthrough=bb2
34 +bb1:
35 + predecessor blocks: bb0 bb3
36 + If (read cond$1) then:bb3 else:bb2
37 +bb3:
38 + predecessor blocks: bb1
39 + [4] Let mutate z$5_@0[0:8] = read a$2_@0
40 + [5] Reassign mutate a$2_@0[0:8] = read b$3_@0
41 + [6] Reassign mutate b$3_@0[0:8] = read c$4_@0
42 + [7] Reassign mutate c$4_@0[0:8] = read z$5_@0
43 + [8] Call mutate mutate$6_@0(mutate a$2_@0, mutate b$3_@0)
44 + Goto(Continue) bb1
45 +bb2:
46 + predecessor blocks: bb1
47 + [9] read a$2_@0
48 + [10] read b$3_@0
49 + [11] read c$4_@0
50 + Return freeze a$2_@0
51 +```
52 +
53 +### CFG
54 +
55 +```mermaid
56 +flowchart TB
57 + %% Basic Blocks
58 + subgraph bb0
59 + bb0_instrs["
60 + [1] Let mutate a$2_@0[0:8] = Object { }
61 + [2] Let mutate b$3_@0[0:8] = Object { }
62 + [3] Let mutate c$4_@0[0:8] = Object { }
63 + "]
64 + bb0_instrs --> bb0_terminal(["While"])
65 + end
66 + subgraph bb1
67 + bb1_terminal(["If (read cond$1)"])
68 + end
69 + subgraph bb3
70 + bb3_instrs["
71 + [4] Let mutate z$5_@0[0:8] = read a$2_@0
72 + [5] Reassign mutate a$2_@0[0:8] = read b$3_@0
73 + [6] Reassign mutate b$3_@0[0:8] = read c$4_@0
74 + [7] Reassign mutate c$4_@0[0:8] = read z$5_@0
75 + [8] Call mutate mutate$6_@0(mutate a$2_@0, mutate b$3_@0)
76 + "]
77 + bb3_instrs --> bb3_terminal(["Goto"])
78 + end
79 + subgraph bb2
80 + bb2_instrs["
81 + [9] read a$2_@0
82 + [10] read b$3_@0
83 + [11] read c$4_@0
84 + "]
85 + bb2_instrs --> bb2_terminal(["Return freeze a$2_@0"])
86 + end
87 +
88 + %% Jumps
89 + bb0_terminal -- "test" --> bb1
90 + bb0_terminal -- "loop" --> bb3
91 + bb0_terminal -- "fallthrough" --> bb2
92 + bb1_terminal -- "then" --> bb3
93 + bb1_terminal -- "else" --> bb2
94 + bb3_terminal --> bb1
95 +
96 +```
97 +
98 +## Code
99 +
100 +```javascript
101 +function foo$0(cond$1) {
102 + let a$2 = {};
103 + let b$3 = {};
104 + let c$4 = {};
105 + bb2: while (cond$1) {
106 + let z$5 = a$2;
107 + a$2 = b$3;
108 + b$3 = c$4;
109 + c$4 = z$5;
110 + mutate$6(a$2, b$3);
111 + }
112 +
113 + a$2;
114 + b$3;
115 + c$4;
116 + return a$2;
117 +}
118 +
119 +```
120 +## HIR
121 +
122 +```
123 +bb0:
124 + Return
125 +```
126 +
127 +### CFG
128 +
129 +```mermaid
130 +flowchart TB
131 + %% Basic Blocks
132 + subgraph bb0
133 + bb0_terminal(["Return"])
134 + end
135 +
136 + %% Jumps
137 + %% empty
138 +```
139 +
140 +## Code
141 +
142 +```javascript
143 +function mutate$0(x$1, y$2) {
144 + return;
145 +}
146 +
147 +```
148 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/alias-while.js new
+18
@@ -0,0 +1,18 @@
1 +function foo(cond) {
2 + let a = {};
3 + let b = {};
4 + let c = {};
5 + while (cond) {
6 + let z = a;
7 + a = b;
8 + b = c;
9 + c = z;
10 + mutate(a, b);
11 + }
12 + a;
13 + b;
14 + c;
15 + return a;
16 +}
17 +
18 +function mutate(x, y) {}
compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md
+20 -20
@@ -101,20 +101,20 @@ function cond$0(x$1) {
101 bb0:
102 [1] Let mutate a$2_@0[0:14] = Object { }
103 [2] Let mutate b$3_@0[0:14] = Object { }
104 - [3] Let mutate c$4_@1[0:9] = Object { }
104 + [3] Let mutate c$4_@0[0:14] = Object { }
105 [4] Let mutate d$5_@0[0:14] = Object { }
106 While test=bb1 loop=bb3 fallthrough=bb2
107 bb1:
108 predecessor blocks: bb0 bb4
109 - [5] Const mutate $10_@2 = true
110 - If (read $10_@2) then:bb3 else:bb2
109 + [5] Const mutate $10_@1 = true
110 + If (read $10_@1) then:bb3 else:bb2
111 bb3:
112 predecessor blocks: bb1
113 - [6] Let mutate z$6_@3 = read a$2_@0
113 + [6] Let mutate z$6_@0[0:14] = read a$2_@0
114 [7] Reassign mutate a$2_@0[0:14] = read b$3_@0
115 - [8] Reassign mutate b$3_@0[0:14] = read c$4_@1
116 - [9] Reassign mutate c$4_@1[0:9] = read d$5_@0
117 - [10] Reassign mutate d$5_@0[0:14] = read z$6_@3
115 + [8] Reassign mutate b$3_@0[0:14] = read c$4_@0
116 + [9] Reassign mutate c$4_@0[0:14] = read d$5_@0
117 + [10] Reassign mutate d$5_@0[0:14] = read z$6_@0
118 [11] Call mutate mutate$7_@0(mutate a$2_@0, mutate b$3_@0)
119 [12] Const mutate $9_@0[0:14] = Call mutate cond$8_@0(mutate a$2_@0)
120 If (read $9_@0) then:bb2 else:bb4
@@ -129,14 +129,14 @@ bb7:
129 If (read b$3_@0) then:bb9 else:bb9
130 bb9:
131 predecessor blocks: bb7
132 - If (read c$4_@1) then:bb11 else:bb11
132 + If (read c$4_@0) then:bb11 else:bb11
133 bb11:
134 predecessor blocks: bb9
135 If (read d$5_@0) then:bb13 else:bb13
136 bb13:
137 predecessor blocks: bb11
138 - [13] Const mutate $11_@4 = null
139 - [14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@4)
138 + [13] Const mutate $11_@2 = null
139 + [14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@2)
140 Return
141 ```
142
@@ -149,24 +149,24 @@ flowchart TB
149 bb0_instrs["
150 [1] Let mutate a$2_@0[0:14] = Object { }
151 [2] Let mutate b$3_@0[0:14] = Object { }
152 - [3] Let mutate c$4_@1[0:9] = Object { }
152 + [3] Let mutate c$4_@0[0:14] = Object { }
153 [4] Let mutate d$5_@0[0:14] = Object { }
154 "]
155 bb0_instrs --> bb0_terminal(["While"])
156 end
157 subgraph bb1
158 bb1_instrs["
159 - [5] Const mutate $10_@2 = true
159 + [5] Const mutate $10_@1 = true
160 "]
161 - bb1_instrs --> bb1_terminal(["If (read $10_@2)"])
161 + bb1_instrs --> bb1_terminal(["If (read $10_@1)"])
162 end
163 subgraph bb3
164 bb3_instrs["
165 - [6] Let mutate z$6_@3 = read a$2_@0
165 + [6] Let mutate z$6_@0[0:14] = read a$2_@0
166 [7] Reassign mutate a$2_@0[0:14] = read b$3_@0
167 - [8] Reassign mutate b$3_@0[0:14] = read c$4_@1
168 - [9] Reassign mutate c$4_@1[0:9] = read d$5_@0
169 - [10] Reassign mutate d$5_@0[0:14] = read z$6_@3
167 + [8] Reassign mutate b$3_@0[0:14] = read c$4_@0
168 + [9] Reassign mutate c$4_@0[0:14] = read d$5_@0
169 + [10] Reassign mutate d$5_@0[0:14] = read z$6_@0
170 [11] Call mutate mutate$7_@0(mutate a$2_@0, mutate b$3_@0)
171 [12] Const mutate $9_@0[0:14] = Call mutate cond$8_@0(mutate a$2_@0)
172 "]
@@ -182,15 +182,15 @@ flowchart TB
182 bb7_terminal(["If (read b$3_@0)"])
183 end
184 subgraph bb9
185 - bb9_terminal(["If (read c$4_@1)"])
185 + bb9_terminal(["If (read c$4_@0)"])
186 end
187 subgraph bb11
188 bb11_terminal(["If (read d$5_@0)"])
189 end
190 subgraph bb13
191 bb13_instrs["
192 - [13] Const mutate $11_@4 = null
193 - [14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@4)
192 + [13] Const mutate $11_@2 = null
193 + [14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@2)
194 "]
195 bb13_instrs --> bb13_terminal(["Return"])
196 end
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+10 -10
@@ -25,7 +25,7 @@ function Component(props) {
25 bb0:
26 [1] Let mutate x$2_@0[1:4] = Array []
27 [2] Call mutate x$2_@0.push(read props$1.p0)
28 - [3] Let mutate y$3_@1 = read x$2_@0
28 + [3] Let mutate y$3_@0[1:4] = read x$2_@0
29 If (read props$1.p1) then:bb2 else:bb1
30 bb2:
31 predecessor blocks: bb0
@@ -33,10 +33,10 @@ bb2:
33 Goto bb1
34 bb1:
35 predecessor blocks: bb2 bb0
36 - [5] Let mutate _$4_@2 = JSX <read Component$0 x={freeze x$2_@0} ></read Component$0>
37 - [6] Call read y$3_@1.push(read props$1.p2)
38 - [7] Const mutate $5_@3 = JSX <read Component$0 x={read x$2_@0} y={read y$3_@1} ></read Component$0>
39 - Return read $5_@3
36 + [5] Let mutate _$4_@1 = JSX <read Component$0 x={freeze x$2_@0} ></read Component$0>
37 + [6] Call read y$3_@0.push(read props$1.p2)
38 + [7] Const mutate $5_@2 = JSX <read Component$0 x={read x$2_@0} y={read y$3_@0} ></read Component$0>
39 + Return read $5_@2
40 ```
41
42 ### CFG
@@ -48,7 +48,7 @@ flowchart TB
48 bb0_instrs["
49 [1] Let mutate x$2_@0[1:4] = Array []
50 [2] Call mutate x$2_@0.push(read props$1.p0)
51 - [3] Let mutate y$3_@1 = read x$2_@0
51 + [3] Let mutate y$3_@0[1:4] = read x$2_@0
52 "]
53 bb0_instrs --> bb0_terminal(["If (read props$1.p1)"])
54 end
@@ -60,11 +60,11 @@ flowchart TB
60 end
61 subgraph bb1
62 bb1_instrs["
63 - [5] Let mutate _$4_@2 = JSX <read Component$0 x={freeze x$2_@0} ></read Component$0>
64 - [6] Call read y$3_@1.push(read props$1.p2)
65 - [7] Const mutate $5_@3 = JSX <read Component$0 x={read x$2_@0} y={read y$3_@1} ></read Component$0>
63 + [5] Let mutate _$4_@1 = JSX <read Component$0 x={freeze x$2_@0} ></read Component$0>
64 + [6] Call read y$3_@0.push(read props$1.p2)
65 + [7] Const mutate $5_@2 = JSX <read Component$0 x={read x$2_@0} y={read y$3_@0} ></read Component$0>
66 "]
67 - bb1_instrs --> bb1_terminal(["Return read $5_@3"])
67 + bb1_instrs --> bb1_terminal(["Return read $5_@2"])
68 end
69
70 %% Jumps
compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md
+14 -14
@@ -21,14 +21,14 @@ function Component(props) {
21
22 ```
23 bb0:
24 - [1] Let mutate x$2_@0[1:2] = Array []
24 + [1] Let mutate x$2_@0[1:6] = Array []
25 [2] Call mutate x$2_@0.push(read props$1.p0)
26 - [3] Let mutate y$3_@1[3:6] = read x$2_@0
27 - [4] Reassign mutate x$2_@2 = Array []
28 - [5] Let mutate _$4_@3 = JSX <read Component$0 x={freeze x$2_@2} ></read Component$0>
29 - [6] Call mutate y$3_@1.push(read props$1.p1)
30 - [7] Const mutate $5_@4 = JSX <read Component$0 x={read x$2_@2} y={freeze y$3_@1} ></read Component$0>
31 - Return read $5_@4
26 + [3] Let mutate y$3_@0[1:6] = read x$2_@0
27 + [4] Reassign mutate x$2_@1 = Array []
28 + [5] Let mutate _$4_@2 = JSX <read Component$0 x={freeze x$2_@1} ></read Component$0>
29 + [6] Call mutate y$3_@0.push(read props$1.p1)
30 + [7] Const mutate $5_@3 = JSX <read Component$0 x={read x$2_@1} y={freeze y$3_@0} ></read Component$0>
31 + Return read $5_@3
32 ```
33
34 ### CFG
@@ -38,15 +38,15 @@ flowchart TB
38 %% Basic Blocks
39 subgraph bb0
40 bb0_instrs["
41 - [1] Let mutate x$2_@0[1:2] = Array []
41 + [1] Let mutate x$2_@0[1:6] = Array []
42 [2] Call mutate x$2_@0.push(read props$1.p0)
43 - [3] Let mutate y$3_@1[3:6] = read x$2_@0
44 - [4] Reassign mutate x$2_@2 = Array []
45 - [5] Let mutate _$4_@3 = JSX <read Component$0 x={freeze x$2_@2} ></read Component$0>
46 - [6] Call mutate y$3_@1.push(read props$1.p1)
47 - [7] Const mutate $5_@4 = JSX <read Component$0 x={read x$2_@2} y={freeze y$3_@1} ></read Component$0>
43 + [3] Let mutate y$3_@0[1:6] = read x$2_@0
44 + [4] Reassign mutate x$2_@1 = Array []
45 + [5] Let mutate _$4_@2 = JSX <read Component$0 x={freeze x$2_@1} ></read Component$0>
46 + [6] Call mutate y$3_@0.push(read props$1.p1)
47 + [7] Const mutate $5_@3 = JSX <read Component$0 x={read x$2_@1} y={freeze y$3_@0} ></read Component$0>
48 "]
49 - bb0_instrs --> bb0_terminal(["Return read $5_@4"])
49 + bb0_instrs --> bb0_terminal(["Return read $5_@3"])
50 end
51
52 %% Jumps
compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md new
+98
@@ -0,0 +1,98 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function mutate() {}
6 +function foo() {
7 + let a = {};
8 + let b = {};
9 + let c = {};
10 + a = b;
11 + b = c;
12 + c = a;
13 + mutate(a, b);
14 + return c;
15 +}
16 +
17 +```
18 +
19 +## HIR
20 +
21 +```
22 +bb0:
23 + Return
24 +```
25 +
26 +### CFG
27 +
28 +```mermaid
29 +flowchart TB
30 + %% Basic Blocks
31 + subgraph bb0
32 + bb0_terminal(["Return"])
33 + end
34 +
35 + %% Jumps
36 + %% empty
37 +```
38 +
39 +## Code
40 +
41 +```javascript
42 +function mutate$0() {
43 + return;
44 +}
45 +
46 +```
47 +## HIR
48 +
49 +```
50 +bb0:
51 + [1] Let mutate a$1_@0 = Object { }
52 + [2] Let mutate b$2_@1[0:7] = Object { }
53 + [3] Let mutate c$3_@1[0:7] = Object { }
54 + [4] Reassign mutate a$1_@1[0:7] = read b$2_@1
55 + [5] Reassign mutate b$2_@1[0:7] = read c$3_@1
56 + [6] Reassign mutate c$3_@1[0:7] = read a$1_@1
57 + [7] Call mutate mutate$4_@1(mutate a$1_@1, mutate b$2_@1)
58 + Return freeze c$3_@1
59 +```
60 +
61 +### CFG
62 +
63 +```mermaid
64 +flowchart TB
65 + %% Basic Blocks
66 + subgraph bb0
67 + bb0_instrs["
68 + [1] Let mutate a$1_@0 = Object { }
69 + [2] Let mutate b$2_@1[0:7] = Object { }
70 + [3] Let mutate c$3_@1[0:7] = Object { }
71 + [4] Reassign mutate a$1_@1[0:7] = read b$2_@1
72 + [5] Reassign mutate b$2_@1[0:7] = read c$3_@1
73 + [6] Reassign mutate c$3_@1[0:7] = read a$1_@1
74 + [7] Call mutate mutate$4_@1(mutate a$1_@1, mutate b$2_@1)
75 + "]
76 + bb0_instrs --> bb0_terminal(["Return freeze c$3_@1"])
77 + end
78 +
79 + %% Jumps
80 + %% empty
81 +```
82 +
83 +## Code
84 +
85 +```javascript
86 +function foo$0() {
87 + let a$1 = {};
88 + let b$2 = {};
89 + let c$3 = {};
90 + a$1 = b$2;
91 + b$2 = c$3;
92 + c$3 = a$1;
93 + mutate$4(a$1, b$2);
94 + return c$3;
95 +}
96 +
97 +```
98 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/simple-alias.js new
+11
@@ -0,0 +1,11 @@
1 +function mutate() {}
2 +function foo() {
3 + let a = {};
4 + let b = {};
5 + let c = {};
6 + a = b;
7 + b = c;
8 + c = a;
9 + mutate(a, b);
10 + return c;
11 +}
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md
+8 -8
@@ -21,14 +21,14 @@ function foo() {
21
22 ```
23 bb0:
24 - [1] Let mutate x$1_@0[1:8] = 1
24 + [1] Let mutate x$1_@0[1:9] = 1
25 [2] Let mutate y$2_@1 = 2
26 [3] Const mutate $3_@2 = 2
27 [4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2
28 If (read $4_@3) then:bb2 else:bb1
29 bb2:
30 predecessor blocks: bb0
31 - [5] Reassign mutate x$1_@0[1:8] = 3
31 + [5] Reassign mutate x$1_@0[1:9] = 3
32 Goto bb1
33 bb1:
34 predecessor blocks: bb2 bb0
@@ -37,11 +37,11 @@ bb1:
37 If (read $6_@5) then:bb4 else:bb3
38 bb4:
39 predecessor blocks: bb1
40 - [8] Reassign mutate x$1_@0[1:8] = 5
40 + [8] Reassign mutate x$1_@0[1:9] = 5
41 Goto bb3
42 bb3:
43 predecessor blocks: bb4 bb1
44 - [9] Reassign mutate y$2_@6 = read x$1_@0
44 + [9] Reassign mutate y$2_@0[1:9] = read x$1_@0
45 Return
46 ```
47
@@ -52,7 +52,7 @@ flowchart TB
52 %% Basic Blocks
53 subgraph bb0
54 bb0_instrs["
55 - [1] Let mutate x$1_@0[1:8] = 1
55 + [1] Let mutate x$1_@0[1:9] = 1
56 [2] Let mutate y$2_@1 = 2
57 [3] Const mutate $3_@2 = 2
58 [4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2
@@ -61,7 +61,7 @@ flowchart TB
61 end
62 subgraph bb2
63 bb2_instrs["
64 - [5] Reassign mutate x$1_@0[1:8] = 3
64 + [5] Reassign mutate x$1_@0[1:9] = 3
65 "]
66 bb2_instrs --> bb2_terminal(["Goto"])
67 end
@@ -74,13 +74,13 @@ flowchart TB
74 end
75 subgraph bb4
76 bb4_instrs["
77 - [8] Reassign mutate x$1_@0[1:8] = 5
77 + [8] Reassign mutate x$1_@0[1:9] = 5
78 "]
79 bb4_instrs --> bb4_terminal(["Goto"])
80 end
81 subgraph bb3
82 bb3_instrs["
83 - [9] Reassign mutate y$2_@6 = read x$1_@0
83 + [9] Reassign mutate y$2_@0[1:9] = read x$1_@0
84 "]
85 bb3_instrs --> bb3_terminal(["Return"])
86 end
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md
+6 -6
@@ -18,18 +18,18 @@ function foo() {
18
19 ```
20 bb0:
21 - [1] Let mutate x$1_@0[1:5] = 1
21 + [1] Let mutate x$1_@0[1:6] = 1
22 [2] Let mutate y$2_@1 = 2
23 [3] Const mutate $3_@2 = 2
24 [4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2
25 If (read $4_@3) then:bb2 else:bb1
26 bb2:
27 predecessor blocks: bb0
28 - [5] Reassign mutate x$1_@0[1:5] = 3
28 + [5] Reassign mutate x$1_@0[1:6] = 3
29 Goto bb1
30 bb1:
31 predecessor blocks: bb2 bb0
32 - [6] Reassign mutate y$2_@4 = read x$1_@0
32 + [6] Reassign mutate y$2_@0[1:6] = read x$1_@0
33 Return
34 ```
35
@@ -40,7 +40,7 @@ flowchart TB
40 %% Basic Blocks
41 subgraph bb0
42 bb0_instrs["
43 - [1] Let mutate x$1_@0[1:5] = 1
43 + [1] Let mutate x$1_@0[1:6] = 1
44 [2] Let mutate y$2_@1 = 2
45 [3] Const mutate $3_@2 = 2
46 [4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2
@@ -49,13 +49,13 @@ flowchart TB
49 end
50 subgraph bb2
51 bb2_instrs["
52 - [5] Reassign mutate x$1_@0[1:5] = 3
52 + [5] Reassign mutate x$1_@0[1:6] = 3
53 "]
54 bb2_instrs --> bb2_terminal(["Goto"])
55 end
56 subgraph bb1
57 bb1_instrs["
58 - [6] Reassign mutate y$2_@4 = read x$1_@0
58 + [6] Reassign mutate y$2_@0[1:6] = read x$1_@0
59 "]
60 bb1_instrs --> bb1_terminal(["Return"])
61 end
compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md
+6 -6
@@ -26,15 +26,15 @@ bb0:
26 If (read $3_@2) then:bb2 else:bb3
27 bb2:
28 predecessor blocks: bb0
29 - [4] Reassign mutate y$1_@3[4:5] = 1
29 + [4] Reassign mutate y$1_@3[4:6] = 1
30 Goto bb1
31 bb3:
32 predecessor blocks: bb0
33 - [5] Reassign mutate y$1_@3[4:5] = 2
33 + [5] Reassign mutate y$1_@3[4:6] = 2
34 Goto bb1
35 bb1:
36 predecessor blocks: bb2 bb3
37 - [6] Let mutate x$4_@4 = read y$1_@3
37 + [6] Let mutate x$4_@3[4:6] = read y$1_@3
38 Return
39 ```
40
@@ -53,19 +53,19 @@ flowchart TB
53 end
54 subgraph bb2
55 bb2_instrs["
56 - [4] Reassign mutate y$1_@3[4:5] = 1
56 + [4] Reassign mutate y$1_@3[4:6] = 1
57 "]
58 bb2_instrs --> bb2_terminal(["Goto"])
59 end
60 subgraph bb3
61 bb3_instrs["
62 - [5] Reassign mutate y$1_@3[4:5] = 2
62 + [5] Reassign mutate y$1_@3[4:6] = 2
63 "]
64 bb3_instrs --> bb3_terminal(["Goto"])
65 end
66 subgraph bb1
67 bb1_instrs["
68 - [6] Let mutate x$4_@4 = read y$1_@3
68 + [6] Let mutate x$4_@3[4:6] = read y$1_@3
69 "]
70 bb1_instrs --> bb1_terminal(["Return"])
71 end
compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md
+8 -8
@@ -40,21 +40,21 @@ bb0:
40 bb5:
41 predecessor blocks: bb0
42 [6] Const mutate $6_@5 = 1
43 - [7] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $6_@5
43 + [7] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $6_@5
44 Goto bb1
45 bb3:
46 predecessor blocks: bb0
47 [8] Const mutate $3_@7 = 2
48 - [9] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $3_@7
48 + [9] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $3_@7
49 Goto bb1
50 bb2:
51 predecessor blocks: bb0
52 [10] Const mutate $2_@8 = 3
53 - [11] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $2_@8
53 + [11] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $2_@8
54 Goto bb1
55 bb1:
56 predecessor blocks: bb5 bb3 bb2
57 - [12] Let mutate y$9_@9 = read x$1_@6
57 + [12] Let mutate y$9_@6[7:12] = read x$1_@6
58 Return
59 ```
60
@@ -76,27 +76,27 @@ flowchart TB
76 subgraph bb5
77 bb5_instrs["
78 [6] Const mutate $6_@5 = 1
79 - [7] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $6_@5
79 + [7] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $6_@5
80 "]
81 bb5_instrs --> bb5_terminal(["Goto"])
82 end
83 subgraph bb3
84 bb3_instrs["
85 [8] Const mutate $3_@7 = 2
86 - [9] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $3_@7
86 + [9] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $3_@7
87 "]
88 bb3_instrs --> bb3_terminal(["Goto"])
89 end
90 subgraph bb2
91 bb2_instrs["
92 [10] Const mutate $2_@8 = 3
93 - [11] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $2_@8
93 + [11] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $2_@8
94 "]
95 bb2_instrs --> bb2_terminal(["Goto"])
96 end
97 subgraph bb1
98 bb1_instrs["
99 - [12] Let mutate y$9_@9 = read x$1_@6
99 + [12] Let mutate y$9_@6[7:12] = read x$1_@6
100 "]
101 bb1_instrs --> bb1_terminal(["Return"])
102 end
compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md
+28 -28
@@ -32,31 +32,31 @@ function Component(props) {
32
33 ```
34 bb0:
35 - [1] Let mutate x$2_@0[1:6] = Array []
36 - [2] Let mutate y$3_@1[2:8] = undefined
37 - [3] Const mutate $4_@2 = false
38 - [4] Const mutate $5_@3 = true
39 - [5] Const mutate $6_@4 = 1
35 + [1] Let mutate x$2_@0[1:8] = Array []
36 + [2] Let mutate y$3_@0[1:8] = undefined
37 + [3] Const mutate $4_@1 = false
38 + [4] Const mutate $5_@2 = true
39 + [5] Const mutate $6_@3 = 1
40 Switch (read props$1.p0)
41 - Case read $6_@4: bb1
42 - Case read $5_@3: bb6
41 + Case read $6_@3: bb1
42 + Case read $5_@2: bb6
43 Default: bb1
44 - Case read $4_@2: bb2
44 + Case read $4_@1: bb2
45 bb6:
46 predecessor blocks: bb0
47 [6] Call mutate x$2_@0.push(read props$1.p2)
48 - [7] Reassign mutate y$3_@1[2:8] = Array []
48 + [7] Reassign mutate y$3_@0[1:8] = Array []
49 Goto bb1
50 bb2:
51 predecessor blocks: bb0
52 - [8] Reassign mutate y$3_@1[2:8] = read x$2_@0
52 + [8] Reassign mutate y$3_@0[1:8] = read x$2_@0
53 Goto bb1
54 bb1:
55 predecessor blocks: bb0 bb6 bb2
56 - [9] Const mutate child$7_@5 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
57 - [10] Call read y$3_@1.push(read props$1.p4)
58 - [11] Const mutate $8_@6 = JSX <read Component$0 data={freeze y$3_@1} >{read child$7_@5}</read Component$0>
59 - Return read $8_@6
56 + [9] Const mutate child$7_@4 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
57 + [10] Call read y$3_@0.push(read props$1.p4)
58 + [11] Const mutate $8_@5 = JSX <read Component$0 data={freeze y$3_@0} >{read child$7_@4}</read Component$0>
59 + Return read $8_@5
60 ```
61
62 ### CFG
@@ -66,41 +66,41 @@ flowchart TB
66 %% Basic Blocks
67 subgraph bb0
68 bb0_instrs["
69 - [1] Let mutate x$2_@0[1:6] = Array []
70 - [2] Let mutate y$3_@1[2:8] = undefined
71 - [3] Const mutate $4_@2 = false
72 - [4] Const mutate $5_@3 = true
73 - [5] Const mutate $6_@4 = 1
69 + [1] Let mutate x$2_@0[1:8] = Array []
70 + [2] Let mutate y$3_@0[1:8] = undefined
71 + [3] Const mutate $4_@1 = false
72 + [4] Const mutate $5_@2 = true
73 + [5] Const mutate $6_@3 = 1
74 "]
75 bb0_instrs --> bb0_terminal(["Switch (read props$1.p0)"])
76 end
77 subgraph bb6
78 bb6_instrs["
79 [6] Call mutate x$2_@0.push(read props$1.p2)
80 - [7] Reassign mutate y$3_@1[2:8] = Array []
80 + [7] Reassign mutate y$3_@0[1:8] = Array []
81 "]
82 bb6_instrs --> bb6_terminal(["Goto"])
83 end
84 subgraph bb2
85 bb2_instrs["
86 - [8] Reassign mutate y$3_@1[2:8] = read x$2_@0
86 + [8] Reassign mutate y$3_@0[1:8] = read x$2_@0
87 "]
88 bb2_instrs --> bb2_terminal(["Goto"])
89 end
90 subgraph bb1
91 bb1_instrs["
92 - [9] Const mutate child$7_@5 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
93 - [10] Call read y$3_@1.push(read props$1.p4)
94 - [11] Const mutate $8_@6 = JSX <read Component$0 data={freeze y$3_@1} >{read child$7_@5}</read Component$0>
92 + [9] Const mutate child$7_@4 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
93 + [10] Call read y$3_@0.push(read props$1.p4)
94 + [11] Const mutate $8_@5 = JSX <read Component$0 data={freeze y$3_@0} >{read child$7_@4}</read Component$0>
95 "]
96 - bb1_instrs --> bb1_terminal(["Return read $8_@6"])
96 + bb1_instrs --> bb1_terminal(["Return read $8_@5"])
97 end
98
99 %% Jumps
100 - bb0_terminal -- "read $6_@4" --> bb1
101 - bb0_terminal -- "read $5_@3" --> bb6
100 + bb0_terminal -- "read $6_@3" --> bb1
101 + bb0_terminal -- "read $5_@2" --> bb6
102 bb0_terminal -- "default" --> bb1
103 - bb0_terminal -- "read $4_@2" --> bb2
103 + bb0_terminal -- "read $4_@1" --> bb2
104 bb0_terminal -- "fallthrough" --> bb1
105 bb6_terminal --> bb1
106 bb2_terminal --> bb1
compiler/forget/src/__tests__/fixtures/hir/switch.expect.md
+24 -24
@@ -28,30 +28,30 @@ function Component(props) {
28
29 ```
30 bb0:
31 - [1] Let mutate x$2_@0[1:6] = Array []
32 - [2] Let mutate y$3_@1[2:8] = undefined
33 - [3] Const mutate $4_@2 = false
34 - [4] Const mutate $5_@3 = true
31 + [1] Let mutate x$2_@0[1:8] = Array []
32 + [2] Let mutate y$3_@0[1:8] = undefined
33 + [3] Const mutate $4_@1 = false
34 + [4] Const mutate $5_@2 = true
35 Switch (read props$1.p0)
36 - Case read $5_@3: bb4
37 - Case read $4_@2: bb2
36 + Case read $5_@2: bb4
37 + Case read $4_@1: bb2
38 Default: bb1
39 bb4:
40 predecessor blocks: bb0
41 [5] Call mutate x$2_@0.push(read props$1.p2)
42 [6] Call mutate x$2_@0.push(read props$1.p3)
43 - [7] Reassign mutate y$3_@4 = Array []
43 + [7] Reassign mutate y$3_@3 = Array []
44 Goto bb2
45 bb2:
46 predecessor blocks: bb4 bb0
47 - [8] Reassign mutate y$3_@1[2:8] = read x$2_@0
47 + [8] Reassign mutate y$3_@0[1:8] = read x$2_@0
48 Goto bb1
49 bb1:
50 predecessor blocks: bb2 bb0
51 - [9] Const mutate child$6_@5 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
52 - [10] Call read y$3_@1.push(read props$1.p4)
53 - [11] Const mutate $7_@6 = JSX <read Component$0 data={read y$3_@1} >{read child$6_@5}</read Component$0>
54 - Return read $7_@6
51 + [9] Const mutate child$6_@4 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
52 + [10] Call read y$3_@0.push(read props$1.p4)
53 + [11] Const mutate $7_@5 = JSX <read Component$0 data={read y$3_@0} >{read child$6_@4}</read Component$0>
54 + Return read $7_@5
55 ```
56
57 ### CFG
@@ -61,10 +61,10 @@ flowchart TB
61 %% Basic Blocks
62 subgraph bb0
63 bb0_instrs["
64 - [1] Let mutate x$2_@0[1:6] = Array []
65 - [2] Let mutate y$3_@1[2:8] = undefined
66 - [3] Const mutate $4_@2 = false
67 - [4] Const mutate $5_@3 = true
64 + [1] Let mutate x$2_@0[1:8] = Array []
65 + [2] Let mutate y$3_@0[1:8] = undefined
66 + [3] Const mutate $4_@1 = false
67 + [4] Const mutate $5_@2 = true
68 "]
69 bb0_instrs --> bb0_terminal(["Switch (read props$1.p0)"])
70 end
@@ -72,28 +72,28 @@ flowchart TB
72 bb4_instrs["
73 [5] Call mutate x$2_@0.push(read props$1.p2)
74 [6] Call mutate x$2_@0.push(read props$1.p3)
75 - [7] Reassign mutate y$3_@4 = Array []
75 + [7] Reassign mutate y$3_@3 = Array []
76 "]
77 bb4_instrs --> bb4_terminal(["Goto"])
78 end
79 subgraph bb2
80 bb2_instrs["
81 - [8] Reassign mutate y$3_@1[2:8] = read x$2_@0
81 + [8] Reassign mutate y$3_@0[1:8] = read x$2_@0
82 "]
83 bb2_instrs --> bb2_terminal(["Goto"])
84 end
85 subgraph bb1
86 bb1_instrs["
87 - [9] Const mutate child$6_@5 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
88 - [10] Call read y$3_@1.push(read props$1.p4)
89 - [11] Const mutate $7_@6 = JSX <read Component$0 data={read y$3_@1} >{read child$6_@5}</read Component$0>
87 + [9] Const mutate child$6_@4 = JSX <read Component$0 data={freeze x$2_@0} ></read Component$0>
88 + [10] Call read y$3_@0.push(read props$1.p4)
89 + [11] Const mutate $7_@5 = JSX <read Component$0 data={read y$3_@0} >{read child$6_@4}</read Component$0>
90 "]
91 - bb1_instrs --> bb1_terminal(["Return read $7_@6"])
91 + bb1_instrs --> bb1_terminal(["Return read $7_@5"])
92 end
93
94 %% Jumps
95 - bb0_terminal -- "read $5_@3" --> bb4
96 - bb0_terminal -- "read $4_@2" --> bb2
95 + bb0_terminal -- "read $5_@2" --> bb4
96 + bb0_terminal -- "read $4_@1" --> bb2
97 bb0_terminal -- "default" --> bb1
98 bb0_terminal -- "fallthrough" --> bb1
99 bb4_terminal --> bb2