@samitouri / QOS-React-2 / commits / 4a3640f25c

Merge scopes that interleave or cross control-flow boundaries together

- [x] Merge scopes that are interleaved - [x] Merge scopes if they both cross control-flow boundaries together - [x] Don't merge scopes that strictly shadow Still WIP because I want to double-check and see if i can find a simpler algorithm for this. But it works.

Joe Savona committed Nov 22, 2022 at 10:42 UTC 4a3640f25c97e1862812b62885f4447de9f1f8d9
31 files changed +816 -179
compiler/forget/src/HIR/InferReactiveScopes.ts
+195 -15
@@ -6,11 +6,13 @@
6 */
7
8 import invariant from "invariant";
9 +import DisjointSet from "./DisjointSet";
10 import {
11 HIRFunction,
12 Instruction,
13 InstructionId,
14 InstructionValue,
15 + makeInstructionId,
16 ReactiveScope,
17 ScopeId,
18 } from "./HIR";
@@ -107,13 +109,177 @@ import { eachInstructionOperand } from "./visitors";
109 * to be merged.
110 */
111 export function inferReactiveScopes(fn: HIRFunction) {
110 - const visitor = new ScopeVisitor();
111 - visitTree(fn, visitor);
112 + // Note sure if this is strictly required: in general the only way for two scopes to have
113 + // the same range is if they were already inferred as aliasing together, and therefore
114 + // they should end up with the same range and scope anyway.
115 + mergeScopesWithIdenticalRanges(fn);
116 +
117 + visitTree(fn, new AlignReactiveScopesToBlockScopeRangeVisitor());
118 + visitTree(fn, new MergeOverlappingReactiveScopesVisitor());
119 +}
120 +
121 +/**
122 + * Finds scopes with identical ranges and merges them
123 + */
124 +function mergeScopesWithIdenticalRanges(fn: HIRFunction) {
125 + const scopesByRange: Map<string, ReactiveScope> = new Map();
126 + for (const [_, block] of fn.body.blocks) {
127 + for (const instr of block.instructions) {
128 + const instrScope = getInstructionScope(instr);
129 + if (instrScope === null) {
130 + continue;
131 + }
132 + const rangeKey = `${instrScope.range.start}:${instrScope.range.end}`;
133 + let scope = scopesByRange.get(rangeKey);
134 + if (scope === undefined) {
135 + scope = instrScope;
136 + scopesByRange.set(rangeKey, scope);
137 + }
138 + if (scope.id !== instrScope.id) {
139 + instrScope.id = scope.id;
140 + instrScope.range = scope.range;
141 + }
142 + }
143 + }
144 +}
145 +
146 +class BlockScope {
147 + seen: Set<ScopeId> = new Set();
148 + scopes: Array<PendingReactiveScope> = [];
149 +}
150 +
151 +// maybe we just merge cases of interleaving when at the same block scope - eh fine?
152 +// then we can look at scopes that start at the same block scope and overlap
153 +class MergeOverlappingReactiveScopesVisitor
154 + implements Visitor<void, void, void, void>
155 +{
156 + scopes: Array<BlockScope> = [];
157 + seenScopes: Set<ScopeId> = new Set();
158 + joinedScopes: DisjointSet<ReactiveScope> = new DisjointSet();
159 +
160 + /**
161 + * Determine if this scope is interleaved with any other scopes,
162 + * and if so merge them.
163 + */
164 + visitScope(scope: ReactiveScope) {
165 + const currentBlock = this.scopes[this.scopes.length - 1]!;
166 + // Fast-path for the first time we see a new scope
167 + if (!this.seenScopes.has(scope.id)) {
168 + this.seenScopes.add(scope.id);
169 + currentBlock.seen.add(scope.id);
170 + currentBlock.scopes.push({ active: true, scope });
171 + return;
172 + }
173 + // Scope has already been seen, find it in the current block or a parent
174 + let index = this.scopes.length - 1;
175 + let nextBlock = currentBlock;
176 + while (!nextBlock.seen.has(scope.id)) {
177 + // scopes that cross control-flow boundaries are merged with overlapping
178 + // scopes
179 + this.joinedScopes.union([scope, ...nextBlock.scopes.map((s) => s.scope)]);
180 + index--;
181 + if (index < 0) {
182 + // TODO: handle reassignments in multiple branches. these create new identifiers that
183 + // add an entry to this.seenScopes but which are then removed when their blocks exit.
184 + // this is also wrong for codegen, different versions of an identifier could be cached
185 + // differently and so a reassigned version of a variable needs a separate declaration.
186 + currentBlock.seen.add(scope.id);
187 + currentBlock.scopes.push({ active: true, scope });
188 + return;
189 + }
190 + nextBlock = this.scopes[index]!;
191 + }
192 +
193 + // Handle interleaving within a given block scope
194 + let found = false;
195 + let active = null;
196 + for (let i = 0; i < nextBlock.scopes.length; i++) {
197 + const current = nextBlock.scopes[i]!;
198 + if (current.active && !found) {
199 + active = current;
200 + }
201 + if (current.scope.id === scope.id) {
202 + found = true;
203 + if (!current.active) {
204 + invariant(active !== null, "Expected an active scope");
205 + this.joinedScopes.union([active.scope, current.scope]);
206 + }
207 + } else if (found && current.active) {
208 + // `scope` is shadowing `current`, but we don't know they are interleaved yet
209 + current.active = false;
210 + }
211 + }
212 + if (!currentBlock.seen.has(scope.id)) {
213 + currentBlock.seen.add(scope.id);
214 + currentBlock.scopes.push({ active: true, scope });
215 + }
216 + }
217 +
218 + /**
219 + * Prune any scopes that are out of range
220 + */
221 + visitId(id: InstructionId) {
222 + const currentBlock = this.scopes[this.scopes.length - 1]!;
223 + retainWhere(currentBlock.scopes, (pending) => {
224 + if (pending.scope.range.end > id) {
225 + return true;
226 + } else {
227 + currentBlock.seen.delete(pending.scope.id);
228 + return false;
229 + }
230 + });
231 + }
232 +
233 + enterBlock(): void {
234 + this.scopes.push(new BlockScope());
235 + }
236 + visitValue(value: InstructionValue): void {}
237 + visitInstruction(instruction: Instruction, value: void): void {
238 + const scope = getInstructionScope(instruction);
239 + if (scope !== null && instruction.id < scope.range.end) {
240 + this.visitScope(scope);
241 + }
242 + this.visitId(instruction.id);
243 + }
244 + visitImplicitTerminal(id: InstructionId | null): void | null {
245 + if (id !== null) {
246 + this.visitId(id);
247 + }
248 + }
249 + visitTerminal(terminal: BlockTerminal<void, void, void, void>): void {
250 + if (terminal.id !== null) {
251 + this.visitId(terminal.id);
252 + }
253 + }
254 + visitCase(test: void | null, block: void): void {}
255 + appendBlock(block: void, item: void, label?: string | undefined): void {}
256 + leaveBlock(block: void): void {
257 + this.scopes.pop();
258 + if (this.scopes.length === 0) {
259 + this.joinedScopes.forEach((scope, groupScope) => {
260 + if (scope !== groupScope) {
261 + groupScope.range.start = makeInstructionId(
262 + Math.min(groupScope.range.start, scope.range.start)
263 + );
264 + groupScope.range.end = makeInstructionId(
265 + Math.max(groupScope.range.end, scope.range.end)
266 + );
267 + scope.range = groupScope.range;
268 + scope.id = groupScope.id;
269 + }
270 + });
271 + }
272 + }
273 }
274
114 -type PendingReactiveScope = ReactiveScope & { active: boolean };
275 +type PendingReactiveScope = { active: boolean; scope: ReactiveScope };
276
116 -class ScopeVisitor implements Visitor<void, void, void, void> {
277 +/**
278 + * Aligns scopes to block scope boundaries.
279 + */
280 +class AlignReactiveScopesToBlockScopeRangeVisitor
281 + implements Visitor<void, void, void, void>
282 +{
283 // For each block scope (outer array) stores a list of ReactiveScopes that start
284 // in that block scope.
285 blockScopes: Array<Array<PendingReactiveScope>> = [];
@@ -130,13 +296,13 @@ class ScopeVisitor implements Visitor<void, void, void, void> {
296 visitId(id: InstructionId) {
297 const currentScopes = this.blockScopes[this.blockScopes.length - 1]!;
298 const scopes = [...currentScopes, ...this.unclosedScopes];
133 - for (const scope of scopes) {
134 - if (!scope.active) {
299 + for (const pending of scopes) {
300 + if (!pending.active) {
301 continue;
302 }
137 - if (id >= scope.range.end) {
138 - scope.active = false;
139 - scope.range.end = id;
303 + if (id >= pending.scope.range.end) {
304 + pending.active = false;
305 + pending.scope.range.end = id;
306 }
307 }
308 }
@@ -165,9 +331,8 @@ class ScopeVisitor implements Visitor<void, void, void, void> {
331 const currentScopes = this.blockScopes[this.blockScopes.length - 1]!;
332 this.seenScopes.add(scope.id);
333 currentScopes.push({
168 - id: scope.id,
334 active: true,
170 - range: scope.range,
335 + scope,
336 });
337 }
338 }
@@ -196,11 +361,26 @@ class ScopeVisitor implements Visitor<void, void, void, void> {
361 function getInstructionScope(instr: Instruction): ReactiveScope | null {
362 if (instr.lvalue !== null && instr.lvalue.place.identifier.scope !== null) {
363 return instr.lvalue.place.identifier.scope;
199 - }
200 - for (const operand of eachInstructionOperand(instr)) {
201 - if (operand.identifier.scope !== null) {
202 - return operand.identifier.scope;
364 + } else {
365 + for (const operand of eachInstructionOperand(instr)) {
366 + if (operand.identifier.scope !== null) {
367 + return operand.identifier.scope;
368 + }
369 }
370 }
371 return null;
372 }
373 +
374 +/**
375 + * Modifies @param array, retaining only the items where the predicate returns true.
376 + */
377 +function retainWhere<T>(array: Array<T>, predicate: (item: T) => boolean) {
378 + let writeIndex = 0;
379 + for (let readIndex = 0; readIndex < array.length; readIndex++) {
380 + const item = array[readIndex];
381 + if (predicate(item) === true) {
382 + array[writeIndex++] = item;
383 + }
384 + }
385 + array.length = writeIndex;
386 +}
compiler/forget/src/HIR/PrintHIR.ts
+7 -3
@@ -99,7 +99,7 @@ export function printInstruction(instr: Instruction): string {
99 function printPhi(phi: Phi): string {
100 const items = [];
101 items.push(printIdentifier(phi.id));
102 - items.push(printMutableRange(phi.id.mutableRange));
102 + items.push(printMutableRange(phi.id));
103 items.push(": phi(");
104 const phis = [];
105 for (const [block, id] of phi.operands) {
@@ -261,13 +261,17 @@ function isMutable(range: MutableRange): boolean {
261 return range.end > range.start + 1;
262 }
263
264 -function printMutableRange(range: MutableRange): string {
264 +function printMutableRange(identifier: Identifier): string {
265 + const range =
266 + identifier.scope !== null
267 + ? identifier.scope.range
268 + : identifier.mutableRange;
269 return isMutable(range) ? `[${range.start}:${range.end}]` : "";
270 }
271
272 export function printLValue(lval: LValue): string {
273 let place = printPlace(lval.place);
270 - place += printMutableRange(lval.place.identifier.mutableRange);
274 + place += printMutableRange(lval.place.identifier);
275 switch (lval.kind) {
276 case InstructionKind.Let: {
277 return `Let ${place}`;
compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md
+15 -15
@@ -28,21 +28,21 @@ function mutate(x, y) {}
28 ```
29 bb0:
30 [1] Let mutate a$8_@0[0:12] = Object { }
31 - [2] Let mutate b$9_@0[0:11] = Object { }
32 - [3] Let mutate c$10_@0[0:11] = Object { }
31 + [2] Let mutate b$9_@0[0:12] = Object { }
32 + [3] Let mutate c$10_@0[0:12] = Object { }
33 [4] While test=bb1 loop=bb3 fallthrough=bb2
34 bb1:
35 predecessor blocks: bb0 bb3
36 - a$12_@0[0:11]: phi(bb0: a$8_@0, bb3: a$15_@0)
37 - b$14_@0[0:11]: phi(bb0: b$9_@0, bb3: b$17_@0)
38 - c$16_@0[0:11]: phi(bb0: c$10_@0, bb3: c$18_@0)
36 + a$12_@0[0:12]: phi(bb0: a$8_@0, bb3: a$15_@0)
37 + b$14_@0[0:12]: phi(bb0: b$9_@0, bb3: b$17_@0)
38 + c$16_@0[0:12]: phi(bb0: c$10_@0, bb3: c$18_@0)
39 [5] If (read cond$7) then:bb3 else:bb2
40 bb3:
41 predecessor blocks: bb1
42 - [6] Let mutate z$13_@0[0:11] = read a$12_@0
43 - [7] Reassign mutate a$15_@0[0:11] = read b$14_@0
44 - [8] Reassign mutate b$17_@0[0:11] = read c$16_@0
45 - [9] Reassign mutate c$18_@0[0:11] = read z$13_@0
42 + [6] Let mutate z$13_@0[0:12] = read a$12_@0
43 + [7] Reassign mutate a$15_@0[0:12] = read b$14_@0
44 + [8] Reassign mutate b$17_@0[0:12] = read c$16_@0
45 + [9] Reassign mutate c$18_@0[0:12] = read z$13_@0
46 [10] Call mutate mutate$6_@0(mutate a$15_@0, mutate b$17_@0)
47 [11] Goto(Continue) bb1
48 bb2:
@@ -61,8 +61,8 @@ flowchart TB
61 subgraph bb0
62 bb0_instrs["
63 [1] Let mutate a$8_@0[0:12] = Object { }
64 - [2] Let mutate b$9_@0[0:11] = Object { }
65 - [3] Let mutate c$10_@0[0:11] = Object { }
64 + [2] Let mutate b$9_@0[0:12] = Object { }
65 + [3] Let mutate c$10_@0[0:12] = Object { }
66 "]
67 bb0_instrs --> bb0_terminal(["While"])
68 end
@@ -71,10 +71,10 @@ flowchart TB
71 end
72 subgraph bb3
73 bb3_instrs["
74 - [6] Let mutate z$13_@0[0:11] = read a$12_@0
75 - [7] Reassign mutate a$15_@0[0:11] = read b$14_@0
76 - [8] Reassign mutate b$17_@0[0:11] = read c$16_@0
77 - [9] Reassign mutate c$18_@0[0:11] = read z$13_@0
74 + [6] Let mutate z$13_@0[0:12] = read a$12_@0
75 + [7] Reassign mutate a$15_@0[0:12] = read b$14_@0
76 + [8] Reassign mutate b$17_@0[0:12] = read c$16_@0
77 + [9] Reassign mutate c$18_@0[0:12] = read z$13_@0
78 [10] Call mutate mutate$6_@0(mutate a$15_@0, mutate b$17_@0)
79 "]
80 bb3_instrs --> bb3_terminal(["Goto"])
compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md
+22 -22
@@ -67,9 +67,9 @@ function mayMutate() {}
67
68 ```
69 bb0:
70 - [1] Const mutate a$7_@0[1:6] = Array []
71 - [2] Const mutate b$8_@1[2:9] = Array []
72 - [3] If (read b$8_@1) then:bb2 else:bb1
70 + [1] Const mutate a$7_@0[1:9] = Array []
71 + [2] Const mutate b$8_@0[1:9] = Array []
72 + [3] If (read b$8_@0) then:bb2 else:bb1
73 bb2:
74 predecessor blocks: bb0
75 [4] Call mutate a$7_@0.push(read props$6.p0)
@@ -79,11 +79,11 @@ bb1:
79 [6] If (read props$6.p1) then:bb4 else:bb3
80 bb4:
81 predecessor blocks: bb1
82 - [7] Call mutate b$8_@1.push(read props$6.p2)
82 + [7] Call mutate b$8_@0.push(read props$6.p2)
83 [8] Goto bb3
84 bb3:
85 predecessor blocks: bb4 bb1
86 - [9] Const mutate $16_@2 = JSX <read Foo$4 a={freeze a$7_@0} b={freeze b$8_@1} ></read Foo$4>
86 + [9] Const mutate $16_@2 = JSX <read Foo$4 a={freeze a$7_@0} b={freeze b$8_@0} ></read Foo$4>
87 [10] Return read $16_@2
88 ```
89
@@ -94,10 +94,10 @@ flowchart TB
94 %% Basic Blocks
95 subgraph bb0
96 bb0_instrs["
97 - [1] Const mutate a$7_@0[1:6] = Array []
98 - [2] Const mutate b$8_@1[2:9] = Array []
97 + [1] Const mutate a$7_@0[1:9] = Array []
98 + [2] Const mutate b$8_@0[1:9] = Array []
99 "]
100 - bb0_instrs --> bb0_terminal(["If (read b$8_@1)"])
100 + bb0_instrs --> bb0_terminal(["If (read b$8_@0)"])
101 end
102 subgraph bb2
103 bb2_instrs["
@@ -110,13 +110,13 @@ flowchart TB
110 end
111 subgraph bb4
112 bb4_instrs["
113 - [7] Call mutate b$8_@1.push(read props$6.p2)
113 + [7] Call mutate b$8_@0.push(read props$6.p2)
114 "]
115 bb4_instrs --> bb4_terminal(["Goto"])
116 end
117 subgraph bb3
118 bb3_instrs["
119 - [9] Const mutate $16_@2 = JSX <read Foo$4 a={freeze a$7_@0} b={freeze b$8_@1} ></read Foo$4>
119 + [9] Const mutate $16_@2 = JSX <read Foo$4 a={freeze a$7_@0} b={freeze b$8_@0} ></read Foo$4>
120 "]
121 bb3_instrs --> bb3_terminal(["Return read $16_@2"])
122 end
@@ -153,10 +153,10 @@ function Component$0(props$1) {
153
154 ```
155 bb0:
156 - [1] Const mutate a$9_@0[1:7] = Array []
157 - [2] Const mutate b$10_@1[0:10] = Array []
158 - [3] Const mutate $11_@1[0:9] = Call mutate mayMutate$4_@1(mutate b$10_@1)
159 - [4] If (read $11_@1) then:bb2 else:bb1
156 + [1] Const mutate a$9_@0[0:10] = Array []
157 + [2] Const mutate b$10_@0[0:10] = Array []
158 + [3] Const mutate $11_@0[0:10] = Call mutate mayMutate$4_@0(mutate b$10_@0)
159 + [4] If (read $11_@0) then:bb2 else:bb1
160 bb2:
161 predecessor blocks: bb0
162 [5] Call mutate a$9_@0.push(read props$8.p0)
@@ -166,11 +166,11 @@ bb1:
166 [7] If (read props$8.p1) then:bb4 else:bb3
167 bb4:
168 predecessor blocks: bb1
169 - [8] Call mutate b$10_@1.push(read props$8.p2)
169 + [8] Call mutate b$10_@0.push(read props$8.p2)
170 [9] Goto bb3
171 bb3:
172 predecessor blocks: bb4 bb1
173 - [10] Const mutate $19_@2 = JSX <read Foo$6 a={freeze a$9_@0} b={freeze b$10_@1} ></read Foo$6>
173 + [10] Const mutate $19_@2 = JSX <read Foo$6 a={freeze a$9_@0} b={freeze b$10_@0} ></read Foo$6>
174 [11] Return read $19_@2
175 ```
176
@@ -181,11 +181,11 @@ flowchart TB
181 %% Basic Blocks
182 subgraph bb0
183 bb0_instrs["
184 - [1] Const mutate a$9_@0[1:7] = Array []
185 - [2] Const mutate b$10_@1[0:10] = Array []
186 - [3] Const mutate $11_@1[0:9] = Call mutate mayMutate$4_@1(mutate b$10_@1)
184 + [1] Const mutate a$9_@0[0:10] = Array []
185 + [2] Const mutate b$10_@0[0:10] = Array []
186 + [3] Const mutate $11_@0[0:10] = Call mutate mayMutate$4_@0(mutate b$10_@0)
187 "]
188 - bb0_instrs --> bb0_terminal(["If (read $11_@1)"])
188 + bb0_instrs --> bb0_terminal(["If (read $11_@0)"])
189 end
190 subgraph bb2
191 bb2_instrs["
@@ -198,13 +198,13 @@ flowchart TB
198 end
199 subgraph bb4
200 bb4_instrs["
201 - [8] Call mutate b$10_@1.push(read props$8.p2)
201 + [8] Call mutate b$10_@0.push(read props$8.p2)
202 "]
203 bb4_instrs --> bb4_terminal(["Goto"])
204 end
205 subgraph bb3
206 bb3_instrs["
207 - [10] Const mutate $19_@2 = JSX <read Foo$6 a={freeze a$9_@0} b={freeze b$10_@1} ></read Foo$6>
207 + [10] Const mutate $19_@2 = JSX <read Foo$6 a={freeze a$9_@0} b={freeze b$10_@0} ></read Foo$6>
208 "]
209 bb3_instrs --> bb3_terminal(["Return read $19_@2"])
210 end
compiler/forget/src/__tests__/fixtures/hir/extend-scopes-if.expect.md
+4 -4
@@ -33,8 +33,8 @@ bb4:
33 [4] If (read c$9) then:bb6 else:bb1
34 bb6:
35 predecessor blocks: bb4
36 - [5] Const mutate $11_@1 = 0
37 - [6] Call mutate x$10_@0.push(read $11_@1)
36 + [5] Const mutate $11_@0[1:8] = 0
37 + [6] Call mutate x$10_@0.push(read $11_@0)
38 [7] Goto bb1
39 bb1:
40 predecessor blocks: bb6 bb4 bb2 bb0
@@ -67,8 +67,8 @@ flowchart TB
67 end
68 subgraph bb6
69 bb6_instrs["
70 - [5] Const mutate $11_@1 = 0
71 - [6] Call mutate x$10_@0.push(read $11_@1)
70 + [5] Const mutate $11_@0[1:8] = 0
71 + [6] Call mutate x$10_@0.push(read $11_@0)
72 "]
73 bb6_instrs --> bb6_terminal(["Goto"])
74 end
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md
+5 -5
@@ -32,15 +32,15 @@ bb0:
32 [4] If (read cond$8_@0) then:bb2 else:bb3
33 bb2:
34 predecessor blocks: bb0
35 - [5] Reassign mutate a$11_@1[2:8] = read x$9_@1
35 + [5] Reassign mutate a$11_@1[2:9] = read x$9_@1
36 [6] Goto bb1
37 bb3:
38 predecessor blocks: bb0
39 - [7] Reassign mutate a$12_@1[2:8] = Array []
39 + [7] Reassign mutate a$12_@1[2:9] = Array []
40 [8] Goto bb1
41 bb1:
42 predecessor blocks: bb2 bb3
43 - a$14_@1[2:8]: phi(bb2: a$11_@1, bb3: a$12_@1)
43 + a$14_@1[2:9]: phi(bb2: a$11_@1, bb3: a$12_@1)
44 [9] Call read useFreeze$5(freeze a$14_@1)
45 [10] Call read useFreeze$5(read a$14_@1)
46 [11] Call mutate call$6_@3(read a$14_@1)
@@ -62,13 +62,13 @@ flowchart TB
62 end
63 subgraph bb2
64 bb2_instrs["
65 - [5] Reassign mutate a$11_@1[2:8] = read x$9_@1
65 + [5] Reassign mutate a$11_@1[2:9] = read x$9_@1
66 "]
67 bb2_instrs --> bb2_terminal(["Goto"])
68 end
69 subgraph bb3
70 bb3_instrs["
71 - [7] Reassign mutate a$12_@1[2:8] = Array []
71 + [7] Reassign mutate a$12_@1[2:9] = Array []
72 "]
73 bb3_instrs --> bb3_terminal(["Goto"])
74 end
compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md
+2 -2
@@ -142,7 +142,7 @@ function Foo$0() {}
142 ```
143 bb0:
144 [1] Const mutate a$9_@0[0:7] = Call mutate compute$3_@0(read props$8.a)
145 - [2] Const mutate b$10_@0[0:6] = Call mutate compute$3_@0(read props$8.b)
145 + [2] Const mutate b$10_@0[0:7] = Call mutate compute$3_@0(read props$8.b)
146 [3] If (read props$8.c) then:bb2 else:bb1
147 bb2:
148 predecessor blocks: bb0
@@ -163,7 +163,7 @@ flowchart TB
163 subgraph bb0
164 bb0_instrs["
165 [1] Const mutate a$9_@0[0:7] = Call mutate compute$3_@0(read props$8.a)
166 - [2] Const mutate b$10_@0[0:6] = Call mutate compute$3_@0(read props$8.b)
166 + [2] Const mutate b$10_@0[0:7] = Call mutate compute$3_@0(read props$8.b)
167 "]
168 bb0_instrs --> bb0_terminal(["If (read props$8.c)"])
169 end
compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md
+2 -2
@@ -110,7 +110,7 @@ function Foo$0() {}
110 ```
111 bb0:
112 [1] Const mutate a$9_@0[0:6] = Call mutate compute$3_@0(read props$8.a)
113 - [2] Const mutate b$10_@0[0:5] = Call mutate compute$3_@0(read props$8.b)
113 + [2] Const mutate b$10_@0[0:6] = Call mutate compute$3_@0(read props$8.b)
114 [3] If (read props$8.c) then:bb2 else:bb1
115 bb2:
116 predecessor blocks: bb0
@@ -130,7 +130,7 @@ flowchart TB
130 subgraph bb0
131 bb0_instrs["
132 [1] Const mutate a$9_@0[0:6] = Call mutate compute$3_@0(read props$8.a)
133 - [2] Const mutate b$10_@0[0:5] = Call mutate compute$3_@0(read props$8.b)
133 + [2] Const mutate b$10_@0[0:6] = Call mutate compute$3_@0(read props$8.b)
134 "]
135 bb0_instrs --> bb0_terminal(["If (read props$8.c)"])
136 end
compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md
+17 -17
@@ -27,15 +27,15 @@ bb0:
27 [2] If (read $5_@0) then:bb2 else:bb3
28 bb2:
29 predecessor blocks: bb0
30 - [3] Const mutate $6_@0[0:6] = Call mutate g$4_@0()
30 + [3] Const mutate $6_@0[0:7] = Call mutate g$4_@0()
31 [4] Goto bb1
32 bb3:
33 predecessor blocks: bb0
34 - [5] Const mutate $7_@0[0:6] = read $5_@0
34 + [5] Const mutate $7_@0[0:7] = read $5_@0
35 [6] Goto bb1
36 bb1:
37 predecessor blocks: bb2 bb3
38 - $8_@0[0:6]: phi(bb2: $6_@0, bb3: $7_@0)
38 + $8_@0[0:7]: phi(bb2: $6_@0, bb3: $7_@0)
39 [7] Return freeze $8_@0
40 ```
41
@@ -52,13 +52,13 @@ flowchart TB
52 end
53 subgraph bb2
54 bb2_instrs["
55 - [3] Const mutate $6_@0[0:6] = Call mutate g$4_@0()
55 + [3] Const mutate $6_@0[0:7] = Call mutate g$4_@0()
56 "]
57 bb2_instrs --> bb2_terminal(["Goto"])
58 end
59 subgraph bb3
60 bb3_instrs["
61 - [5] Const mutate $7_@0[0:6] = read $5_@0
61 + [5] Const mutate $7_@0[0:7] = read $5_@0
62 "]
63 bb3_instrs --> bb3_terminal(["Goto"])
64 end
@@ -94,15 +94,15 @@ bb0:
94 [2] If (read $5_@0) then:bb2 else:bb3
95 bb2:
96 predecessor blocks: bb0
97 - [3] Const mutate $6_@0[0:6] = read $5_@0
97 + [3] Const mutate $6_@0[0:7] = read $5_@0
98 [4] Goto bb1
99 bb3:
100 predecessor blocks: bb0
101 - [5] Const mutate $7_@0[0:6] = Call mutate g$4_@0()
101 + [5] Const mutate $7_@0[0:7] = Call mutate g$4_@0()
102 [6] Goto bb1
103 bb1:
104 predecessor blocks: bb2 bb3
105 - $8_@0[0:6]: phi(bb2: $6_@0, bb3: $7_@0)
105 + $8_@0[0:7]: phi(bb2: $6_@0, bb3: $7_@0)
106 [7] Return freeze $8_@0
107 ```
108
@@ -119,13 +119,13 @@ flowchart TB
119 end
120 subgraph bb2
121 bb2_instrs["
122 - [3] Const mutate $6_@0[0:6] = read $5_@0
122 + [3] Const mutate $6_@0[0:7] = read $5_@0
123 "]
124 bb2_instrs --> bb2_terminal(["Goto"])
125 end
126 subgraph bb3
127 bb3_instrs["
128 - [5] Const mutate $7_@0[0:6] = Call mutate g$4_@0()
128 + [5] Const mutate $7_@0[0:7] = Call mutate g$4_@0()
129 "]
130 bb3_instrs --> bb3_terminal(["Goto"])
131 end
@@ -159,19 +159,19 @@ function Or$0() {
159 bb0:
160 [1] Const mutate $9_@0[0:9] = Call mutate f$2_@0()
161 [2] Const mutate $10_@1 = null
162 - [3] Const mutate $11_@0[0:8] = Binary read $9_@0 != read $10_@1
162 + [3] Const mutate $11_@0[0:9] = Binary read $9_@0 != read $10_@1
163 [4] If (read $11_@0) then:bb2 else:bb3
164 bb2:
165 predecessor blocks: bb0
166 - [5] Const mutate $12_@0[0:8] = read $9_@0
166 + [5] Const mutate $12_@0[0:9] = read $9_@0
167 [6] Goto bb1
168 bb3:
169 predecessor blocks: bb0
170 - [7] Const mutate $13_@0[0:8] = Call mutate g$7_@0()
170 + [7] Const mutate $13_@0[0:9] = Call mutate g$7_@0()
171 [8] Goto bb1
172 bb1:
173 predecessor blocks: bb2 bb3
174 - $14_@0[0:8]: phi(bb2: $12_@0, bb3: $13_@0)
174 + $14_@0[0:9]: phi(bb2: $12_@0, bb3: $13_@0)
175 [9] Return freeze $14_@0
176 ```
177
@@ -184,19 +184,19 @@ flowchart TB
184 bb0_instrs["
185 [1] Const mutate $9_@0[0:9] = Call mutate f$2_@0()
186 [2] Const mutate $10_@1 = null
187 - [3] Const mutate $11_@0[0:8] = Binary read $9_@0 != read $10_@1
187 + [3] Const mutate $11_@0[0:9] = Binary read $9_@0 != read $10_@1
188 "]
189 bb0_instrs --> bb0_terminal(["If (read $11_@0)"])
190 end
191 subgraph bb2
192 bb2_instrs["
193 - [5] Const mutate $12_@0[0:8] = read $9_@0
193 + [5] Const mutate $12_@0[0:9] = read $9_@0
194 "]
195 bb2_instrs --> bb2_terminal(["Goto"])
196 end
197 subgraph bb3
198 bb3_instrs["
199 - [7] Const mutate $13_@0[0:8] = Call mutate g$7_@0()
199 + [7] Const mutate $13_@0[0:9] = Call mutate g$7_@0()
200 "]
201 bb3_instrs --> bb3_terminal(["Goto"])
202 end
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved.expect.md new
+55
@@ -0,0 +1,55 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function foo(a, b) {
6 + let x = [];
7 + let y = [];
8 + x.push(a);
9 + y.push(b);
10 +}
11 +
12 +```
13 +
14 +## HIR
15 +
16 +```
17 +bb0:
18 + [1] Let mutate x$7_@0[1:5] = Array []
19 + [2] Let mutate y$8_@0[1:5] = Array []
20 + [3] Call mutate x$7_@0.push(read a$5)
21 + [4] Call mutate y$8_@0.push(read b$6)
22 + [5] Return
23 +```
24 +
25 +### CFG
26 +
27 +```mermaid
28 +flowchart TB
29 + %% Basic Blocks
30 + subgraph bb0
31 + bb0_instrs["
32 + [1] Let mutate x$7_@0[1:5] = Array []
33 + [2] Let mutate y$8_@0[1:5] = Array []
34 + [3] Call mutate x$7_@0.push(read a$5)
35 + [4] Call mutate y$8_@0.push(read b$6)
36 + "]
37 + bb0_instrs --> bb0_terminal(["Return"])
38 + end
39 +
40 + %% Jumps
41 + %% empty
42 +```
43 +
44 +## Code
45 +
46 +```javascript
47 +function foo$0(a$1, b$2) {
48 + let x$3 = [];
49 + let y$4 = [];
50 + x$3.push(a$1);
51 + y$4.push(b$2);
52 +}
53 +
54 +```
55 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved.js new
+6
@@ -0,0 +1,6 @@
1 +function foo(a, b) {
2 + let x = [];
3 + let y = [];
4 + x.push(a);
5 + y.push(b);
6 +}
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowed.expect.md new
+55
@@ -0,0 +1,55 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function foo(a, b) {
6 + let x = [];
7 + let y = [];
8 + y.push(b);
9 + x.push(a);
10 +}
11 +
12 +```
13 +
14 +## HIR
15 +
16 +```
17 +bb0:
18 + [1] Let mutate x$7_@0[1:5] = Array []
19 + [2] Let mutate y$8_@1[2:4] = Array []
20 + [3] Call mutate y$8_@1.push(read b$6)
21 + [4] Call mutate x$7_@0.push(read a$5)
22 + [5] Return
23 +```
24 +
25 +### CFG
26 +
27 +```mermaid
28 +flowchart TB
29 + %% Basic Blocks
30 + subgraph bb0
31 + bb0_instrs["
32 + [1] Let mutate x$7_@0[1:5] = Array []
33 + [2] Let mutate y$8_@1[2:4] = Array []
34 + [3] Call mutate y$8_@1.push(read b$6)
35 + [4] Call mutate x$7_@0.push(read a$5)
36 + "]
37 + bb0_instrs --> bb0_terminal(["Return"])
38 + end
39 +
40 + %% Jumps
41 + %% empty
42 +```
43 +
44 +## Code
45 +
46 +```javascript
47 +function foo$0(a$1, b$2) {
48 + let x$3 = [];
49 + let y$4 = [];
50 + y$4.push(b$2);
51 + x$3.push(a$1);
52 +}
53 +
54 +```
55 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowed.js new
+6
@@ -0,0 +1,6 @@
1 +function foo(a, b) {
2 + let x = [];
3 + let y = [];
4 + y.push(b);
5 + x.push(a);
6 +}
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md new
+109
@@ -0,0 +1,109 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function foo(a, b, c) {
6 + let x = [];
7 + if (a) {
8 + let y = [];
9 + if (b) {
10 + y.push(c);
11 + }
12 +
13 + x.push(<div>{y}</div>);
14 + }
15 + return x;
16 +}
17 +
18 +```
19 +
20 +## HIR
21 +
22 +```
23 +bb0:
24 + [1] Let mutate x$11_@0[1:11] = Array []
25 + [2] If (read a$8) then:bb2 else:bb1
26 +bb2:
27 + predecessor blocks: bb0
28 + [3] Let mutate y$12_@1[3:7] = Array []
29 + [4] If (read b$9) then:bb4 else:bb3
30 +bb4:
31 + predecessor blocks: bb2
32 + [5] Call mutate y$12_@1.push(read c$10)
33 + [6] Goto bb3
34 +bb3:
35 + predecessor blocks: bb4 bb2
36 + [7] Const mutate $13_@2 = "div"
37 + [8] Const mutate $15_@0[1:11] = JSX <read $13_@2>{freeze y$12_@1}</read $13_@2>
38 + [9] Call mutate x$11_@0.push(read $15_@0)
39 + [10] Goto bb1
40 +bb1:
41 + predecessor blocks: bb3 bb0
42 + [11] Return freeze x$11_@0
43 +```
44 +
45 +### CFG
46 +
47 +```mermaid
48 +flowchart TB
49 + %% Basic Blocks
50 + subgraph bb0
51 + bb0_instrs["
52 + [1] Let mutate x$11_@0[1:11] = Array []
53 + "]
54 + bb0_instrs --> bb0_terminal(["If (read a$8)"])
55 + end
56 + subgraph bb2
57 + bb2_instrs["
58 + [3] Let mutate y$12_@1[3:7] = Array []
59 + "]
60 + bb2_instrs --> bb2_terminal(["If (read b$9)"])
61 + end
62 + subgraph bb4
63 + bb4_instrs["
64 + [5] Call mutate y$12_@1.push(read c$10)
65 + "]
66 + bb4_instrs --> bb4_terminal(["Goto"])
67 + end
68 + subgraph bb3
69 + bb3_instrs["
70 + [7] Const mutate $13_@2 = 'div'
71 + [8] Const mutate $15_@0[1:11] = JSX <read $13_@2>{freeze y$12_@1}</read $13_@2>
72 + [9] Call mutate x$11_@0.push(read $15_@0)
73 + "]
74 + bb3_instrs --> bb3_terminal(["Goto"])
75 + end
76 + subgraph bb1
77 + bb1_terminal(["Return freeze x$11_@0"])
78 + end
79 +
80 + %% Jumps
81 + bb0_terminal -- "then" --> bb2
82 + bb0_terminal -- "else" --> bb1
83 + bb2_terminal -- "then" --> bb4
84 + bb2_terminal -- "else" --> bb3
85 + bb4_terminal --> bb3
86 + bb3_terminal --> bb1
87 +
88 +```
89 +
90 +## Code
91 +
92 +```javascript
93 +function foo$0(a$1, b$2, c$3) {
94 + let x$4 = [];
95 + bb1: if (a$1) {
96 + let y$5 = [];
97 +
98 + bb3: if (b$2) {
99 + y$5.push(c$3);
100 + }
101 +
102 + x$4.push(<div>{y$5}</div>);
103 + }
104 +
105 + return x$4;
106 +}
107 +
108 +```
109 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.js new
+12
@@ -0,0 +1,12 @@
1 +function foo(a, b, c) {
2 + let x = [];
3 + if (a) {
4 + let y = [];
5 + if (b) {
6 + y.push(c);
7 + }
8 +
9 + x.push(<div>{y}</div>);
10 + }
11 + return x;
12 +}
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-while.expect.md new
+85
@@ -0,0 +1,85 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function foo(a, b, c) {
6 + let x = [];
7 + let y = [];
8 + while (c) {
9 + y.push(b);
10 + x.push(a);
11 + }
12 +}
13 +
14 +```
15 +
16 +## HIR
17 +
18 +```
19 +bb0:
20 + [1] Let mutate x$9_@0[1:8] = Array []
21 + [2] Let mutate y$10_@0[1:8] = Array []
22 + [3] While test=bb1 loop=bb3 fallthrough=bb2
23 +bb1:
24 + predecessor blocks: bb0 bb3
25 + [4] If (read c$8) then:bb3 else:bb2
26 +bb3:
27 + predecessor blocks: bb1
28 + [5] Call mutate y$10_@0.push(read b$7)
29 + [6] Call mutate x$9_@0.push(read a$6)
30 + [7] Goto(Continue) bb1
31 +bb2:
32 + predecessor blocks: bb1
33 + [8] Return
34 +```
35 +
36 +### CFG
37 +
38 +```mermaid
39 +flowchart TB
40 + %% Basic Blocks
41 + subgraph bb0
42 + bb0_instrs["
43 + [1] Let mutate x$9_@0[1:8] = Array []
44 + [2] Let mutate y$10_@0[1:8] = Array []
45 + "]
46 + bb0_instrs --> bb0_terminal(["While"])
47 + end
48 + subgraph bb1
49 + bb1_terminal(["If (read c$8)"])
50 + end
51 + subgraph bb3
52 + bb3_instrs["
53 + [5] Call mutate y$10_@0.push(read b$7)
54 + [6] Call mutate x$9_@0.push(read a$6)
55 + "]
56 + bb3_instrs --> bb3_terminal(["Goto"])
57 + end
58 + subgraph bb2
59 + bb2_terminal(["Return"])
60 + end
61 +
62 + %% Jumps
63 + bb0_terminal -- "test" --> bb1
64 + bb0_terminal -- "loop" --> bb3
65 + bb0_terminal -- "fallthrough" --> bb2
66 + bb1_terminal -- "then" --> bb3
67 + bb1_terminal -- "else" --> bb2
68 + bb3_terminal --> bb1
69 +
70 +```
71 +
72 +## Code
73 +
74 +```javascript
75 +function foo$0(a$1, b$2, c$3) {
76 + let x$4 = [];
77 + let y$5 = [];
78 + bb2: while (c$3) {
79 + y$5.push(b$2);
80 + x$4.push(a$1);
81 + }
82 +}
83 +
84 +```
85 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-while.js new
+8
@@ -0,0 +1,8 @@
1 +function foo(a, b, c) {
2 + let x = [];
3 + let y = [];
4 + while (c) {
5 + y.push(b);
6 + x.push(a);
7 + }
8 +}
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-within-block.expect.md new
+105
@@ -0,0 +1,105 @@
1 +
2 +## Input
3 +
4 +```javascript
5 +function foo(a, b, c) {
6 + let x = [];
7 + if (a) {
8 + let y = [];
9 + if (b) {
10 + y.push(c);
11 + }
12 +
13 + x.push(y);
14 + }
15 + return x;
16 +}
17 +
18 +```
19 +
20 +## HIR
21 +
22 +```
23 +bb0:
24 + [1] Let mutate x$9_@0[1:9] = Array []
25 + [2] If (read a$6) then:bb2 else:bb1
26 +bb2:
27 + predecessor blocks: bb0
28 + [3] Let mutate y$10_@0[1:9] = Array []
29 + [4] If (read b$7) then:bb4 else:bb3
30 +bb4:
31 + predecessor blocks: bb2
32 + [5] Call mutate y$10_@0.push(read c$8)
33 + [6] Goto bb3
34 +bb3:
35 + predecessor blocks: bb4 bb2
36 + [7] Call mutate x$9_@0.push(mutate y$10_@0)
37 + [8] Goto bb1
38 +bb1:
39 + predecessor blocks: bb3 bb0
40 + [9] Return freeze x$9_@0
41 +```
42 +
43 +### CFG
44 +
45 +```mermaid
46 +flowchart TB
47 + %% Basic Blocks
48 + subgraph bb0
49 + bb0_instrs["
50 + [1] Let mutate x$9_@0[1:9] = Array []
51 + "]
52 + bb0_instrs --> bb0_terminal(["If (read a$6)"])
53 + end
54 + subgraph bb2
55 + bb2_instrs["
56 + [3] Let mutate y$10_@0[1:9] = Array []
57 + "]
58 + bb2_instrs --> bb2_terminal(["If (read b$7)"])
59 + end
60 + subgraph bb4
61 + bb4_instrs["
62 + [5] Call mutate y$10_@0.push(read c$8)
63 + "]
64 + bb4_instrs --> bb4_terminal(["Goto"])
65 + end
66 + subgraph bb3
67 + bb3_instrs["
68 + [7] Call mutate x$9_@0.push(mutate y$10_@0)
69 + "]
70 + bb3_instrs --> bb3_terminal(["Goto"])
71 + end
72 + subgraph bb1
73 + bb1_terminal(["Return freeze x$9_@0"])
74 + end
75 +
76 + %% Jumps
77 + bb0_terminal -- "then" --> bb2
78 + bb0_terminal -- "else" --> bb1
79 + bb2_terminal -- "then" --> bb4
80 + bb2_terminal -- "else" --> bb3
81 + bb4_terminal --> bb3
82 + bb3_terminal --> bb1
83 +
84 +```
85 +
86 +## Code
87 +
88 +```javascript
89 +function foo$0(a$1, b$2, c$3) {
90 + let x$4 = [];
91 + bb1: if (a$1) {
92 + let y$5 = [];
93 +
94 + bb3: if (b$2) {
95 + y$5.push(c$3);
96 + }
97 +
98 + x$4.push(y$5);
99 + }
100 +
101 + return x$4;
102 +}
103 +
104 +```
105 +
\ No newline at end of file
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-within-block.js new
+12
@@ -0,0 +1,12 @@
1 +function foo(a, b, c) {
2 + let x = [];
3 + if (a) {
4 + let y = [];
5 + if (b) {
6 + y.push(c);
7 + }
8 +
9 + x.push(y);
10 + }
11 + return x;
12 +}
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+5 -5
@@ -25,15 +25,15 @@ function Component(props) {
25 bb0:
26 [1] Let mutate x$7_@0[1:7] = Array []
27 [2] Call mutate x$7_@0.push(read props$6.p0)
28 - [3] Let mutate y$8_@0[1:6] = read x$7_@0
28 + [3] Let mutate y$8_@0[1:7] = read x$7_@0
29 [4] If (read props$6.p1) then:bb2 else:bb1
30 bb2:
31 predecessor blocks: bb0
32 - [5] Reassign mutate x$9_@0[1:6] = Array []
32 + [5] Reassign mutate x$9_@0[1:7] = Array []
33 [6] Goto bb1
34 bb1:
35 predecessor blocks: bb2 bb0
36 - x$11_@0[1:6]: phi(bb2: x$9_@0, bb0: x$7_@0)
36 + x$11_@0[1:7]: phi(bb2: x$9_@0, bb0: x$7_@0)
37 [7] Let mutate _$12_@1 = JSX <read Component$0 x={freeze x$11_@0} ></read Component$0>
38 [8] Call read y$8_@0.push(read props$6.p2)
39 [9] Const mutate $15_@2 = JSX <read Component$0 x={read x$11_@0} y={read y$8_@0} ></read Component$0>
@@ -49,13 +49,13 @@ flowchart TB
49 bb0_instrs["
50 [1] Let mutate x$7_@0[1:7] = Array []
51 [2] Call mutate x$7_@0.push(read props$6.p0)
52 - [3] Let mutate y$8_@0[1:6] = read x$7_@0
52 + [3] Let mutate y$8_@0[1:7] = read x$7_@0
53 "]
54 bb0_instrs --> bb0_terminal(["If (read props$6.p1)"])
55 end
56 subgraph bb2
57 bb2_instrs["
58 - [5] Reassign mutate x$9_@0[1:6] = Array []
58 + [5] Reassign mutate x$9_@0[1:7] = Array []
59 "]
60 bb2_instrs --> bb2_terminal(["Goto"])
61 end
compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md
+17 -17
@@ -36,44 +36,44 @@ function Component(props) {
36
37 ```
38 bb0:
39 - [1] Let mutate x$7_@0 = undefined
39 + [1] Let mutate x$7_@4[1:17] = undefined
40 [2] If (read props$6.cond) then:bb2 else:bb10
41 bb2:
42 predecessor blocks: bb0
43 [3] Const mutate $8_@1 = 2
44 [4] Const mutate $9_@2 = 1
45 - [5] Const mutate $10_@3 = 0
45 + [5] Const mutate $10_@4[1:17] = 0
46 [6] Switch (read props$6.test)
47 - Case read $10_@3: bb8
47 + Case read $10_@4: bb8
48 Case read $9_@2: bb6
49 Case read $8_@1: bb4
50 Default: bb4
51 bb8:
52 predecessor blocks: bb2
53 - [7] Reassign mutate x$11_@4[7:17] = read props$6.v0
53 + [7] Reassign mutate x$11_@4[1:17] = read props$6.v0
54 [8] Goto bb1
55 bb6:
56 predecessor blocks: bb2
57 - [9] Reassign mutate x$12_@4[7:17] = read props$6.v1
57 + [9] Reassign mutate x$12_@4[1:17] = read props$6.v1
58 [10] Goto bb1
59 bb4:
60 predecessor blocks: bb2
61 - [11] Reassign mutate x$13_@4[7:17] = read props$6.v2
61 + [11] Reassign mutate x$13_@4[1:17] = read props$6.v2
62 [12] Goto bb1
63 bb10:
64 predecessor blocks: bb0
65 [13] If (read props$6.cond2) then:bb12 else:bb13
66 bb12:
67 predecessor blocks: bb10
68 - [14] Reassign mutate x$14_@4[7:17] = read props$6.b
68 + [14] Reassign mutate x$14_@4[1:17] = read props$6.b
69 [15] Goto bb1
70 bb13:
71 predecessor blocks: bb10
72 - [16] Reassign mutate x$15_@4[7:17] = read props$6.c
72 + [16] Reassign mutate x$15_@4[1:17] = read props$6.c
73 [17] Goto bb1
74 bb1:
75 predecessor blocks: bb8 bb6 bb4 bb12 bb13
76 - x$16_@4[7:17]: phi(bb8: x$11_@4, bb6: x$12_@4, bb4: x$13_@4, bb12: x$14_@4, bb13: x$15_@4)
76 + x$16_@4[1:17]: phi(bb8: x$11_@4, bb6: x$12_@4, bb4: x$13_@4, bb12: x$14_@4, bb13: x$15_@4)
77 [18] read x$16_@4
78 [19] Return
79 ```
@@ -85,7 +85,7 @@ flowchart TB
85 %% Basic Blocks
86 subgraph bb0
87 bb0_instrs["
88 - [1] Let mutate x$7_@0 = undefined
88 + [1] Let mutate x$7_@4[1:17] = undefined
89 "]
90 bb0_instrs --> bb0_terminal(["If (read props$6.cond)"])
91 end
@@ -93,25 +93,25 @@ flowchart TB
93 bb2_instrs["
94 [3] Const mutate $8_@1 = 2
95 [4] Const mutate $9_@2 = 1
96 - [5] Const mutate $10_@3 = 0
96 + [5] Const mutate $10_@4[1:17] = 0
97 "]
98 bb2_instrs --> bb2_terminal(["Switch (read props$6.test)"])
99 end
100 subgraph bb8
101 bb8_instrs["
102 - [7] Reassign mutate x$11_@4[7:17] = read props$6.v0
102 + [7] Reassign mutate x$11_@4[1:17] = read props$6.v0
103 "]
104 bb8_instrs --> bb8_terminal(["Goto"])
105 end
106 subgraph bb6
107 bb6_instrs["
108 - [9] Reassign mutate x$12_@4[7:17] = read props$6.v1
108 + [9] Reassign mutate x$12_@4[1:17] = read props$6.v1
109 "]
110 bb6_instrs --> bb6_terminal(["Goto"])
111 end
112 subgraph bb4
113 bb4_instrs["
114 - [11] Reassign mutate x$13_@4[7:17] = read props$6.v2
114 + [11] Reassign mutate x$13_@4[1:17] = read props$6.v2
115 "]
116 bb4_instrs --> bb4_terminal(["Goto"])
117 end
@@ -120,13 +120,13 @@ flowchart TB
120 end
121 subgraph bb12
122 bb12_instrs["
123 - [14] Reassign mutate x$14_@4[7:17] = read props$6.b
123 + [14] Reassign mutate x$14_@4[1:17] = read props$6.b
124 "]
125 bb12_instrs --> bb12_terminal(["Goto"])
126 end
127 subgraph bb13
128 bb13_instrs["
129 - [16] Reassign mutate x$15_@4[7:17] = read props$6.c
129 + [16] Reassign mutate x$15_@4[1:17] = read props$6.c
130 "]
131 bb13_instrs --> bb13_terminal(["Goto"])
132 end
@@ -141,7 +141,7 @@ flowchart TB
141 bb0_terminal -- "then" --> bb2
142 bb0_terminal -- "else" --> bb10
143 bb0_terminal -- "fallthrough" --> bb1
144 - bb2_terminal -- "read $10_@3" --> bb8
144 + bb2_terminal -- "read $10_@4" --> bb8
145 bb2_terminal -- "read $9_@2" --> bb6
146 bb2_terminal -- "read $8_@1" --> bb4
147 bb2_terminal -- "default" --> bb4
compiler/forget/src/__tests__/fixtures/hir/ssa-if-else.expect.md
+4 -4
@@ -24,11 +24,11 @@ bb0:
24 [3] If (read y$6_@1) then:bb2 else:bb3
25 bb2:
26 predecessor blocks: bb0
27 - [4] Let mutate z$7_@0[1:7] = Binary read x$5_@0 + read y$6_@1
27 + [4] Let mutate z$7_@0[1:8] = Binary read x$5_@0 + read y$6_@1
28 [5] Goto bb1
29 bb3:
30 predecessor blocks: bb0
31 - [6] Let mutate z$8_@0[1:7] = read x$5_@0
31 + [6] Let mutate z$8_@0[1:8] = read x$5_@0
32 [7] Goto bb1
33 bb1:
34 predecessor blocks: bb2 bb3
@@ -49,13 +49,13 @@ flowchart TB
49 end
50 subgraph bb2
51 bb2_instrs["
52 - [4] Let mutate z$7_@0[1:7] = Binary read x$5_@0 + read y$6_@1
52 + [4] Let mutate z$7_@0[1:8] = Binary read x$5_@0 + read y$6_@1
53 "]
54 bb2_instrs --> bb2_terminal(["Goto"])
55 end
56 subgraph bb3
57 bb3_instrs["
58 - [6] Let mutate z$8_@0[1:7] = read x$5_@0
58 + [6] Let mutate z$8_@0[1:8] = read x$5_@0
59 "]
60 bb3_instrs --> bb3_terminal(["Goto"])
61 end
compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md
+10 -10
@@ -23,23 +23,23 @@ function foo() {
23 ```
24 bb0:
25 [1] Let mutate x$6_@0[1:10] = 1
26 - [2] Let mutate y$7_@1[2:10] = 2
26 + [2] Let mutate y$7_@0[1:10] = 2
27 [3] Const mutate $8_@2 = 1
28 [4] Const mutate $9_@3 = Binary read x$6_@0 > read $8_@2
29 [5] If (read $9_@3) then:bb2 else:bb3
30 bb2:
31 predecessor blocks: bb0
32 - [6] Reassign mutate x$10_@0[1:7] = 2
32 + [6] Reassign mutate x$10_@0[1:10] = 2
33 [7] Goto bb1
34 bb3:
35 predecessor blocks: bb0
36 - [8] Reassign mutate y$11_@1[2:9] = 3
36 + [8] Reassign mutate y$11_@0[1:10] = 3
37 [9] Goto bb1
38 bb1:
39 predecessor blocks: bb2 bb3
40 - x$12_@0[1:7]: phi(bb2: x$10_@0, bb3: x$6_@0)
41 - y$13_@1[2:9]: phi(bb2: y$7_@1, bb3: y$11_@1)
42 - [10] Let mutate t$14_@4 = Object { x: read x$12_@0, y: read y$13_@1 }
40 + x$12_@0[1:10]: phi(bb2: x$10_@0, bb3: x$6_@0)
41 + y$13_@0[1:10]: phi(bb2: y$7_@0, bb3: y$11_@0)
42 + [10] Let mutate t$14_@4 = Object { x: read x$12_@0, y: read y$13_@0 }
43 [11] Return freeze t$14_@4
44 ```
45
@@ -51,7 +51,7 @@ flowchart TB
51 subgraph bb0
52 bb0_instrs["
53 [1] Let mutate x$6_@0[1:10] = 1
54 - [2] Let mutate y$7_@1[2:10] = 2
54 + [2] Let mutate y$7_@0[1:10] = 2
55 [3] Const mutate $8_@2 = 1
56 [4] Const mutate $9_@3 = Binary read x$6_@0 > read $8_@2
57 "]
@@ -59,19 +59,19 @@ flowchart TB
59 end
60 subgraph bb2
61 bb2_instrs["
62 - [6] Reassign mutate x$10_@0[1:7] = 2
62 + [6] Reassign mutate x$10_@0[1:10] = 2
63 "]
64 bb2_instrs --> bb2_terminal(["Goto"])
65 end
66 subgraph bb3
67 bb3_instrs["
68 - [8] Reassign mutate y$11_@1[2:9] = 3
68 + [8] Reassign mutate y$11_@0[1:10] = 3
69 "]
70 bb3_instrs --> bb3_terminal(["Goto"])
71 end
72 subgraph bb1
73 bb1_instrs["
74 - [10] Let mutate t$14_@4 = Object { x: read x$12_@0, y: read y$13_@1 }
74 + [10] Let mutate t$14_@4 = Object { x: read x$12_@0, y: read y$13_@0 }
75 "]
76 bb1_instrs --> bb1_terminal(["Return freeze t$14_@4"])
77 end
compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md
+3 -3
@@ -23,11 +23,11 @@ bb0:
23 [4] If (read $6_@2) then:bb2 else:bb1
24 bb2:
25 predecessor blocks: bb0
26 - [5] Reassign mutate x$7_@0[1:6] = 2
26 + [5] Reassign mutate x$7_@0[1:7] = 2
27 [6] Goto bb1
28 bb1:
29 predecessor blocks: bb2 bb0
30 - x$8_@0[1:6]: phi(bb2: x$7_@0, bb0: x$4_@0)
30 + x$8_@0[1:7]: phi(bb2: x$7_@0, bb0: x$4_@0)
31 [7] Return read x$8_@0
32 ```
33
@@ -46,7 +46,7 @@ flowchart TB
46 end
47 subgraph bb2
48 bb2_instrs["
49 - [5] Reassign mutate x$7_@0[1:6] = 2
49 + [5] Reassign mutate x$7_@0[1:7] = 2
50 "]
51 bb2_instrs --> bb2_terminal(["Goto"])
52 end
compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md
+7 -7
@@ -47,7 +47,7 @@ function log$0() {}
47
48 ```
49 bb0:
50 - [1] Let mutate str$6_@0[1:8] = ""
50 + [1] Let mutate str$6_@2[0:9] = ""
51 [2] If (read cond$5) then:bb2 else:bb3
52 bb2:
53 predecessor blocks: bb0
@@ -56,12 +56,12 @@ bb2:
56 [5] Goto bb1
57 bb3:
58 predecessor blocks: bb0
59 - [6] Reassign mutate str$8_@0[1:7] = "fallthrough test"
59 + [6] Reassign mutate str$8_@2[0:9] = "fallthrough test"
60 [7] Goto bb1
61 bb1:
62 predecessor blocks: bb2 bb3
63 - str$10_@0[1:7]: phi(bb2: str$6_@0, bb3: str$8_@0)
64 - [8] Call mutate log$4_@2(read str$10_@0)
63 + str$10_@2[0:9]: phi(bb2: str$6_@2, bb3: str$8_@2)
64 + [8] Call mutate log$4_@2(read str$10_@2)
65 [9] Return
66 ```
67
@@ -72,7 +72,7 @@ flowchart TB
72 %% Basic Blocks
73 subgraph bb0
74 bb0_instrs["
75 - [1] Let mutate str$6_@0[1:8] = ''
75 + [1] Let mutate str$6_@2[0:9] = ''
76 "]
77 bb0_instrs --> bb0_terminal(["If (read cond$5)"])
78 end
@@ -85,13 +85,13 @@ flowchart TB
85 end
86 subgraph bb3
87 bb3_instrs["
88 - [6] Reassign mutate str$8_@0[1:7] = 'fallthrough test'
88 + [6] Reassign mutate str$8_@2[0:9] = 'fallthrough test'
89 "]
90 bb3_instrs --> bb3_terminal(["Goto"])
91 end
92 subgraph bb1
93 bb1_instrs["
94 - [8] Call mutate log$4_@2(read str$10_@0)
94 + [8] Call mutate log$4_@2(read str$10_@2)
95 "]
96 bb1_instrs --> bb1_terminal(["Return"])
97 end
compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md
+11 -11
@@ -22,20 +22,20 @@ function foo() {
22 bb0:
23 [1] Let mutate y$5_@0 = 2
24 [2] Const mutate $6_@1 = 1
25 - [3] Const mutate $7_@2 = Binary read y$5_@0 > read $6_@1
26 - [4] If (read $7_@2) then:bb2 else:bb3
25 + [3] Const mutate $7_@3[3:10] = Binary read y$5_@0 > read $6_@1
26 + [4] If (read $7_@3) then:bb2 else:bb3
27 bb2:
28 predecessor blocks: bb0
29 - [5] Reassign mutate y$8_@3[5:10] = 1
29 + [5] Reassign mutate y$8_@3[3:10] = 1
30 [6] Goto bb1
31 bb3:
32 predecessor blocks: bb0
33 - [7] Reassign mutate y$9_@3[5:10] = 2
33 + [7] Reassign mutate y$9_@3[3:10] = 2
34 [8] Goto bb1
35 bb1:
36 predecessor blocks: bb2 bb3
37 - y$10_@3[5:10]: phi(bb2: y$8_@3, bb3: y$9_@3)
38 - [9] Let mutate x$11_@3[5:10] = read y$10_@3
37 + y$10_@3[3:10]: phi(bb2: y$8_@3, bb3: y$9_@3)
38 + [9] Let mutate x$11_@3[3:10] = read y$10_@3
39 [10] Return
40 ```
41
@@ -48,25 +48,25 @@ flowchart TB
48 bb0_instrs["
49 [1] Let mutate y$5_@0 = 2
50 [2] Const mutate $6_@1 = 1
51 - [3] Const mutate $7_@2 = Binary read y$5_@0 > read $6_@1
51 + [3] Const mutate $7_@3[3:10] = Binary read y$5_@0 > read $6_@1
52 "]
53 - bb0_instrs --> bb0_terminal(["If (read $7_@2)"])
53 + bb0_instrs --> bb0_terminal(["If (read $7_@3)"])
54 end
55 subgraph bb2
56 bb2_instrs["
57 - [5] Reassign mutate y$8_@3[5:10] = 1
57 + [5] Reassign mutate y$8_@3[3:10] = 1
58 "]
59 bb2_instrs --> bb2_terminal(["Goto"])
60 end
61 subgraph bb3
62 bb3_instrs["
63 - [7] Reassign mutate y$9_@3[5:10] = 2
63 + [7] Reassign mutate y$9_@3[3:10] = 2
64 "]
65 bb3_instrs --> bb3_terminal(["Goto"])
66 end
67 subgraph bb1
68 bb1_instrs["
69 - [9] Let mutate x$11_@3[5:10] = read y$10_@3
69 + [9] Let mutate x$11_@3[3:10] = read y$10_@3
70 "]
71 bb1_instrs --> bb1_terminal(["Return"])
72 end
compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md
+17 -17
@@ -32,30 +32,30 @@ bb0:
32 [2] Const mutate $11_@1 = 2
33 [3] Const mutate $12_@2 = Binary read x$10_@0 === read $11_@1
34 [4] Const mutate $13_@3 = 1
35 - [5] Const mutate $14_@4 = Binary read x$10_@0 === read $13_@3
35 + [5] Const mutate $14_@6[5:17] = Binary read x$10_@0 === read $13_@3
36 [6] Switch (read x$10_@0)
37 - Case read $14_@4: bb5
37 + Case read $14_@6: bb5
38 Case read $12_@2: bb3
39 Default: bb2
40 bb5:
41 predecessor blocks: bb0
42 - [7] Const mutate $15_@5 = 1
43 - [8] Reassign mutate x$16_@6[8:17] = Binary read x$10_@0 + read $15_@5
42 + [7] Const mutate $15_@6[5:17] = 1
43 + [8] Reassign mutate x$16_@6[5:17] = Binary read x$10_@0 + read $15_@6
44 [9] Goto bb1
45 bb3:
46 predecessor blocks: bb0
47 - [10] Const mutate $17_@7 = 2
48 - [11] Reassign mutate x$18_@6[8:17] = Binary read x$10_@0 + read $17_@7
47 + [10] Const mutate $17_@6[5:17] = 2
48 + [11] Reassign mutate x$18_@6[5:17] = Binary read x$10_@0 + read $17_@6
49 [12] Goto bb1
50 bb2:
51 predecessor blocks: bb0
52 [13] Const mutate $19_@8 = 3
53 - [14] Reassign mutate x$20_@6[8:17] = Binary read x$10_@0 + read $19_@8
53 + [14] Reassign mutate x$20_@6[5:17] = Binary read x$10_@0 + read $19_@8
54 [15] Goto bb1
55 bb1:
56 predecessor blocks: bb5 bb3 bb2
57 - x$21_@6[8:17]: phi(bb5: x$16_@6, bb3: x$18_@6, bb2: x$20_@6)
58 - [16] Let mutate y$22_@6[8:17] = read x$21_@6
57 + x$21_@6[5:17]: phi(bb5: x$16_@6, bb3: x$18_@6, bb2: x$20_@6)
58 + [16] Let mutate y$22_@6[5:17] = read x$21_@6
59 [17] Return
60 ```
61
@@ -70,40 +70,40 @@ flowchart TB
70 [2] Const mutate $11_@1 = 2
71 [3] Const mutate $12_@2 = Binary read x$10_@0 === read $11_@1
72 [4] Const mutate $13_@3 = 1
73 - [5] Const mutate $14_@4 = Binary read x$10_@0 === read $13_@3
73 + [5] Const mutate $14_@6[5:17] = Binary read x$10_@0 === read $13_@3
74 "]
75 bb0_instrs --> bb0_terminal(["Switch (read x$10_@0)"])
76 end
77 subgraph bb5
78 bb5_instrs["
79 - [7] Const mutate $15_@5 = 1
80 - [8] Reassign mutate x$16_@6[8:17] = Binary read x$10_@0 + read $15_@5
79 + [7] Const mutate $15_@6[5:17] = 1
80 + [8] Reassign mutate x$16_@6[5:17] = Binary read x$10_@0 + read $15_@6
81 "]
82 bb5_instrs --> bb5_terminal(["Goto"])
83 end
84 subgraph bb3
85 bb3_instrs["
86 - [10] Const mutate $17_@7 = 2
87 - [11] Reassign mutate x$18_@6[8:17] = Binary read x$10_@0 + read $17_@7
86 + [10] Const mutate $17_@6[5:17] = 2
87 + [11] Reassign mutate x$18_@6[5:17] = Binary read x$10_@0 + read $17_@6
88 "]
89 bb3_instrs --> bb3_terminal(["Goto"])
90 end
91 subgraph bb2
92 bb2_instrs["
93 [13] Const mutate $19_@8 = 3
94 - [14] Reassign mutate x$20_@6[8:17] = Binary read x$10_@0 + read $19_@8
94 + [14] Reassign mutate x$20_@6[5:17] = Binary read x$10_@0 + read $19_@8
95 "]
96 bb2_instrs --> bb2_terminal(["Goto"])
97 end
98 subgraph bb1
99 bb1_instrs["
100 - [16] Let mutate y$22_@6[8:17] = read x$21_@6
100 + [16] Let mutate y$22_@6[5:17] = read x$21_@6
101 "]
102 bb1_instrs --> bb1_terminal(["Return"])
103 end
104
105 %% Jumps
106 - bb0_terminal -- "read $14_@4" --> bb5
106 + bb0_terminal -- "read $14_@6" --> bb5
107 bb0_terminal -- "read $12_@2" --> bb3
108 bb0_terminal -- "default" --> bb2
109 bb0_terminal -- "fallthrough" --> bb1
compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md
+3 -3
@@ -22,11 +22,11 @@ bb0:
22 [4] If (read $6_@2) then:bb2 else:bb1
23 bb2:
24 predecessor blocks: bb0
25 - [5] Reassign mutate x$7_@0[1:6] = 2
25 + [5] Reassign mutate x$7_@0[1:7] = 2
26 [6] Goto bb1
27 bb1:
28 predecessor blocks: bb2 bb0
29 - x$8_@0[1:6]: phi(bb2: x$7_@0, bb0: x$4_@0)
29 + x$8_@0[1:7]: phi(bb2: x$7_@0, bb0: x$4_@0)
30 [7] Throw read x$8_@0
31 ```
32
@@ -45,7 +45,7 @@ flowchart TB
45 end
46 subgraph bb2
47 bb2_instrs["
48 - [5] Reassign mutate x$7_@0[1:6] = 2
48 + [5] Reassign mutate x$7_@0[1:7] = 2
49 "]
50 bb2_instrs --> bb2_terminal(["Goto"])
51 end
compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md
+5 -5
@@ -21,14 +21,14 @@ bb0:
21 [2] While test=bb1 loop=bb3 fallthrough=bb2
22 bb1:
23 predecessor blocks: bb0 bb3
24 - x$7_@0[0:8]: phi(bb0: x$5_@0, bb3: x$10_@0)
24 + x$7_@0[0:9]: phi(bb0: x$5_@0, bb3: x$10_@0)
25 [3] Const mutate $6_@1 = 10
26 [4] Const mutate $8_@2[4:9] = Binary read x$7_@0 < read $6_@1
27 [5] If (read $8_@2) then:bb3 else:bb2
28 bb3:
29 predecessor blocks: bb1
30 - [6] Const mutate $9_@3 = 1
31 - [7] Reassign mutate x$10_@0[0:8] = Binary read x$7_@0 + read $9_@3
30 + [6] Const mutate $9_@0[0:9] = 1
31 + [7] Reassign mutate x$10_@0[0:9] = Binary read x$7_@0 + read $9_@0
32 [8] Goto(Continue) bb1
33 bb2:
34 predecessor blocks: bb1
@@ -55,8 +55,8 @@ flowchart TB
55 end
56 subgraph bb3
57 bb3_instrs["
58 - [6] Const mutate $9_@3 = 1
59 - [7] Reassign mutate x$10_@0[0:8] = Binary read x$7_@0 + read $9_@3
58 + [6] Const mutate $9_@0[0:9] = 1
59 + [7] Reassign mutate x$10_@0[0:9] = Binary read x$7_@0 + read $9_@0
60 "]
61 bb3_instrs --> bb3_terminal(["Goto"])
62 end
compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md
+7 -7
@@ -33,7 +33,7 @@ function Component(props) {
33 ```
34 bb0:
35 [1] Let mutate x$10_@0[1:12] = Array []
36 - [2] Let mutate y$11_@0[1:11] = undefined
36 + [2] Let mutate y$11_@0[1:12] = undefined
37 [3] Const mutate $12_@1 = false
38 [4] Const mutate $13_@2 = true
39 [5] Const mutate $14_@3 = 1
@@ -45,15 +45,15 @@ bb0:
45 bb6:
46 predecessor blocks: bb0
47 [7] Call mutate x$10_@0.push(read props$9.p2)
48 - [8] Reassign mutate y$15_@0[1:11] = Array []
48 + [8] Reassign mutate y$15_@0[1:12] = Array []
49 [9] Goto bb1
50 bb2:
51 predecessor blocks: bb0
52 - [10] Reassign mutate y$16_@0[1:11] = read x$10_@0
52 + [10] Reassign mutate y$16_@0[1:12] = read x$10_@0
53 [11] Goto bb1
54 bb1:
55 predecessor blocks: bb0 bb6 bb2
56 - y$20_@0[1:11]: phi(bb0: y$11_@0, bb6: y$15_@0, bb2: y$16_@0)
56 + y$20_@0[1:12]: phi(bb0: y$11_@0, bb6: y$15_@0, bb2: y$16_@0)
57 [12] Const mutate child$19_@4 = JSX <read Component$0 data={freeze x$10_@0} ></read Component$0>
58 [13] Call read y$20_@0.push(read props$9.p4)
59 [14] Const mutate $22_@5 = JSX <read Component$0 data={freeze y$20_@0} >{read child$19_@4}</read Component$0>
@@ -68,7 +68,7 @@ flowchart TB
68 subgraph bb0
69 bb0_instrs["
70 [1] Let mutate x$10_@0[1:12] = Array []
71 - [2] Let mutate y$11_@0[1:11] = undefined
71 + [2] Let mutate y$11_@0[1:12] = undefined
72 [3] Const mutate $12_@1 = false
73 [4] Const mutate $13_@2 = true
74 [5] Const mutate $14_@3 = 1
@@ -78,13 +78,13 @@ flowchart TB
78 subgraph bb6
79 bb6_instrs["
80 [7] Call mutate x$10_@0.push(read props$9.p2)
81 - [8] Reassign mutate y$15_@0[1:11] = Array []
81 + [8] Reassign mutate y$15_@0[1:12] = Array []
82 "]
83 bb6_instrs --> bb6_terminal(["Goto"])
84 end
85 subgraph bb2
86 bb2_instrs["
87 - [10] Reassign mutate y$16_@0[1:11] = read x$10_@0
87 + [10] Reassign mutate y$16_@0[1:12] = read x$10_@0
88 "]
89 bb2_instrs --> bb2_terminal(["Goto"])
90 end
compiler/forget/src/__tests__/fixtures/hir/switch.expect.md
+5 -5
@@ -29,7 +29,7 @@ function Component(props) {
29 ```
30 bb0:
31 [1] Let mutate x$9_@0[1:12] = Array []
32 - [2] Let mutate y$10_@0[1:11] = undefined
32 + [2] Let mutate y$10_@0[1:12] = undefined
33 [3] Const mutate $11_@1 = false
34 [4] Const mutate $12_@2 = true
35 [5] Switch (read props$8.p0)
@@ -44,11 +44,11 @@ bb4:
44 [9] Goto bb2
45 bb2:
46 predecessor blocks: bb4 bb0
47 - [10] Reassign mutate y$15_@0[1:11] = read x$9_@0
47 + [10] Reassign mutate y$15_@0[1:12] = read x$9_@0
48 [11] Goto bb1
49 bb1:
50 predecessor blocks: bb2 bb0
51 - y$20_@0[1:11]: phi(bb2: y$15_@0, bb0: y$10_@0)
51 + y$20_@0[1:12]: phi(bb2: y$15_@0, bb0: y$10_@0)
52 [12] Const mutate child$19_@4 = JSX <read Component$0 data={freeze x$9_@0} ></read Component$0>
53 [13] Call read y$20_@0.push(read props$8.p4)
54 [14] Const mutate $23_@5 = JSX <read Component$0 data={read y$20_@0} >{read child$19_@4}</read Component$0>
@@ -63,7 +63,7 @@ flowchart TB
63 subgraph bb0
64 bb0_instrs["
65 [1] Let mutate x$9_@0[1:12] = Array []
66 - [2] Let mutate y$10_@0[1:11] = undefined
66 + [2] Let mutate y$10_@0[1:12] = undefined
67 [3] Const mutate $11_@1 = false
68 [4] Const mutate $12_@2 = true
69 "]
@@ -79,7 +79,7 @@ flowchart TB
79 end
80 subgraph bb2
81 bb2_instrs["
82 - [10] Reassign mutate y$15_@0[1:11] = read x$9_@0
82 + [10] Reassign mutate y$15_@0[1:12] = read x$9_@0
83 "]
84 bb2_instrs --> bb2_terminal(["Goto"])
85 end