[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