@samitouri / QOS-React-2 / commits / dd1ff4dc30

Combine dependency collection and propagation, more precise collection

I realized that properly propagating scope dependencies requires reusing the same logic as dependency collection itself: a dependency of an inner scope should only be propagated upward if the dependency was declared before the outer scope, for example. So this PR reimplements dependency collection in the propagation pass. At the same time I made a few other improvements: * Don't report dependencies that are "constant". This is a bit simplistic for now, we can use a more advanced analysis later. * Try to avoid creating duplicate dependencies. This addresses the todo from the previous PR (flattening scopes in loops) since now we don't need to compute deps until after that runs. As a follow-up i'll remove the existing dependency collection.

Joe Savona committed Dec 14, 2022 at 08:42 UTC dd1ff4dc302b1cdcfd0df7494a6abbb9b9f73006
47 files changed +392 -120
compiler/forget/src/HIR/InferReactiveScopeDependencies.ts
+56
@@ -37,6 +37,7 @@ export function instructionInScope(
37 class ScopeDependenciesVisitor
38 implements Visitor<void, void, void, void, InstructionValue, void, void>
39 {
40 + #kinds: Map<Identifier, DeclKind> = new Map();
41 #identifiers: Map<Identifier, InstructionId> = new Map();
42 // Scopes that are currently active at this point in the traversal
43 #activeScopes: Set<ReactiveScope> = new Set();
@@ -49,9 +50,11 @@ class ScopeDependenciesVisitor
50 constructor(fn: HIRFunction) {
51 if (fn.id !== null) {
52 this.#identifiers.set(fn.id, makeInstructionId(0));
53 + this.#kinds.set(fn.id, DeclKind.Const);
54 }
55 for (const param of fn.params) {
56 this.#identifiers.set(param.identifier, makeInstructionId(0));
57 + this.#kinds.set(param.identifier, DeclKind.Dynamic);
58 }
59 }
60
@@ -190,3 +193,56 @@ class ScopeDependenciesVisitor
193 }
194 leaveInitBlock(block: void): void {}
195 }
196 +
197 +enum DeclKind {
198 + Const = "Const",
199 + Dynamic = "Dynamic",
200 +}
201 +
202 +function visitOperand(
203 + operand: Place,
204 + dependencies: Set<Place>,
205 + declarations: Map<Identifier, DeclKind>
206 +): void {
207 + const kind = declarations.get(operand.identifier);
208 + if (kind === undefined) {
209 + // TODO: global, ignore
210 + return;
211 + } else if (kind === DeclKind.Const) {
212 + // constant, dont need to add a dep
213 + return;
214 + } else {
215 + for (const dep of dependencies) {
216 + // not the same identifier
217 + if (dep.identifier !== operand.identifier) {
218 + continue;
219 + }
220 + const depPath = dep.memberPath;
221 + // existing dep covers all paths
222 + if (depPath === null) {
223 + return;
224 + }
225 + const operandPath = operand.memberPath;
226 + // existing dep is for a path, this operand covers all paths so swap them
227 + if (operandPath === null) {
228 + dependencies.delete(dep);
229 + dependencies.add(operand);
230 + return;
231 + }
232 + // both the operand and dep have paths, determine if the existing path
233 + // is a subset of the new path
234 + let commonPathIndex = 0;
235 + while (
236 + commonPathIndex < operandPath.length &&
237 + commonPathIndex < depPath.length &&
238 + operandPath[commonPathIndex] === depPath[commonPathIndex]
239 + ) {
240 + commonPathIndex++;
241 + }
242 + if (commonPathIndex === depPath.length) {
243 + return;
244 + }
245 + }
246 + dependencies.add(operand);
247 + }
248 +}
compiler/forget/src/HIR/PropagateScopeDependencies.ts
+255 -14
@@ -6,57 +6,160 @@
6 */
7
8 import { assertExhaustive } from "../Common/utils";
9 -import { Place, ReactiveBasicBlock, ReactiveFunction } from "./HIR";
9 +import {
10 + Identifier,
11 + Instruction,
12 + InstructionId,
13 + InstructionKind,
14 + InstructionValue,
15 + makeInstructionId,
16 + Place,
17 + ReactiveBasicBlock,
18 + ReactiveFunction,
19 + ReactiveValueBlock,
20 +} from "./HIR";
21 +import { eachInstructionValueOperand } from "./visitors";
22
23 /**
12 - * Propagates the dependencies of each scope to its parent scope(s).
24 + * Infers the dependencies of each scope to include variables whose values
25 + * are non-stable and created prior to the start of the scope. Also propagates
26 + * dependencies upwards, so that parent scope dependencies are the union of
27 + * their direct dependencies and those of their child scopes.
28 */
29 export function propagateScopeDependencies(fn: ReactiveFunction): void {
30 const dependencies: Set<Place> = new Set();
16 - visit(fn.body, dependencies);
31 + const declarations: DeclMap = new Map();
32 + if (fn.id !== null) {
33 + declarations.set(fn.id, { kind: DeclKind.Const, id: makeInstructionId(0) });
34 + }
35 + for (const param of fn.params) {
36 + declarations.set(param.identifier, {
37 + kind: DeclKind.Dynamic,
38 + id: makeInstructionId(0),
39 + });
40 + }
41 + visit(fn.body, dependencies, declarations, null);
42 +}
43 +
44 +enum DeclKind {
45 + Const = "Const",
46 + Dynamic = "Dynamic",
47 }
48
19 -function visit(block: ReactiveBasicBlock, dependencies: Set<Place>): void {
49 +type DeclMap = Map<Identifier, { kind: DeclKind; id: InstructionId }>;
50 +
51 +function visit(
52 + block: ReactiveBasicBlock,
53 + dependencies: Set<Place>,
54 + declarations: DeclMap,
55 + scopeStart: InstructionId | null
56 +): void {
57 for (const item of block) {
58 switch (item.kind) {
59 case "block": {
23 - visit(item.instructions, item.dependencies);
24 - for (const dep of item.dependencies) {
25 - dependencies.add(dep);
60 + const scopeDependencies: Set<Place> = new Set();
61 + // TODO: it would be sufficient to use a single mapping of declarations
62 + const scopeDeclarations: DeclMap = new Map(declarations);
63 + visit(
64 + item.instructions,
65 + scopeDependencies,
66 + scopeDeclarations,
67 + item.range.start
68 + );
69 + item.dependencies = scopeDependencies;
70 + for (const dep of scopeDependencies) {
71 + // propagate dependencies upward using the same rules as
72 + // normal dependency collection. child scopes may have dependencies
73 + // on values created within the outer scope, which necessarily cannot
74 + // be dependencies of the outer scope
75 + visitOperand(dep, dependencies, declarations, scopeStart);
76 + }
77 + for (const [ident, kind] of scopeDeclarations) {
78 + declarations.set(ident, kind);
79 }
80 break;
81 }
82 case "instruction": {
83 + visitInstruction(
84 + item.instruction,
85 + dependencies,
86 + declarations,
87 + scopeStart
88 + );
89 break;
90 }
91 case "terminal": {
92 const terminal = item.terminal;
93 switch (terminal.kind) {
94 case "break":
36 - case "continue":
37 - case "return":
95 + case "continue": {
96 + break;
97 + }
98 + case "return": {
99 + if (terminal.value !== null) {
100 + visitOperand(
101 + terminal.value,
102 + dependencies,
103 + declarations,
104 + scopeStart
105 + );
106 + }
107 + break;
108 + }
109 case "throw": {
110 + visitOperand(
111 + terminal.value,
112 + dependencies,
113 + declarations,
114 + scopeStart
115 + );
116 break;
117 }
118 case "for": {
42 - visit(terminal.loop, dependencies);
119 + visitValueBlock(
120 + terminal.init,
121 + dependencies,
122 + declarations,
123 + scopeStart
124 + );
125 + visitValueBlock(
126 + terminal.test,
127 + dependencies,
128 + declarations,
129 + scopeStart
130 + );
131 + visitValueBlock(
132 + terminal.update,
133 + dependencies,
134 + declarations,
135 + scopeStart
136 + );
137 + visit(terminal.loop, dependencies, declarations, scopeStart);
138 break;
139 }
140 case "while": {
46 - visit(terminal.loop, dependencies);
141 + visitValueBlock(
142 + terminal.test,
143 + dependencies,
144 + declarations,
145 + scopeStart
146 + );
147 + visit(terminal.loop, dependencies, declarations, scopeStart);
148 break;
149 }
150 case "if": {
50 - visit(terminal.consequent, dependencies);
151 + visitOperand(terminal.test, dependencies, declarations, scopeStart);
152 + visit(terminal.consequent, dependencies, declarations, scopeStart);
153 if (terminal.alternate !== null) {
52 - visit(terminal.alternate, dependencies);
154 + visit(terminal.alternate, dependencies, declarations, scopeStart);
155 }
156 break;
157 }
158 case "switch": {
159 + visitOperand(terminal.test, dependencies, declarations, scopeStart);
160 for (const case_ of terminal.cases) {
161 if (case_.block !== undefined) {
59 - visit(case_.block, dependencies);
162 + visit(case_.block, dependencies, declarations, scopeStart);
163 }
164 }
165 break;
@@ -76,3 +179,141 @@ function visit(block: ReactiveBasicBlock, dependencies: Set<Place>): void {
179 }
180 }
181 }
182 +
183 +function visitValueBlock(
184 + block: ReactiveValueBlock,
185 + dependencies: Set<Place>,
186 + declarations: DeclMap,
187 + scopeStart: InstructionId | null
188 +): void {
189 + for (const initItem of block.instructions) {
190 + if (initItem.kind === "instruction") {
191 + visitInstruction(
192 + initItem.instruction,
193 + dependencies,
194 + declarations,
195 + scopeStart
196 + );
197 + }
198 + }
199 + if (block.value !== null) {
200 + visitInstructionValue(block.value, dependencies, declarations, scopeStart);
201 + }
202 +}
203 +
204 +function visitOperand(
205 + operand: Place,
206 + dependencies: Set<Place>,
207 + declarations: DeclMap,
208 + scopeStart: InstructionId | null
209 +): void {
210 + const decl = declarations.get(operand.identifier);
211 + if (decl === undefined) {
212 + // Probably a global, ignore for now
213 + // TODO @josephsavona: improve handling of globals
214 + return;
215 + } else if (decl.kind === DeclKind.Const) {
216 + // constant, dont need to add a dep
217 + return;
218 + } else if (scopeStart !== null && decl.id < scopeStart) {
219 + // Check if there is an existing dependency that describes this operand
220 + for (const dep of dependencies) {
221 + // not the same identifier
222 + if (dep.identifier !== operand.identifier) {
223 + continue;
224 + }
225 + const depPath = dep.memberPath;
226 + // existing dep covers all paths
227 + if (depPath === null) {
228 + return;
229 + }
230 + const operandPath = operand.memberPath;
231 + // existing dep is for a path, this operand covers all paths so swap them
232 + if (operandPath === null) {
233 + dependencies.delete(dep);
234 + dependencies.add(operand);
235 + return;
236 + }
237 + // both the operand and dep have paths, determine if the existing path
238 + // is a subset of the new path
239 + let commonPathIndex = 0;
240 + while (
241 + commonPathIndex < operandPath.length &&
242 + commonPathIndex < depPath.length &&
243 + operandPath[commonPathIndex] === depPath[commonPathIndex]
244 + ) {
245 + commonPathIndex++;
246 + }
247 + if (commonPathIndex === depPath.length) {
248 + return;
249 + }
250 + }
251 + dependencies.add(operand);
252 + }
253 +}
254 +
255 +function visitInstructionValue(
256 + value: InstructionValue,
257 + dependencies: Set<Place>,
258 + declarations: DeclMap,
259 + scopeStart: InstructionId | null
260 +): void {
261 + for (const operand of eachInstructionValueOperand(value)) {
262 + // check for method invocation, we want to depend on the callee, not the method
263 + if (
264 + value.kind === "CallExpression" &&
265 + operand === value.callee &&
266 + operand.memberPath !== null
267 + ) {
268 + const callee = {
269 + ...operand,
270 + memberPath: operand.memberPath.slice(0, -1),
271 + };
272 + visitOperand(callee, dependencies, declarations, scopeStart);
273 + } else {
274 + visitOperand(operand, dependencies, declarations, scopeStart);
275 + }
276 + }
277 +}
278 +
279 +function visitInstruction(
280 + instr: Instruction,
281 + dependencies: Set<Place>,
282 + declarations: DeclMap,
283 + scopeStart: InstructionId | null
284 +): void {
285 + visitInstructionValue(instr.value, dependencies, declarations, scopeStart);
286 + const { lvalue } = instr;
287 + if (
288 + lvalue !== null &&
289 + lvalue.kind !== InstructionKind.Reassign &&
290 + lvalue.place.memberPath === null
291 + ) {
292 + const kind = valueKind(instr.value);
293 + declarations.set(lvalue.place.identifier, { kind, id: instr.id });
294 + }
295 +}
296 +
297 +function valueKind(value: InstructionValue): DeclKind {
298 + switch (value.kind) {
299 + case "BinaryExpression":
300 + case "JSXText":
301 + case "Primitive": {
302 + return DeclKind.Const;
303 + }
304 + case "Identifier":
305 + case "ArrayExpression":
306 + case "CallExpression":
307 + case "JsxExpression":
308 + case "JsxFragment":
309 + case "NewExpression":
310 + case "ObjectExpression":
311 + case "OtherStatement":
312 + case "UnaryExpression": {
313 + return DeclKind.Dynamic;
314 + }
315 + default: {
316 + assertExhaustive(value, `Unexpected value kind '${(value as any).kind}'`);
317 + }
318 + }
319 +}
compiler/forget/src/__tests__/fixtures/hir/_bug_conditional-break-labeled.expect.md
+1 -1
@@ -47,7 +47,7 @@ scope0 [1:7]:
47 function Component(
48 props,
49 ) {
50 - scope @0 [1:7] deps=[read props$3.a, read props$3.d, read props$3.c] {
50 + scope @0 [1:7] deps=[read props$3.a, read props$3.b, read props$3.d, read props$3.c] {
51 [1] Const mutate a$4_@0:TFunction[1:7] = Array []
52 [2] Call mutate a$4_@0.push(read props$3.a)
53 if (read props$3.b) {
compiler/forget/src/__tests__/fixtures/hir/call.expect.md
+3 -5
@@ -52,8 +52,6 @@ bb0:
52 [7] Const mutate $14:TPrimitive = "div"
53 [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0:TObject} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
54 [9] Return read $15_@2
55 -scope0 [1:7]:
56 - - dependency: read $12:TPrimitive
55 scope1 [5:6]:
56 - dependency: read $12:TPrimitive
57 scope2 [8:9]:
@@ -68,18 +66,18 @@ scope2 [8:9]:
66 function Component(
67 props,
68 ) {
71 - scope @0 [1:7] deps=[read $12:TPrimitive] {
69 + scope @0 [1:7] deps=[] {
70 [1] Const mutate a$10_@0:TObject[1:7] = Array []
71 [2] Const mutate b$11_@0:TObject[1:7] = Object { }
72 [3] Call mutate foo$4:TFunction(mutate a$10_@0:TObject, mutate b$11_@0:TObject)
73 [4] Const mutate $12:TPrimitive = "div"
76 - scope @1 [5:6] deps=[read $12:TPrimitive] {
74 + scope @1 [5:6] deps=[freeze a$10_@0:TObject] {
75 [5] Const mutate _$13_@1 = JSX <read $12:TPrimitive a={freeze a$10_@0:TObject} ></read $12:TPrimitive>
76 }
77 [6] Call mutate foo$4:TFunction(mutate b$11_@0:TObject)
78 }
79 [7] Const mutate $14:TPrimitive = "div"
82 - scope @2 [8:9] deps=[read $14:TPrimitive, read a$10_@0:TObject, freeze b$11_@0:TObject] {
80 + scope @2 [8:9] deps=[read a$10_@0:TObject, freeze b$11_@0:TObject] {
81 [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0:TObject} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
82 }
83 return read $15_@2
compiler/forget/src/__tests__/fixtures/hir/component.expect.md
+4 -7
@@ -100,9 +100,6 @@ bb2:
100 [40] Const mutate $73 = "\n "
101 [41] Const mutate $74_@5 = JSX <read $67:TPrimitive>{read $68}{read $71_@4}{read $72}{freeze renderedItems$32_@0:TFunction}{read $73}</read $67:TPrimitive>
102 [42] Return read $74_@5
103 -scope0 [3:33]:
104 - - dependency: read $34:TPrimitive
105 - - dependency: read maxItems$31:TProp
103 scope2 [6:7]:
104 - dependency: read $34:TPrimitive
105 - dependency: read maxItems$31:TProp
@@ -129,11 +126,11 @@ function Component(
126 ) {
127 [1] Const mutate items$30:TProp = read props$29.items
128 [2] Const mutate maxItems$31:TProp = read props$29.maxItems
132 - scope @0 [3:33] deps=[read $34:TPrimitive, read maxItems$31:TProp] {
129 + scope @0 [3:33] deps=[read maxItems$31:TProp, read items$30.length, read items$30] {
130 [3] Const mutate renderedItems$32_@0:TFunction[3:33] = Array []
131 [4] Const mutate seen$33_@0:TFunction[3:33] = New mutate Set$6()
132 [5] Const mutate $34:TPrimitive = 0
136 - scope @2 [6:7] deps=[read $34:TPrimitive, read maxItems$31:TProp] {
133 + scope @2 [6:7] deps=[read maxItems$31:TProp] {
134 [6] Const mutate max$35_@2:TPrimitive = Call mutate Math$8.max(read $34:TPrimitive, read maxItems$31:TProp)
135 }
136 for (
@@ -173,12 +170,12 @@ function Component(
170 [35] Const mutate $68 = "\n "
171 [36] Const mutate $69:TPrimitive = "h1"
172 [37] Const mutate $70 = " Items"
176 - scope @4 [38:39] deps=[read $69:TPrimitive, freeze count$66:TProp, read $70] {
173 + scope @4 [38:39] deps=[freeze count$66:TProp] {
174 [38] Const mutate $71_@4 = JSX <read $69:TPrimitive>{freeze count$66:TProp}{read $70}</read $69:TPrimitive>
175 }
176 [39] Const mutate $72 = "\n "
177 [40] Const mutate $73 = "\n "
181 - scope @5 [41:42] deps=[read $67:TPrimitive, read $68, read $71_@4, read $72, freeze renderedItems$32_@0:TFunction, read $73] {
178 + scope @5 [41:42] deps=[read $71_@4, freeze renderedItems$32_@0:TFunction] {
179 [41] Const mutate $74_@5 = JSX <read $67:TPrimitive>{read $68}{read $71_@4}{read $72}{freeze renderedItems$32_@0:TFunction}{read $73}</read $67:TPrimitive>
180 }
181 return read $74_@5
compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md
+4 -4
@@ -158,7 +158,7 @@ scope0 [1:7]:
158 function Component(
159 props,
160 ) {
161 - scope @0 [1:7] deps=[read props$3.a, read props$3.c, read props$3.b, read props$3.d] {
161 + scope @0 [1:7] deps=[read props$3.a, read props$3.b, read props$3.c, read props$3.d] {
162 [1] Const mutate a$4_@0:TFunction[1:7] = Array []
163 [2] Call mutate a$4_@0.push(read props$3.a)
164 if (read props$3.b) {
@@ -215,7 +215,7 @@ scope0 [1:8]:
215 function Component(
216 props,
217 ) {
218 - scope @0 [1:8] deps=[read props$4.a, read props$4.c, read props$4.b, read props$4.d] {
218 + scope @0 [1:8] deps=[read props$4.a, read props$4.b, read props$4.c, read props$4.d] {
219 [1] Const mutate a$5_@0:TFunction[1:8] = Array []
220 [2] Call mutate a$5_@0.push(read props$4.a)
221 if (read props$4.b) {
@@ -274,7 +274,7 @@ scope0 [1:7]:
274 function Component(
275 props,
276 ) {
277 - scope @0 [1:7] deps=[read props$3.a, read props$3.c, read props$3.b, read props$3.d] {
277 + scope @0 [1:7] deps=[read props$3.a, read props$3.b, read props$3.c, read props$3.d] {
278 [1] Const mutate a$4_@0:TFunction[1:7] = Array []
279 [2] Call mutate a$4_@0.push(read props$3.a)
280 if (read props$3.b) {
@@ -331,7 +331,7 @@ scope0 [1:7]:
331 function Component(
332 props,
333 ) {
334 - scope @0 [1:7] deps=[read props$3.a, read props$3.d, read props$3.c] {
334 + scope @0 [1:7] deps=[read props$3.a, read props$3.b, read props$3.d, read props$3.c] {
335 [1] Const mutate a$4_@0:TFunction[1:7] = Array []
336 [2] Call mutate a$4_@0.push(read props$3.a)
337 if (read props$3.b) {
compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md
+2 -2
@@ -64,7 +64,7 @@ scope2 [9:10]:
64 function Component(
65 props,
66 ) {
67 - scope @0 [1:9] deps=[] {
67 + scope @0 [1:9] deps=[read props$6.p0, read props$6.p1, read props$6.p2] {
68 [1] Const mutate a$7_@0:TFunction[1:9] = Array []
69 [2] Const mutate b$8_@0:TFunction[1:9] = Array []
70 if (read b$8_@0:TFunction) {
@@ -134,7 +134,7 @@ scope2 [10:11]:
134 function Component(
135 props,
136 ) {
137 - scope @0 [1:10] deps=[] {
137 + scope @0 [1:10] deps=[read props$8.p0, read props$8.p1, read props$8.p2] {
138 [1] Const mutate a$9_@0:TFunction[1:10] = Array []
139 [2] Const mutate b$10_@0:TFunction[1:10] = Array []
140 [3] Const mutate $11_@0[1:10] = Call mutate mayMutate$4:TFunction(mutate b$10_@0:TFunction)
compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md
+3 -5
@@ -52,8 +52,6 @@ bb0:
52 [7] Const mutate $14:TPrimitive = "div"
53 [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
54 [9] Return read $15_@2
55 -scope0 [1:7]:
56 - - dependency: read $12:TPrimitive
55 scope1 [5:6]:
56 - dependency: read $12:TPrimitive
57 scope2 [8:9]:
@@ -68,18 +66,18 @@ scope2 [8:9]:
66 function Component(
67 props,
68 ) {
71 - scope @0 [1:7] deps=[read $12:TPrimitive] {
69 + scope @0 [1:7] deps=[] {
70 [1] Const mutate a$10_@0[1:7] = Array []
71 [2] Const mutate b$11_@0:TObject[1:7] = Object { }
72 [3] New mutate Foo$4(mutate a$10_@0, mutate b$11_@0:TObject)
73 [4] Const mutate $12:TPrimitive = "div"
76 - scope @1 [5:6] deps=[read $12:TPrimitive] {
74 + scope @1 [5:6] deps=[freeze a$10_@0] {
75 [5] Const mutate _$13_@1 = JSX <read $12:TPrimitive a={freeze a$10_@0} ></read $12:TPrimitive>
76 }
77 [6] New mutate Foo$4(mutate b$11_@0:TObject)
78 }
79 [7] Const mutate $14:TPrimitive = "div"
82 - scope @2 [8:9] deps=[read $14:TPrimitive, read a$10_@0, freeze b$11_@0:TObject] {
80 + scope @2 [8:9] deps=[read a$10_@0, freeze b$11_@0:TObject] {
81 [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
82 }
83 return read $15_@2
compiler/forget/src/__tests__/fixtures/hir/dependencies-outputs.expect.md
+1 -1
@@ -64,7 +64,7 @@ function foo(
64 }
65 [3] Const mutate $9:TPrimitive = "div"
66 [4] JSX <read $9:TPrimitive>{freeze x$8_@0:TFunction}</read $9:TPrimitive>
67 - scope @1 [5:12] deps=[read x$8_@0:TFunction, read x$8_@0.length, read b$7:TFunction, read b$7:TFunction] {
67 + scope @1 [5:12] deps=[read x$8_@0:TFunction, read b$7:TFunction] {
68 [5] Const mutate y$10_@1:TFunction[5:12] = Array []
69 if (read x$8_@0.length) {
70 [7] Call mutate y$10_@1.push(read x$8_@0:TFunction)
compiler/forget/src/__tests__/fixtures/hir/dependencies.expect.md
+2 -4
@@ -47,8 +47,6 @@ scope0 [1:10]:
47 - dependency: read x$6
48 - dependency: read x$6
49 - dependency: read y$7
50 - - dependency: read y$7
51 - - dependency: read x$6
50 scope1 [3:7]:
51 - dependency: read y$7
52 - dependency: read x$6
@@ -62,10 +60,10 @@ function foo(
60 y,
61 z,
62 ) {
65 - scope @0 [1:10] deps=[read z$8, read x$6, read x$6, read y$7, read y$7, read x$6] {
63 + scope @0 [1:10] deps=[read z$8, read x$6, read y$7] {
64 [1] Const mutate items$9_@0:TFunction[1:10] = Array [read z$8]
65 [2] Call mutate items$9_@0.push(read x$6)
68 - scope @1 [3:7] deps=[read y$7, read x$6] {
66 + scope @1 [3:7] deps=[read x$6, read y$7] {
67 [3] Const mutate items2$10_@1:TFunction[3:7] = Array []
68 if (read x$6) {
69 [5] Call mutate items2$10_@1.push(read y$7)
compiler/forget/src/__tests__/fixtures/hir/extend-scopes-if.expect.md
+1 -1
@@ -60,7 +60,7 @@ function foo(
60 b,
61 c,
62 ) {
63 - scope @0 [1:8] deps=[read c$9, read b$8, read a$7] {
63 + scope @0 [1:8] deps=[read a$7, read b$8, read c$9] {
64 [1] Const mutate x$10_@0:TFunction[1:8] = Array []
65 if (read a$7) {
66 if (read b$8) {
compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md
+1 -1
@@ -106,7 +106,7 @@ function Component(
106 [4] Const mutate $13 = "\n "
107 [5] Const mutate $14 = "\n "
108 [6] Const mutate $15 = "\n "
109 - scope @2 [7:8] deps=[read Component$0, read $13, read x$11_@0, read $14, read y$12_@1, read $15] {
109 + scope @2 [7:8] deps=[read x$11_@0, read y$12_@1] {
110 [7] Const mutate $16_@2 = JSX <read Component$0>{read $13}{read x$11_@0}{read $14}{read y$12_@1}{read $15}</read Component$0>
111 }
112 return read $16_@2
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md
+1 -1
@@ -59,7 +59,7 @@ function Component(
59 [1] Const mutate cond$8:TProp = read props$7.cond
60 [2] Const mutate x$9:TProp = read props$7.x
61 [3] Const mutate a$10:TPrimitive = undefined
62 - scope @0 [4:9] deps=[read x$9:TProp, read cond$8:TProp] {
62 + scope @0 [4:9] deps=[read cond$8:TProp, read x$9:TProp] {
63 [4] Let mutate a$11_@0:TProp[4:9] = undefined
64 if (read cond$8:TProp) {
65 [5] Reassign mutate a$11_@0:TProp[4:9] = read x$9:TProp
compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md
+1 -1
@@ -158,7 +158,7 @@ scope2 [7:8]:
158 function Component(
159 props,
160 ) {
161 - scope @1 [1:7] deps=[read props$8.a] {
161 + scope @1 [1:7] deps=[read props$8.a, read props$8.b, read props$8.c] {
162 [1] Const mutate a$9_@1[1:7] = Call mutate compute$3:TFunction(read props$8.a)
163 [2] Const mutate b$10_@1[1:7] = Call mutate compute$3:TFunction(read props$8.b)
164 if (read props$8.c) {
compiler/forget/src/__tests__/fixtures/hir/inverted-if.expect.md
+1 -1
@@ -44,7 +44,7 @@ function foo(
44 b,
45 c,
46 ) {
47 - scope @0 [1:6] deps=[read c$7, read b$6, read a$5] {
47 + scope @0 [1:6] deps=[read a$5, read b$6, read c$7] {
48 [1] Const mutate y$8_@0:TFunction[1:6] = Array []
49 if (read a$5) {
50 if (read b$6) {
compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md
+3 -3
@@ -59,15 +59,15 @@ function Foo(
59 [4] Const mutate $17:TPrimitive = "div"
60 [5] Const mutate $18 = "\n "
61 [6] Const mutate $19 = "Text"
62 - scope @0 [7:8] deps=[read $19] {
62 + scope @0 [7:8] deps=[] {
63 [7] Const mutate $20_@0 = JsxFragment [read $19]
64 }
65 [8] Const mutate $21 = "\n "
66 - scope @1 [9:10] deps=[read $17:TPrimitive, read $18, read $20_@0, read $21] {
66 + scope @1 [9:10] deps=[read $20_@0] {
67 [9] Const mutate $22_@1 = JSX <read $17:TPrimitive>{read $18}{read $20_@0}{read $21}</read $17:TPrimitive>
68 }
69 [10] Const mutate $23 = "\n "
70 - scope @2 [11:12] deps=[read $14, read props$13.greeting, read $15:TPrimitive, read $16, read $22_@1, read $23] {
70 + scope @2 [11:12] deps=[read props$13.greeting, read $22_@1] {
71 [11] Const mutate $24_@2 = JsxFragment [read $14, read props$13.greeting, read $15:TPrimitive, read $16, read $22_@1, read $23]
72 }
73 return read $24_@2
compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md
+3 -3
@@ -50,7 +50,7 @@ function And(
50 scope @0 [1:2] deps=[] {
51 [1] Const mutate $5_@0 = Call mutate f$1:TFunction()
52 }
53 - scope @1 [2:7] deps=[read $5_@0, read $5_@0] {
53 + scope @1 [2:7] deps=[read $5_@0] {
54 [2] Let mutate $6_@1[2:7] = undefined
55 if (read $5_@0) {
56 [3] Const mutate $6_@1[2:7] = Call mutate g$4:TFunction()
@@ -105,7 +105,7 @@ function Or(
105 scope @0 [1:2] deps=[] {
106 [1] Const mutate $5_@0 = Call mutate f$1:TFunction()
107 }
108 - scope @1 [2:7] deps=[read $5_@0, read $5_@0] {
108 + scope @1 [2:7] deps=[read $5_@0] {
109 [2] Let mutate $6_@1[2:7] = undefined
110 if (read $5_@0) {
111 [3] Const mutate $6_@1[2:7] = read $5_@0
@@ -165,7 +165,7 @@ function QuestionQuestion(
165 }
166 [2] Const mutate $10:TPrimitive = null
167 [3] Const mutate $11:TPrimitive = Binary read $9_@0:TPrimitive != read $10:TPrimitive
168 - scope @1 [4:9] deps=[read $9_@0:TPrimitive, read $11:TPrimitive] {
168 + scope @1 [4:9] deps=[read $9_@0:TPrimitive] {
169 [4] Let mutate $12_@1:TPrimitive[4:9] = undefined
170 if (read $11:TPrimitive) {
171 [5] Const mutate $12_@1:TPrimitive[4:9] = read $9_@0:TPrimitive
compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md
+1 -1
@@ -104,7 +104,7 @@ function Component(
104 scope @0 [1:2] deps=[] {
105 [1] Const mutate a$11_@0:TObject = Object { }
106 }
107 - scope @1 [2:15] deps=[read a$11_@0:TObject, read a$11_@0:TObject] {
107 + scope @1 [2:15] deps=[read a$11_@0:TObject] {
108 [2] Const mutate b$12_@1[2:15] = Array [read a$11_@0:TObject]
109 scope @2 [3:4] deps=[] {
110 [3] Const mutate c$13_@2:TObject = Object { }
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved-by-terminal.expect.md
+1 -1
@@ -38,7 +38,7 @@ function foo(
38 b,
39 c,
40 ) {
41 - scope @0 [1:6] deps=[] {
41 + scope @0 [1:6] deps=[read a$6, read b$7] {
42 [1] Const mutate x$9_@0:TFunction[1:6] = Array []
43 [2] Const mutate y$10_@0:TFunction[1:6] = Array []
44 if (read x$9_@0:TFunction) {
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved.expect.md
+1 -1
@@ -30,7 +30,7 @@ function foo(
30 a,
31 b,
32 ) {
33 - scope @0 [1:5] deps=[] {
33 + scope @0 [1:5] deps=[read a$5, read b$6] {
34 [1] Const mutate x$7_@0:TFunction[1:5] = Array []
35 [2] Const mutate y$8_@0:TFunction[1:5] = Array []
36 [3] Call mutate x$7_@0.push(read a$5)
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowed.expect.md
+1 -2
@@ -22,7 +22,6 @@ bb0:
22 [5] Return
23 scope0 [1:5]:
24 - dependency: read a$5
25 - - dependency: read b$6
25 scope1 [2:4]:
26 - dependency: read b$6
27 ```
@@ -34,7 +33,7 @@ function foo(
33 a,
34 b,
35 ) {
37 - scope @0 [1:5] deps=[read a$5, read b$6] {
36 + scope @0 [1:5] deps=[read b$6, read a$5] {
37 [1] Const mutate x$7_@0:TFunction[1:5] = Array []
38 scope @1 [2:4] deps=[read b$6] {
39 [2] Const mutate y$8_@1:TFunction[2:4] = Array []
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md
+3 -7
@@ -42,10 +42,6 @@ bb1:
42 [11] Return freeze x$11_@0:TFunction
43 scope0 [1:11]:
44 - dependency: read a$8
45 - - dependency: read c$10
46 - - dependency: read b$9
47 - - dependency: read $13:TPrimitive
48 - - dependency: freeze y$12_@1:TFunction
45 scope1 [3:7]:
46 - dependency: read c$10
47 - dependency: read b$9
@@ -62,17 +58,17 @@ function foo(
58 b,
59 c,
60 ) {
65 - scope @0 [1:11] deps=[read a$8, read c$10, read b$9, read $13:TPrimitive, freeze y$12_@1:TFunction] {
61 + scope @0 [1:11] deps=[read a$8, read b$9, read c$10] {
62 [1] Const mutate x$11_@0:TFunction[1:11] = Array []
63 if (read a$8) {
68 - scope @1 [3:7] deps=[read c$10, read b$9] {
64 + scope @1 [3:7] deps=[read b$9, read c$10] {
65 [3] Const mutate y$12_@1:TFunction[3:7] = Array []
66 if (read b$9) {
67 [5] Call mutate y$12_@1.push(read c$10)
68 }
69 }
70 [7] Const mutate $13:TPrimitive = "div"
75 - scope @2 [8:9] deps=[read $13:TPrimitive, freeze y$12_@1:TFunction] {
71 + scope @2 [8:9] deps=[freeze y$12_@1:TFunction] {
72 [8] Const mutate $15_@2 = JSX <read $13:TPrimitive>{freeze y$12_@1:TFunction}</read $13:TPrimitive>
73 }
74 [9] Call mutate x$11_@0.push(read $15_@2)
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-while.expect.md
+1 -1
@@ -42,7 +42,7 @@ function foo(
42 b,
43 c,
44 ) {
45 - scope @0 [1:8] deps=[] {
45 + scope @0 [1:8] deps=[read c$8, read b$7, read a$6] {
46 [1] Const mutate x$9_@0:TFunction[1:8] = Array []
47 [2] Const mutate y$10_@0:TFunction[1:8] = Array []
48 while (
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-within-block.expect.md
+1 -1
@@ -52,7 +52,7 @@ function foo(
52 b,
53 c,
54 ) {
55 - scope @0 [1:9] deps=[read c$8, read b$7, read a$6] {
55 + scope @0 [1:9] deps=[read a$6, read b$7, read c$8] {
56 [1] Const mutate x$9_@0:TFunction[1:9] = Array []
57 if (read a$6) {
58 [3] Const mutate y$10_@0:TFunction[1:9] = Array []
compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md
+2 -2
@@ -39,14 +39,14 @@ scope1 [6:7]:
39 function Component(
40 props,
41 ) {
42 - scope @0 [1:6] deps=[read Component$0, read props$6.p0] {
42 + scope @0 [1:6] deps=[read props$6.p0] {
43 [1] Const mutate x$7_@0:TObject[1:6] = Object { }
44 [2] Const mutate y$8_@0[1:6] = Array []
45 [3] Reassign mutate x$7_@0.y[1:6] = read y$8_@0
46 [4] Const mutate child$9_@0[1:6] = JSX <read Component$0 data={freeze y$8_@0} ></read Component$0>
47 [5] Call mutate x$7_@0.y.push(read props$6.p0)
48 }
49 - scope @1 [6:7] deps=[read Component$0, freeze x$7_@0:TObject, read child$9_@0] {
49 + scope @1 [6:7] deps=[freeze x$7_@0:TObject, read child$9_@0] {
50 [6] Const mutate $10_@1 = JSX <read Component$0 data={freeze x$7_@0:TObject} >{read child$9_@0}</read Component$0>
51 }
52 return read $10_@1
compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md
+2 -5
@@ -40,9 +40,6 @@ bb1:
40 scope0 [1:11]:
41 - dependency: read c$10
42 - dependency: read a$8
43 - - dependency: read b$9
44 - - dependency: read $13:TPrimitive
45 - - dependency: freeze y$12_@1:TFunction
43 scope1 [3:5]:
44 - dependency: read b$9
45 scope2 [6:7]:
@@ -58,7 +55,7 @@ function foo(
55 b,
56 c,
57 ) {
61 - scope @0 [1:11] deps=[read c$10, read a$8, read b$9, read $13:TPrimitive, freeze y$12_@1:TFunction] {
58 + scope @0 [1:11] deps=[read a$8, read b$9, read c$10] {
59 [1] Const mutate x$11_@0:TFunction[1:11] = Array []
60 if (read a$8) {
61 scope @1 [3:5] deps=[read b$9] {
@@ -66,7 +63,7 @@ function foo(
63 [4] Call mutate y$12_@1.push(read b$9)
64 }
65 [5] Const mutate $13:TPrimitive = "div"
69 - scope @2 [6:7] deps=[read $13:TPrimitive, freeze y$12_@1:TFunction] {
66 + scope @2 [6:7] deps=[freeze y$12_@1:TFunction] {
67 [6] Const mutate $14_@2 = JSX <read $13:TPrimitive>{freeze y$12_@1:TFunction}</read $13:TPrimitive>
68 }
69 [7] Call mutate x$11_@0.push(read $14_@2)
compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md
+2 -2
@@ -51,7 +51,7 @@ function f(
51 a,
52 b,
53 ) {
54 - scope @0 [1:8] deps=[read a$8.length, read b$9, read b$9] {
54 + scope @0 [1:8] deps=[read a$8.length, read b$9] {
55 [1] Const mutate x$10_@0:TFunction[1:8] = Array []
56 [2] Const mutate $11:TPrimitive = 1
57 [3] Const mutate $12:TPrimitive = Binary read a$8.length === read $11:TPrimitive
@@ -62,7 +62,7 @@ function f(
62 }
63 }
64 [8] Const mutate $13:TPrimitive = "div"
65 - scope @1 [9:10] deps=[read $13:TPrimitive, freeze x$10_@0:TFunction] {
65 + scope @1 [9:10] deps=[freeze x$10_@0:TFunction] {
66 [9] Const mutate $15_@1 = JSX <read $13:TPrimitive>{freeze x$10_@0:TFunction}</read $13:TPrimitive>
67 }
68 return read $15_@1
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+2 -2
@@ -63,11 +63,11 @@ function Component(
63 [5] Reassign mutate x$7_@0:TFunction[1:7] = Array []
64 }
65 }
66 - scope @1 [7:8] deps=[read Component$0, freeze x$7_@0:TFunction] {
66 + scope @1 [7:8] deps=[freeze x$7_@0:TFunction] {
67 [7] Const mutate _$12_@1 = JSX <read Component$0 x={freeze x$7_@0:TFunction} ></read Component$0>
68 }
69 [8] Call read y$8.push(read props$6.p2)
70 - scope @2 [9:10] deps=[read Component$0, read x$7_@0:TFunction, read y$8:TFunction] {
70 + scope @2 [9:10] deps=[read x$7_@0:TFunction, read y$8:TFunction] {
71 [9] Const mutate $15_@2 = JSX <read Component$0 x={read x$7_@0:TFunction} y={read y$8:TFunction} ></read Component$0>
72 }
73 return read $15_@2
compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md
+4 -4
@@ -95,18 +95,18 @@ function foo(
95 b,
96 c,
97 ) {
98 - scope @0 [1:5] deps=[read a$13, read a$13] {
98 + scope @0 [1:5] deps=[read a$13] {
99 [1] Const mutate x$16_@0:TFunction[1:5] = Array []
100 if (read a$13) {
101 [3] Call mutate x$16_@0.push(read a$13)
102 }
103 }
104 [5] Const mutate $17:TPrimitive = "div"
105 - scope @1 [6:7] deps=[read $17:TPrimitive, freeze x$16_@0:TFunction] {
105 + scope @1 [6:7] deps=[freeze x$16_@0:TFunction] {
106 [6] Const mutate y$19_@1 = JSX <read $17:TPrimitive>{freeze x$16_@0:TFunction}</read $17:TPrimitive>
107 }
108 [7] Const mutate $20:TPrimitive = 0
109 - scope @2 [8:15] deps=[read c$15, read b$14, read b$14] {
109 + scope @2 [8:15] deps=[read b$14, read c$15] {
110 [8] Let mutate x$22_@2:TFunction[8:15] = undefined
111 switch (read b$14) {
112 case read $20:TPrimitive: {
@@ -124,7 +124,7 @@ function foo(
124 [16] Const mutate $26 = "\n "
125 [17] Const mutate $27 = "\n "
126 [18] Const mutate $28 = "\n "
127 - scope @3 [19:20] deps=[read $25:TPrimitive, read $26, read y$19_@1, read $27, freeze x$22_@2:TFunction, read $28] {
127 + scope @3 [19:20] deps=[read y$19_@1] {
128 [19] Const mutate $31_@3 = JSX <read $25:TPrimitive>{read $26}{read y$19_@1}{read $27}{freeze x$22_@2:TFunction}{read $28}</read $25:TPrimitive>
129 }
130 return read $31_@3
compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md
+3 -5
@@ -32,8 +32,6 @@ bb0:
32 scope0 [1:7]:
33 - dependency: read props$6.p0
34 - dependency: read props$6.p1
35 - - dependency: read Component$0
36 - - dependency: freeze x$9_@1
35 scope2 [5:6]:
36 - dependency: read Component$0
37 - dependency: freeze x$9_@1
@@ -49,19 +47,19 @@ scope3 [7:8]:
47 function Component(
48 props,
49 ) {
52 - scope @0 [1:7] deps=[read props$6.p0, read props$6.p1, read Component$0, freeze x$9_@1] {
50 + scope @0 [1:7] deps=[read props$6.p0, read props$6.p1] {
51 [1] Const mutate x$7_@0:TFunction[1:7] = Array []
52 [2] Call mutate x$7_@0.push(read props$6.p0)
53 [3] Const mutate y$8_@0:TFunction[1:7] = read x$7_@0:TFunction
54 scope @1 [4:5] deps=[] {
55 [4] Const mutate x$9_@1 = Array []
56 }
59 - scope @2 [5:6] deps=[read Component$0, freeze x$9_@1] {
57 + scope @2 [5:6] deps=[freeze x$9_@1] {
58 [5] Const mutate _$10_@2 = JSX <read Component$0 x={freeze x$9_@1} ></read Component$0>
59 }
60 [6] Call mutate y$8_@0.push(read props$6.p1)
61 }
64 - scope @3 [7:8] deps=[read Component$0, read x$9_@1, freeze y$8_@0:TFunction] {
62 + scope @3 [7:8] deps=[read x$9_@1, freeze y$8_@0:TFunction] {
63 [7] Const mutate $11_@3 = JSX <read Component$0 x={read x$9_@1} y={freeze y$8_@0:TFunction} ></read Component$0>
64 }
65 return read $11_@3
compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md
+1 -1
@@ -95,7 +95,7 @@ function Component(
95 props,
96 ) {
97 [1] Const mutate x$7:TPrimitive = undefined
98 - scope @0 [2:18] deps=[read props$6.v2, read props$6.v1, read props$6.v0, read props$6.test, read props$6.b, read props$6.c, read props$6.cond2, read props$6.cond] {
98 + scope @0 [2:18] deps=[read props$6.cond, read props$6.test, read props$6.v0, read props$6.v1, read props$6.v2, read props$6.cond2, read props$6.b, read props$6.c] {
99 [2] Let mutate x$11_@0:TProp[2:18] = undefined
100 if (read props$6.cond) {
101 [3] Const mutate $8:TPrimitive = 2
compiler/forget/src/__tests__/fixtures/hir/simple.expect.md
+2 -2
@@ -44,14 +44,14 @@ function foo(
44 ) {
45 if (read x$8) {
46 [2] Const mutate $10:TPrimitive = false
47 - scope @0 [3:4] deps=[read foo$0:TFunction, read $10:TPrimitive, read y$9:TPrimitive] {
47 + scope @0 [3:4] deps=[read y$9:TPrimitive] {
48 [3] Const mutate $11_@0 = Call read foo$0:TFunction(read $10:TPrimitive, read y$9:TPrimitive)
49 }
50 return freeze $11_@0
51 }
52 [5] Const mutate $12:TPrimitive = 10
53 [6] Const mutate $13:TPrimitive = Binary read y$9:TPrimitive * read $12:TPrimitive
54 - scope @1 [7:8] deps=[read $13:TPrimitive] {
54 + scope @1 [7:8] deps=[] {
55 [7] Const mutate $14_@1 = Array [read $13:TPrimitive]
56 }
57 return freeze $14_@1
compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md
+1 -1
@@ -32,7 +32,7 @@ function Component(
32 ) {
33 [1] Const mutate a$6:TPrimitive = 1
34 [2] Const mutate b$7:TPrimitive = 2
35 - scope @0 [3:4] deps=[read a$6:TPrimitive, read b$7:TPrimitive] {
35 + scope @0 [3:4] deps=[] {
36 [3] Const mutate x$8_@0 = Array [read a$6:TPrimitive, read b$7:TPrimitive]
37 }
38 return freeze x$8_@0
compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md
+3 -5
@@ -62,8 +62,6 @@ bb1:
62 [10] Const mutate $19:TPrimitive = "div"
63 [11] Const mutate $20_@3 = JSX <read $19:TPrimitive a={freeze a$11_@0} b={freeze b$12_@0:TObject} ></read $19:TPrimitive>
64 [12] Return read $20_@3
65 -scope0 [1:10]:
66 - - dependency: read $14:TPrimitive
65 scope2 [7:8]:
66 - dependency: read $14:TPrimitive
67 scope3 [11:12]:
@@ -78,7 +76,7 @@ scope3 [11:12]:
76 function Component(
77 props,
78 ) {
81 - scope @0 [1:10] deps=[read $14:TPrimitive] {
79 + scope @0 [1:10] deps=[] {
80 [1] Const mutate a$11_@0[1:10] = Array []
81 [2] Const mutate b$12_@0:TObject[1:10] = Object { }
82 [3] Call mutate foo$4:TFunction(mutate a$11_@0, mutate b$12_@0:TObject)
@@ -87,14 +85,14 @@ function Component(
85 }
86 if (read $13_@1) {
87 [6] Const mutate $14:TPrimitive = "div"
90 - scope @2 [7:8] deps=[read $14:TPrimitive] {
88 + scope @2 [7:8] deps=[freeze a$11_@0] {
89 [7] Const mutate _$15_@2 = JSX <read $14:TPrimitive a={freeze a$11_@0} ></read $14:TPrimitive>
90 }
91 }
92 [9] Call mutate foo$4:TFunction(read a$11_@0, mutate b$12_@0:TObject)
93 }
94 [10] Const mutate $19:TPrimitive = "div"
97 - scope @3 [11:12] deps=[read $19:TPrimitive, freeze a$11_@0, freeze b$12_@0:TObject] {
95 + scope @3 [11:12] deps=[freeze a$11_@0, freeze b$12_@0:TObject] {
96 [11] Const mutate $20_@3 = JSX <read $19:TPrimitive a={freeze a$11_@0} b={freeze b$12_@0:TObject} ></read $19:TPrimitive>
97 }
98 return read $20_@3
compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md
+3 -5
@@ -52,8 +52,6 @@ bb0:
52 [7] Const mutate $14:TPrimitive = "div"
53 [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
54 [9] Return read $15_@2
55 -scope0 [1:7]:
56 - - dependency: read $12:TPrimitive
55 scope1 [5:6]:
56 - dependency: read $12:TPrimitive
57 scope2 [8:9]:
@@ -68,18 +66,18 @@ scope2 [8:9]:
66 function Component(
67 props,
68 ) {
71 - scope @0 [1:7] deps=[read $12:TPrimitive] {
69 + scope @0 [1:7] deps=[] {
70 [1] Const mutate a$10_@0[1:7] = Array []
71 [2] Const mutate b$11_@0:TObject[1:7] = Object { }
72 [3] Call mutate foo$4:TFunction(mutate a$10_@0, mutate b$11_@0:TObject)
73 [4] Const mutate $12:TPrimitive = "div"
76 - scope @1 [5:6] deps=[read $12:TPrimitive] {
74 + scope @1 [5:6] deps=[freeze a$10_@0] {
75 [5] Const mutate _$13_@1 = JSX <read $12:TPrimitive a={freeze a$10_@0} ></read $12:TPrimitive>
76 }
77 [6] Call mutate foo$4:TFunction(read a$10_@0, mutate b$11_@0:TObject)
78 }
79 [7] Const mutate $14:TPrimitive = "div"
82 - scope @2 [8:9] deps=[read $14:TPrimitive, read a$10_@0, freeze b$11_@0:TObject] {
80 + scope @2 [8:9] deps=[read a$10_@0, freeze b$11_@0:TObject] {
81 [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
82 }
83 return read $15_@2
compiler/forget/src/__tests__/fixtures/hir/ssa-multiple-phis.expect.md
+1 -1
@@ -87,7 +87,7 @@ function foo(
87 ) {
88 [1] Const mutate x$13:TPrimitive = 0
89 [2] Const mutate $14:TPrimitive = true
90 - scope @0 [3:20] deps=[read a$9, read b$10, read c$11, read d$12, read $14:TPrimitive] {
90 + scope @0 [3:20] deps=[read a$9, read b$10, read c$11, read d$12] {
91 [3] Let mutate x$18_@0[3:20] = undefined
92 if (read $14:TPrimitive) {
93 [4] Const mutate $15:TPrimitive = true
compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-phi.expect.md
+1 -1
@@ -49,7 +49,7 @@ function foo(
49 b,
50 c,
51 ) {
52 - scope @0 [1:8] deps=[read a$5, read c$7, read c$7, read b$6] {
52 + scope @0 [1:8] deps=[read a$5, read b$6, read c$7] {
53 [1] Const mutate x$8_@0[1:8] = read a$5
54 if (read b$6) {
55 if (read c$7) {
compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-reassignment.expect.md
+1 -1
@@ -53,7 +53,7 @@ function foo(
53 d,
54 e,
55 ) {
56 - scope @0 [1:8] deps=[read b$8, read d$10, read c$9, read a$7] {
56 + scope @0 [1:8] deps=[read a$7, read b$8, read c$9, read d$10] {
57 [1] Let mutate x$12_@0:TPrimitive[1:8] = null
58 if (read a$7) {
59 [3] Reassign mutate x$12_@0:TPrimitive[1:8] = read b$8
compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md
+1 -1
@@ -60,7 +60,7 @@ function foo(
60 [8] Reassign mutate y$7_@0:TPrimitive[1:10] = 3
61 }
62 }
63 - scope @2 [10:11] deps=[read x$6_@0:TPrimitive, read y$7_@0:TPrimitive] {
63 + scope @2 [10:11] deps=[] {
64 [10] Const mutate t$14_@2:TObject = Object { x: read x$6_@0:TPrimitive, y: read y$7_@0:TPrimitive }
65 }
66 return freeze t$14_@2:TObject
compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md
+1 -1
@@ -32,7 +32,7 @@ function Component(
32 ) {
33 [1] Const mutate a$6:TPrimitive = 1
34 [2] Const mutate b$7:TPrimitive = 2
35 - scope @0 [3:4] deps=[read a$6:TPrimitive, read b$7:TPrimitive] {
35 + scope @0 [3:4] deps=[] {
36 [3] Const mutate x$8_@0:TObject = Object { a: read a$6:TPrimitive, b: read b$7:TPrimitive }
37 }
38 return freeze x$8_@0:TObject
compiler/forget/src/__tests__/fixtures/hir/ssa-sibling-phis.expect.md
+2 -2
@@ -91,7 +91,7 @@ function foo(
91 [2] Const mutate $14:TPrimitive = true
92 if (read $14:TPrimitive) {
93 [4] Const mutate $15:TPrimitive = true
94 - scope @0 [5:10] deps=[read a$9, read b$10, read $15:TPrimitive] {
94 + scope @0 [5:10] deps=[read a$9, read b$10] {
95 [5] Let mutate x$16_@0[5:10] = undefined
96 if (read $15:TPrimitive) {
97 [6] Reassign mutate x$16_@0[5:10] = read a$9
@@ -102,7 +102,7 @@ function foo(
102 [10] read x$16_@0
103 } else {
104 [12] Const mutate $19:TPrimitive = true
105 - scope @1 [13:18] deps=[read c$11, read d$12, read $19:TPrimitive] {
105 + scope @1 [13:18] deps=[read c$11, read d$12] {
106 [13] Let mutate x$20_@1[13:18] = undefined
107 if (read $19:TPrimitive) {
108 [14] Reassign mutate x$20_@1[13:18] = read c$11
compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md
+1 -1
@@ -49,7 +49,7 @@ function foo(
49 [1] Const mutate y$5:TPrimitive = 2
50 [2] Const mutate $6:TPrimitive = 1
51 [3] Const mutate $7:TPrimitive = Binary read y$5:TPrimitive > read $6:TPrimitive
52 - scope @0 [4:9] deps=[read $7:TPrimitive] {
52 + scope @0 [4:9] deps=[] {
53 [4] Let mutate y$8_@0:TPrimitive[4:9] = undefined
54 if (read $7:TPrimitive) {
55 [5] Reassign mutate y$8_@0:TPrimitive[4:9] = 1
compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md
+1 -1
@@ -75,7 +75,7 @@ function foo(
75 [3] Const mutate $12:TPrimitive = Binary read x$10:TPrimitive === read $11:TPrimitive
76 [4] Const mutate $13:TPrimitive = 1
77 [5] Const mutate $14:TPrimitive = Binary read x$10:TPrimitive === read $13:TPrimitive
78 - scope @0 [6:16] deps=[read x$10:TPrimitive, read x$10:TPrimitive, read x$10:TPrimitive, read x$10:TPrimitive] {
78 + scope @0 [6:16] deps=[] {
79 [6] Let mutate x$16_@0:TPrimitive[6:16] = undefined
80 switch (read x$10:TPrimitive) {
81 case read $14:TPrimitive: {
compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md
+3 -3
@@ -73,7 +73,7 @@ scope3 [14:15]:
73 function Component(
74 props,
75 ) {
76 - scope @1 [1:12] deps=[] {
76 + scope @1 [1:12] deps=[read props$9.p0, read props$9.p2] {
77 [1] Const mutate x$10_@1:TFunction[1:12] = Array []
78 [2] Let mutate y$11_@1:TPrimitive[1:12] = undefined
79 [3] Const mutate $12:TPrimitive = false
@@ -96,11 +96,11 @@ function Component(
96 }
97 }
98 }
99 - scope @2 [12:13] deps=[read Component$0, freeze x$10_@1:TFunction] {
99 + scope @2 [12:13] deps=[freeze x$10_@1:TFunction] {
100 [12] Const mutate child$19_@2 = JSX <read Component$0 data={freeze x$10_@1:TFunction} ></read Component$0>
101 }
102 [13] Call read y$11_@1.push(read props$9.p4)
103 - scope @3 [14:15] deps=[read Component$0, freeze y$11_@1:TPrimitive, read child$19_@2] {
103 + scope @3 [14:15] deps=[read child$19_@2] {
104 [14] Const mutate $22_@3 = JSX <read Component$0 data={freeze y$11_@1:TPrimitive} >{read child$19_@2}</read Component$0>
105 }
106 return read $22_@3
compiler/forget/src/__tests__/fixtures/hir/switch.expect.md
+3 -4
@@ -2,7 +2,6 @@
2 ## Input
3
4 ```javascript
5 -// @Out DefUseGraph
5 function Component(props) {
6 let x = [];
7 let y;
@@ -68,7 +67,7 @@ scope4 [14:15]:
67 function Component(
68 props,
69 ) {
71 - scope @1 [1:12] deps=[] {
70 + scope @1 [1:12] deps=[read props$8.p0, read props$8.p2, read props$8.p3] {
71 [1] Const mutate x$9_@1:TFunction[1:12] = Array []
72 [2] Let mutate y$10_@1:TPrimitive[1:12] = undefined
73 [3] Const mutate $11:TPrimitive = false
@@ -86,11 +85,11 @@ function Component(
85 }
86 }
87 }
89 - scope @3 [12:13] deps=[read Component$0, freeze x$9_@1:TFunction] {
88 + scope @3 [12:13] deps=[freeze x$9_@1:TFunction] {
89 [12] Const mutate child$19_@3 = JSX <read Component$0 data={freeze x$9_@1:TFunction} ></read Component$0>
90 }
91 [13] Call read y$10_@1.push(read props$8.p4)
93 - scope @4 [14:15] deps=[read Component$0, read y$10_@1:TPrimitive, read child$19_@3] {
92 + scope @4 [14:15] deps=[read child$19_@3] {
93 [14] Const mutate $23_@4 = JSX <read Component$0 data={read y$10_@1:TPrimitive} >{read child$19_@3}</read Component$0>
94 }
95 return read $23_@4
compiler/forget/src/__tests__/fixtures/hir/switch.js
-1
@@ -1,4 +1,3 @@
1 -// @Out DefUseGraph
1 function Component(props) {
2 let x = [];
3 let y;
compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md
+1 -1
@@ -27,7 +27,7 @@ scope0 [2:3]:
27 function component(
28 ) {
29 [1] Const mutate $4:TPrimitive = 1
30 - scope @0 [2:3] deps=[read $4:TPrimitive] {
30 + scope @0 [2:3] deps=[] {
31 [2] Const mutate x$5_@0:TObject = Object { t: read $4:TPrimitive }
32 }
33 [3] Const mutate p$6:TPrimitive = read x$5_@0.t