@samitouri / QOS-React-2 / commits / 575db2b4ea

[wip] Codegen with memoization applied

Updates the ReactiveFunction-based codegen from the previous PR to emit memoization code for each scope. This is currently naive and has some bugs, but it gets the idea across. The core logic is straightforward at this point, all the hard work is in earlier passes: * Compute one change variable per scope dependency, eg `const c_0 = $[0] === maxItems` * Generate one `let` binding for each scope output * Generate an if block where the test is if any of the change variables are true (`||` them together) * Generate the consequent block with the original code block, plus statements to save dependencies and outputs to their cache slots * Generate the alternate block to populate the scope outputs from their cached values ## Todos A few things don't quite work yet: * Codegen is designed to avoid emitting variables for temporary values, but that's causing a few values to sort of disappear n the examples, or get emitted twice. There are a variety of ways to achieve this but we'll need to ensure that this category of values gets assigned to a variable and then reference the variable. This is more involved. * Scopes can end up with zero dependencies, in which case we should check that the first output cache is initialized. This one is more straightforward. * If there are early returns, we don't record that they occurred and replay them in the `else` branch for each scope. We know the algorithm though so i'm okay delaying that for now.

Joe Savona committed Dec 14, 2022 at 16:12 UTC 575db2b4ea7213badc3a0be2b58330a0918091cc
86 files changed +2455 -655
compiler/forget/src/HIR/CodegenReactiveFunction.ts
+132 -6
@@ -18,7 +18,9 @@ import {
18 Temporaries,
19 } from "./Codegen";
20 import {
21 + Identifier,
22 Instruction,
23 + InstructionKind,
24 ReactiveBasicBlock,
25 ReactiveFunction,
26 ReactiveScope,
@@ -38,6 +40,22 @@ export function codegenReactiveFunction(fn: ReactiveFunction): t.Function {
40 statements.pop();
41 }
42 }
43 + if (cx.nextCacheIndex !== 0) {
44 + statements.unshift(
45 + t.variableDeclaration("const", [
46 + t.variableDeclarator(
47 + t.identifier("$"),
48 + t.callExpression(
49 + t.memberExpression(
50 + t.identifier("React"),
51 + t.identifier("useMemoCache")
52 + ),
53 + []
54 + )
55 + ),
56 + ])
57 + );
58 + }
59 return createFunctionDeclaration(
60 fn.loc,
61 fn.id !== null ? convertIdentifier(fn.id) : null,
@@ -49,7 +67,21 @@ export function codegenReactiveFunction(fn: ReactiveFunction): t.Function {
67 }
68
69 class Context {
70 + #nextCacheIndex: number = 0;
71 + #identifiers: Set<Identifier> = new Set();
72 temp: Temporaries = new Map();
73 +
74 + get nextCacheIndex(): number {
75 + return this.#nextCacheIndex++;
76 + }
77 +
78 + declare(identifier: Identifier): void {
79 + this.#identifiers.add(identifier);
80 + }
81 +
82 + declared(identifier: Identifier): boolean {
83 + return this.#identifiers.has(identifier);
84 + }
85 }
86
87 function codegenBlock(
@@ -61,7 +93,7 @@ function codegenBlock(
93 switch (item.kind) {
94 case "instruction": {
95 const statement = codegenInstructionNullable(
64 - cx.temp,
96 + cx,
97 item.instruction,
98 codegenInstructionValue(cx.temp, item.instruction.value)
99 );
@@ -102,9 +134,84 @@ function codegenReactiveScope(
134 scope: ReactiveScope,
135 block: ReactiveBasicBlock
136 ): void {
105 - // TODO @josephsavona: Emit memoized blocks!
106 - const body = codegenBlock(cx, block).body;
107 - statements.push(...body);
137 + const cacheStoreStatements: Array<t.Statement> = [];
138 + const cacheLoadStatements: Array<t.Statement> = [];
139 + const changeIdentifiers: Array<t.Identifier> = [];
140 + for (const dep of scope.dependencies) {
141 + const index = cx.nextCacheIndex;
142 + const changeIdentifier = t.identifier(`c_${index}`);
143 + const depValue = codegenPlace(cx.temp, dep);
144 +
145 + changeIdentifiers.push(changeIdentifier);
146 + statements.push(
147 + t.variableDeclaration("const", [
148 + t.variableDeclarator(
149 + changeIdentifier,
150 + t.binaryExpression(
151 + "!==",
152 + t.memberExpression(
153 + t.identifier("$"),
154 + t.numericLiteral(index),
155 + true
156 + ),
157 + depValue
158 + )
159 + ),
160 + ])
161 + );
162 + cacheStoreStatements.push(
163 + t.expressionStatement(
164 + t.assignmentExpression(
165 + "=",
166 + t.memberExpression(t.identifier("$"), t.numericLiteral(index), true),
167 + depValue
168 + )
169 + )
170 + );
171 + }
172 + for (const output of scope.outputs) {
173 + const index = cx.nextCacheIndex;
174 +
175 + // TODO @josephsavona: ensure change and temp variables have non-conflicting names
176 + output.name ??= `t${index}`;
177 +
178 + const name = convertIdentifier(output);
179 + cx.declare(output);
180 + statements.push(t.variableDeclaration("let", [t.variableDeclarator(name)]));
181 + cacheStoreStatements.push(
182 + t.expressionStatement(
183 + t.assignmentExpression(
184 + "=",
185 + t.memberExpression(t.identifier("$"), t.numericLiteral(index), true),
186 + name
187 + )
188 + )
189 + );
190 + cacheLoadStatements.push(
191 + t.expressionStatement(
192 + t.assignmentExpression(
193 + "=",
194 + name,
195 + t.memberExpression(t.identifier("$"), t.numericLiteral(index), true)
196 + )
197 + )
198 + );
199 + }
200 + const testCondition =
201 + (changeIdentifiers as Array<t.Expression>).reduce(
202 + (acc: t.Expression | null, ident: t.Expression) => {
203 + if (acc == null) {
204 + return ident;
205 + }
206 + return t.logicalExpression("||", acc, ident);
207 + },
208 + null as t.Expression | null
209 + ) ?? t.booleanLiteral(true); // TODO @josephsavona handle case of empty dependencies
210 +
211 + const computationBlock = codegenBlock(cx, block);
212 + computationBlock.body.push(...cacheStoreStatements);
213 + const memoBlock = t.blockStatement(cacheLoadStatements);
214 + statements.push(t.ifStatement(testCondition, computationBlock, memoBlock));
215 }
216
217 function codegenTerminal(cx: Context, terminal: ReactiveTerminal): t.Statement {
@@ -173,11 +280,30 @@ function codegenTerminal(cx: Context, terminal: ReactiveTerminal): t.Statement {
280 }
281
282 export function codegenInstructionNullable(
176 - temp: Temporaries,
283 + cx: Context,
284 instr: Instruction,
285 value: t.Expression
286 ): t.Statement | null {
180 - const statement = codegenInstruction(temp, instr, value);
287 + let statement;
288 + if (
289 + instr.lvalue !== null &&
290 + instr.lvalue.place.memberPath === null &&
291 + cx.declared(instr.lvalue.place.identifier)
292 + ) {
293 + statement = codegenInstruction(
294 + cx.temp,
295 + {
296 + ...instr,
297 + lvalue: {
298 + ...instr.lvalue,
299 + kind: InstructionKind.Reassign,
300 + },
301 + },
302 + value
303 + );
304 + } else {
305 + statement = codegenInstruction(cx.temp, instr, value);
306 + }
307 if (statement.type === "EmptyStatement") {
308 return null;
309 }
compiler/forget/src/__tests__/fixtures/hir/_bug_conditional-break-labeled.expect.md
+20 -7
@@ -60,14 +60,27 @@ function Component(
60
61 ```javascript
62 function Component$0(props$3) {
63 - const a$4 = [];
64 - a$4.push(props$3.a);
65 - bb2: if (props$3.b) {
66 - a$4.push(props$3.d);
67 - return a$4;
68 - }
63 + const $ = React.useMemoCache();
64 + const c_0 = $[0] !== props$3.a;
65 + const c_1 = $[1] !== props$3.b;
66 + const c_2 = $[2] !== props$3.d;
67 + const c_3 = $[3] !== props$3.c;
68 + if (c_0 || c_1 || c_2 || c_3) {
69 + const a$4 = [];
70 + a$4.push(props$3.a);
71 +
72 + bb2: if (props$3.b) {
73 + a$4.push(props$3.d);
74 + return a$4;
75 + }
76
70 - a$4.push(props$3.c);
77 + a$4.push(props$3.c);
78 + $[0] = props$3.a;
79 + $[1] = props$3.b;
80 + $[2] = props$3.d;
81 + $[3] = props$3.c;
82 + } else {
83 + }
84 }
85
86 ```
compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path-mutate.expect.md
+9 -6
@@ -48,12 +48,15 @@ function component(
48
49 ```javascript
50 function component$0() {
51 - const z$5 = [];
52 - const y$6 = {};
53 - y$6.z = z$5;
54 - const x$7 = {};
55 - x$7.y = y$6;
56 - mutate$4(x$7.y.z);
51 + if (true) {
52 + const z$5 = [];
53 + const y$6 = {};
54 + y$6.z = z$5;
55 + const x$7 = {};
56 + x$7.y = y$6;
57 + mutate$4(x$7.y.z);
58 + } else {
59 + }
60 }
61
62 ```
compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md
+33 -5
@@ -50,11 +50,39 @@ function component(
50
51 ```javascript
52 function component$0() {
53 - const z$4 = [];
54 - const y$5 = {};
55 - y$5.z = z$4;
56 - const x$6 = {};
57 - x$6.y = y$5;
53 + const $ = React.useMemoCache();
54 + let z$4;
55 + if (true) {
56 + z$4 = [];
57 + $[0] = z$4;
58 + } else {
59 + z$4 = $[0];
60 + }
61 +
62 + const c_1 = $[1] !== z$4;
63 + let y$5;
64 +
65 + if (c_1) {
66 + y$5 = {};
67 + y$5.z = z$4;
68 + $[1] = z$4;
69 + $[2] = y$5;
70 + } else {
71 + y$5 = $[2];
72 + }
73 +
74 + const c_3 = $[3] !== y$5;
75 + let x$6;
76 +
77 + if (c_3) {
78 + x$6 = {};
79 + x$6.y = y$5;
80 + $[3] = y$5;
81 + $[4] = x$6;
82 + } else {
83 + x$6 = $[4];
84 + }
85 +
86 return x$6;
87 }
88
compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md
+26 -9
@@ -82,15 +82,32 @@ function foo(
82
83 ```javascript
84 function foo$0(cond$7) {
85 - let a$8 = {};
86 - let b$9 = {};
87 - let c$10 = {};
88 - bb2: while (cond$7) {
89 - const z$13 = a$8;
90 - a$8 = b$9;
91 - b$9 = c$10;
92 - c$10 = z$13;
93 - mutate$6(a$8, b$9);
85 + const $ = React.useMemoCache();
86 + const c_0 = $[0] !== cond$7;
87 + let a$8;
88 + let b$9;
89 + let c$10;
90 + if (c_0) {
91 + a$8 = {};
92 + b$9 = {};
93 + c$10 = {};
94 +
95 + bb2: while (cond$7) {
96 + const z$13 = a$8;
97 + a$8 = b$9;
98 + b$9 = c$10;
99 + c$10 = z$13;
100 + mutate$6(a$8, b$9);
101 + }
102 +
103 + $[0] = cond$7;
104 + $[1] = a$8;
105 + $[2] = b$9;
106 + $[3] = c$10;
107 + } else {
108 + a$8 = $[1];
109 + b$9 = $[2];
110 + c$10 = $[3];
111 }
112
113 a$8;
compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md
+5 -2
@@ -90,8 +90,11 @@ function g(
90
91 ```javascript
92 function g$0(a$4) {
93 - a$4.c.b = a$4.b.c + 1;
94 - a$4.c.b = a$4.b.c * 2;
93 + if (true) {
94 + a$4.c.b = a$4.b.c + 1;
95 + a$4.c.b = a$4.b.c * 2;
96 + } else {
97 + }
98 }
99
100 ```
compiler/forget/src/__tests__/fixtures/hir/call.expect.md
+39 -8
@@ -49,8 +49,8 @@ bb0:
49 [5] Const mutate _$13_@1 = JSX <read $12:TPrimitive a={freeze a$10_@0:TObject} ></read $12:TPrimitive>
50 [6] Call mutate foo$4:TFunction(mutate b$11_@0:TObject)
51 [7] Const mutate $14:TPrimitive = "div"
52 - [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0:TObject} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
53 - [9] Return read $15_@2
52 + [8] Const mutate t5$15_@2 = JSX <read $14:TPrimitive a={read a$10_@0:TObject} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
53 + [9] Return read t5$15_@2
54 ```
55
56 ## Reactive Scopes
@@ -82,13 +82,44 @@ function Component(
82
83 ```javascript
84 function Component$0(props$9) {
85 - const a$10 = [];
86 - const b$11 = {};
87 - foo$4(a$10, b$11);
88 - const _$13 = <div a={a$10}></div>;
85 + const $ = React.useMemoCache();
86 + let a$10;
87 + let b$11;
88 + if (true) {
89 + a$10 = [];
90 + b$11 = {};
91 + foo$4(a$10, b$11);
92 + const c_2 = $[2] !== a$10;
93 +
94 + if (c_2) {
95 + const _$13 = <div a={a$10}></div>;
96 +
97 + $[2] = a$10;
98 + } else {
99 + }
100 +
101 + foo$4(b$11);
102 + $[0] = a$10;
103 + $[1] = b$11;
104 + } else {
105 + a$10 = $[0];
106 + b$11 = $[1];
107 + }
108 +
109 + const c_3 = $[3] !== a$10;
110 + const c_4 = $[4] !== b$11;
111 + let t5$15;
112 +
113 + if (c_3 || c_4) {
114 + t5$15 = <div a={a$10} b={b$11}></div>;
115 + $[3] = a$10;
116 + $[4] = b$11;
117 + $[5] = t5$15;
118 + } else {
119 + t5$15 = $[5];
120 + }
121
90 - foo$4(b$11);
91 - return <div a={a$10} b={b$11}></div>;
122 + return t5$15;
123 }
124
125 ```
compiler/forget/src/__tests__/fixtures/hir/component.expect.md
+68 -23
@@ -95,11 +95,11 @@ bb2:
95 [35] Const mutate $68 = "\n "
96 [36] Const mutate $69:TPrimitive = "h1"
97 [37] Const mutate $70 = " Items"
98 - [38] Const mutate $71_@4 = JSX <read $69:TPrimitive>{freeze count$66:TProp}{read $70}</read $69:TPrimitive>
98 + [38] Const mutate t6$71_@4 = JSX <read $69:TPrimitive>{freeze count$66:TProp}{read $70}</read $69:TPrimitive>
99 [39] Const mutate $72 = "\n "
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
101 + [41] Const mutate t9$74_@5 = JSX <read $67:TPrimitive>{read $68}{read t6$71_@4}{read $72}{freeze renderedItems$32_@0:TFunction}{read $73}</read $67:TPrimitive>
102 + [42] Return read t9$74_@5
103 ```
104
105 ## Reactive Scopes
@@ -171,37 +171,82 @@ function Component(
171
172 ```javascript
173 function Component$0(props$29) {
174 + const $ = React.useMemoCache();
175 const items$30 = props$29.items;
176 const maxItems$31 = props$29.maxItems;
176 - const renderedItems$32 = [];
177 - const seen$33 = new Set$6();
178 - const max$35 = Math$8.max(0, maxItems$31);
179 - bb2: for (let i$36 = 0; i$36 < items$30.length; i$36 = i$36 + 1, i$36) {
180 - const item$40 = items$30.at(i$36);
181 -
182 - bb9: if (item$40 == null) {
177 + const c_0 = $[0] !== maxItems$31;
178 + const c_1 = $[1] !== items$30.length;
179 + const c_2 = $[2] !== items$30;
180 + let renderedItems$32;
181 + if (c_0 || c_1 || c_2) {
182 + renderedItems$32 = [];
183 + const seen$33 = new Set$6();
184 + const c_4 = $[4] !== maxItems$31;
185 +
186 + if (c_4) {
187 + const max$35 = Math$8.max(0, maxItems$31);
188 + $[4] = maxItems$31;
189 } else {
190 }
191
186 - bb6: if (seen$33.has(item$40)) {
187 - continue;
188 - }
192 + bb2: for (let i$36 = 0; i$36 < items$30.length; i$36 = i$36 + 1, i$36) {
193 + const item$40 = items$30.at(i$36);
194 +
195 + bb9: if (item$40 == null) {
196 + } else {
197 + }
198
190 - seen$33.add(item$40);
191 - renderedItems$32.push(<div>{item$40}</div>);
199 + bb6: if (seen$33.has(item$40)) {
200 + continue;
201 + }
202
193 - bb12: if (renderedItems$32.length >= max$35) {
194 - break;
203 + seen$33.add(item$40);
204 + renderedItems$32.push(<div>{item$40}</div>);
205 +
206 + bb12: if (renderedItems$32.length >= max$35) {
207 + break;
208 + }
209 }
210 +
211 + $[0] = maxItems$31;
212 + $[1] = items$30.length;
213 + $[2] = items$30;
214 + $[3] = renderedItems$32;
215 + } else {
216 + renderedItems$32 = $[3];
217 }
218
219 const count$66 = renderedItems$32.length;
199 - return (
200 - <div>
201 - {<h1>{count$66} Items</h1>}
202 - {renderedItems$32}
203 - </div>
204 - );
220 + const c_5 = $[5] !== count$66;
221 + let t6$71;
222 +
223 + if (c_5) {
224 + t6$71 = <h1>{count$66} Items</h1>;
225 + $[5] = count$66;
226 + $[6] = t6$71;
227 + } else {
228 + t6$71 = $[6];
229 + }
230 +
231 + const c_7 = $[7] !== t6$71;
232 + const c_8 = $[8] !== renderedItems$32;
233 + let t9$74;
234 +
235 + if (c_7 || c_8) {
236 + t9$74 = (
237 + <div>
238 + {t6$71}
239 + {renderedItems$32}
240 + </div>
241 + );
242 + $[7] = t6$71;
243 + $[8] = renderedItems$32;
244 + $[9] = t9$74;
245 + } else {
246 + t9$74 = $[9];
247 + }
248 +
249 + return t9$74;
250 }
251
252 ```
compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md
+108 -29
@@ -115,13 +115,28 @@ function Component(
115
116 ```javascript
117 function Component$0(props$4) {
118 - const a_DEBUG$5 = [];
119 - a_DEBUG$5.push(props$4.a);
120 - bb1: if (props$4.b) {
121 - return null;
118 + const $ = React.useMemoCache();
119 + const c_0 = $[0] !== props$4.a;
120 + const c_1 = $[1] !== props$4.b;
121 + const c_2 = $[2] !== props$4.d;
122 + let a_DEBUG$5;
123 + if (c_0 || c_1 || c_2) {
124 + a_DEBUG$5 = [];
125 + a_DEBUG$5.push(props$4.a);
126 +
127 + bb1: if (props$4.b) {
128 + return null;
129 + }
130 +
131 + a_DEBUG$5.push(props$4.d);
132 + $[0] = props$4.a;
133 + $[1] = props$4.b;
134 + $[2] = props$4.d;
135 + $[3] = a_DEBUG$5;
136 + } else {
137 + a_DEBUG$5 = $[3];
138 }
139
124 - a_DEBUG$5.push(props$4.d);
140 return a_DEBUG$5;
141 }
142
@@ -166,13 +181,30 @@ function Component(
181
182 ```javascript
183 function Component$0(props$3) {
169 - const a$4 = [];
170 - a$4.push(props$3.a);
171 - bb1: if (props$3.b) {
172 - a$4.push(props$3.c);
184 + const $ = React.useMemoCache();
185 + const c_0 = $[0] !== props$3.a;
186 + const c_1 = $[1] !== props$3.b;
187 + const c_2 = $[2] !== props$3.c;
188 + const c_3 = $[3] !== props$3.d;
189 + let a$4;
190 + if (c_0 || c_1 || c_2 || c_3) {
191 + a$4 = [];
192 + a$4.push(props$3.a);
193 +
194 + bb1: if (props$3.b) {
195 + a$4.push(props$3.c);
196 + }
197 +
198 + a$4.push(props$3.d);
199 + $[0] = props$3.a;
200 + $[1] = props$3.b;
201 + $[2] = props$3.c;
202 + $[3] = props$3.d;
203 + $[4] = a$4;
204 + } else {
205 + a$4 = $[4];
206 }
207
175 - a$4.push(props$3.d);
208 return a$4;
209 }
210
@@ -220,14 +252,31 @@ function Component(
252
253 ```javascript
254 function Component$0(props$4) {
223 - const a$5 = [];
224 - a$5.push(props$4.a);
225 - bb1: if (props$4.b) {
226 - a$5.push(props$4.c);
227 - return null;
255 + const $ = React.useMemoCache();
256 + const c_0 = $[0] !== props$4.a;
257 + const c_1 = $[1] !== props$4.b;
258 + const c_2 = $[2] !== props$4.c;
259 + const c_3 = $[3] !== props$4.d;
260 + let a$5;
261 + if (c_0 || c_1 || c_2 || c_3) {
262 + a$5 = [];
263 + a$5.push(props$4.a);
264 +
265 + bb1: if (props$4.b) {
266 + a$5.push(props$4.c);
267 + return null;
268 + }
269 +
270 + a$5.push(props$4.d);
271 + $[0] = props$4.a;
272 + $[1] = props$4.b;
273 + $[2] = props$4.c;
274 + $[3] = props$4.d;
275 + $[4] = a$5;
276 + } else {
277 + a$5 = $[4];
278 }
279
230 - a$5.push(props$4.d);
280 return a$5;
281 }
282
@@ -273,14 +322,31 @@ function Component(
322
323 ```javascript
324 function Component$0(props$3) {
276 - const a$4 = [];
277 - a$4.push(props$3.a);
278 - bb1: if (props$3.b) {
279 - a$4.push(props$3.c);
280 - return a$4;
325 + const $ = React.useMemoCache();
326 + const c_0 = $[0] !== props$3.a;
327 + const c_1 = $[1] !== props$3.b;
328 + const c_2 = $[2] !== props$3.c;
329 + const c_3 = $[3] !== props$3.d;
330 + let a$4;
331 + if (c_0 || c_1 || c_2 || c_3) {
332 + a$4 = [];
333 + a$4.push(props$3.a);
334 +
335 + bb1: if (props$3.b) {
336 + a$4.push(props$3.c);
337 + return a$4;
338 + }
339 +
340 + a$4.push(props$3.d);
341 + $[0] = props$3.a;
342 + $[1] = props$3.b;
343 + $[2] = props$3.c;
344 + $[3] = props$3.d;
345 + $[4] = a$4;
346 + } else {
347 + a$4 = $[4];
348 }
349
283 - a$4.push(props$3.d);
350 return a$4;
351 }
352
@@ -325,14 +391,27 @@ function Component(
391
392 ```javascript
393 function Component$0(props$3) {
328 - const a$4 = [];
329 - a$4.push(props$3.a);
330 - bb2: if (props$3.b) {
331 - a$4.push(props$3.d);
332 - return a$4;
333 - }
394 + const $ = React.useMemoCache();
395 + const c_0 = $[0] !== props$3.a;
396 + const c_1 = $[1] !== props$3.b;
397 + const c_2 = $[2] !== props$3.d;
398 + const c_3 = $[3] !== props$3.c;
399 + if (c_0 || c_1 || c_2 || c_3) {
400 + const a$4 = [];
401 + a$4.push(props$3.a);
402 +
403 + bb2: if (props$3.b) {
404 + a$4.push(props$3.d);
405 + return a$4;
406 + }
407
335 - a$4.push(props$3.c);
408 + a$4.push(props$3.c);
409 + $[0] = props$3.a;
410 + $[1] = props$3.b;
411 + $[2] = props$3.d;
412 + $[3] = props$3.c;
413 + } else {
414 + }
415 }
416
417 ```
compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md
+74 -18
@@ -51,8 +51,8 @@ bb4:
51 [8] Goto bb3
52 bb3:
53 predecessor blocks: bb4 bb1
54 - [9] Const mutate $16_@2 = JSX <read Foo$4 a={freeze a$7_@0:TFunction} b={freeze b$8_@0:TFunction} ></read Foo$4>
55 - [10] Return read $16_@2
54 + [9] Const mutate t6$16_@2 = JSX <read Foo$4 a={freeze a$7_@0:TFunction} b={freeze b$8_@0:TFunction} ></read Foo$4>
55 + [10] Return read t6$16_@2
56 ```
57
58 ## Reactive Scopes
@@ -83,17 +83,45 @@ function Component(
83
84 ```javascript
85 function Component$0(props$6) {
86 - const a$7 = [];
87 - const b$8 = [];
88 - bb1: if (b$8) {
89 - a$7.push(props$6.p0);
86 + const $ = React.useMemoCache();
87 + const c_0 = $[0] !== props$6.p0;
88 + const c_1 = $[1] !== props$6.p1;
89 + const c_2 = $[2] !== props$6.p2;
90 + let a$7;
91 + if (c_0 || c_1 || c_2) {
92 + a$7 = [];
93 + const b$8 = [];
94 +
95 + bb1: if (b$8) {
96 + a$7.push(props$6.p0);
97 + }
98 +
99 + bb3: if (props$6.p1) {
100 + b$8.push(props$6.p2);
101 + }
102 +
103 + $[0] = props$6.p0;
104 + $[1] = props$6.p1;
105 + $[2] = props$6.p2;
106 + $[3] = a$7;
107 + } else {
108 + a$7 = $[3];
109 }
110
92 - bb3: if (props$6.p1) {
93 - b$8.push(props$6.p2);
111 + const c_4 = $[4] !== a$7;
112 + const c_5 = $[5] !== b$8;
113 + let t6$16;
114 +
115 + if (c_4 || c_5) {
116 + t6$16 = <Foo$4 a={a$7} b={b$8}></Foo$4>;
117 + $[4] = a$7;
118 + $[5] = b$8;
119 + $[6] = t6$16;
120 + } else {
121 + t6$16 = $[6];
122 }
123
96 - return <Foo$4 a={a$7} b={b$8}></Foo$4>;
124 + return t6$16;
125 }
126
127 ```
@@ -118,8 +146,8 @@ bb4:
146 [9] Goto bb3
147 bb3:
148 predecessor blocks: bb4 bb1
121 - [10] Const mutate $19_@2 = JSX <read Foo$6 a={freeze a$9_@0:TFunction} b={freeze b$10_@0:TFunction} ></read Foo$6>
122 - [11] Return read $19_@2
149 + [10] Const mutate t6$19_@2 = JSX <read Foo$6 a={freeze a$9_@0:TFunction} b={freeze b$10_@0:TFunction} ></read Foo$6>
150 + [11] Return read t6$19_@2
151 ```
152
153 ## Reactive Scopes
@@ -151,17 +179,45 @@ function Component(
179
180 ```javascript
181 function Component$0(props$8) {
154 - const a$9 = [];
155 - const b$10 = [];
156 - bb1: if (mayMutate$4(b$10)) {
157 - a$9.push(props$8.p0);
182 + const $ = React.useMemoCache();
183 + const c_0 = $[0] !== props$8.p0;
184 + const c_1 = $[1] !== props$8.p1;
185 + const c_2 = $[2] !== props$8.p2;
186 + let a$9;
187 + if (c_0 || c_1 || c_2) {
188 + a$9 = [];
189 + const b$10 = [];
190 +
191 + bb1: if (mayMutate$4(b$10)) {
192 + a$9.push(props$8.p0);
193 + }
194 +
195 + bb3: if (props$8.p1) {
196 + b$10.push(props$8.p2);
197 + }
198 +
199 + $[0] = props$8.p0;
200 + $[1] = props$8.p1;
201 + $[2] = props$8.p2;
202 + $[3] = a$9;
203 + } else {
204 + a$9 = $[3];
205 }
206
160 - bb3: if (props$8.p1) {
161 - b$10.push(props$8.p2);
207 + const c_4 = $[4] !== a$9;
208 + const c_5 = $[5] !== b$10;
209 + let t6$19;
210 +
211 + if (c_4 || c_5) {
212 + t6$19 = <Foo$6 a={a$9} b={b$10}></Foo$6>;
213 + $[4] = a$9;
214 + $[5] = b$10;
215 + $[6] = t6$19;
216 + } else {
217 + t6$19 = $[6];
218 }
219
164 - return <Foo$6 a={a$9} b={b$10}></Foo$6>;
220 + return t6$19;
221 }
222
223 ```
compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md
+39 -8
@@ -49,8 +49,8 @@ bb0:
49 [5] Const mutate _$13_@1 = JSX <read $12:TPrimitive a={freeze a$10_@0} ></read $12:TPrimitive>
50 [6] New mutate Foo$4(mutate b$11_@0:TObject)
51 [7] Const mutate $14:TPrimitive = "div"
52 - [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
53 - [9] Return read $15_@2
52 + [8] Const mutate t5$15_@2 = JSX <read $14:TPrimitive a={read a$10_@0} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
53 + [9] Return read t5$15_@2
54 ```
55
56 ## Reactive Scopes
@@ -82,13 +82,44 @@ function Component(
82
83 ```javascript
84 function Component$0(props$9) {
85 - const a$10 = [];
86 - const b$11 = {};
87 - new Foo$4(a$10, b$11);
88 - const _$13 = <div a={a$10}></div>;
85 + const $ = React.useMemoCache();
86 + let a$10;
87 + let b$11;
88 + if (true) {
89 + a$10 = [];
90 + b$11 = {};
91 + new Foo$4(a$10, b$11);
92 + const c_2 = $[2] !== a$10;
93 +
94 + if (c_2) {
95 + const _$13 = <div a={a$10}></div>;
96 +
97 + $[2] = a$10;
98 + } else {
99 + }
100 +
101 + new Foo$4(b$11);
102 + $[0] = a$10;
103 + $[1] = b$11;
104 + } else {
105 + a$10 = $[0];
106 + b$11 = $[1];
107 + }
108 +
109 + const c_3 = $[3] !== a$10;
110 + const c_4 = $[4] !== b$11;
111 + let t5$15;
112 +
113 + if (c_3 || c_4) {
114 + t5$15 = <div a={a$10} b={b$11}></div>;
115 + $[3] = a$10;
116 + $[4] = b$11;
117 + $[5] = t5$15;
118 + } else {
119 + t5$15 = $[5];
120 + }
121
90 - new Foo$4(b$11);
91 - return <div a={a$10} b={b$11}></div>;
122 + return t5$15;
123 }
124
125 ```
compiler/forget/src/__tests__/fixtures/hir/dependencies-outputs.expect.md
+28 -8
@@ -75,16 +75,36 @@ function foo(
75
76 ```javascript
77 function foo$0(a$6, b$7) {
78 - const x$8 = [];
79 - x$8.push(a$6);
80 - <div>{x$8}</div>;
81 - const y$10 = [];
82 - bb1: if (x$8.length) {
83 - y$10.push(x$8);
78 + const $ = React.useMemoCache();
79 + const c_0 = $[0] !== a$6;
80 + let x$8;
81 + if (c_0) {
82 + x$8 = [];
83 + x$8.push(a$6);
84 + $[0] = a$6;
85 + $[1] = x$8;
86 + } else {
87 + x$8 = $[1];
88 }
89
86 - bb3: if (b$7) {
87 - y$10.push(b$7);
90 + <div>{x$8}</div>;
91 + const c_2 = $[2] !== x$8;
92 + const c_3 = $[3] !== b$7;
93 +
94 + if (c_2 || c_3) {
95 + const y$10 = [];
96 +
97 + bb1: if (x$8.length) {
98 + y$10.push(x$8);
99 + }
100 +
101 + bb3: if (b$7) {
102 + y$10.push(b$7);
103 + }
104 +
105 + $[2] = x$8;
106 + $[3] = b$7;
107 + } else {
108 }
109 }
110
compiler/forget/src/__tests__/fixtures/hir/dependencies.expect.md
+32 -8
@@ -74,15 +74,39 @@ function foo(
74
75 ```javascript
76 function foo$0(x$6, y$7, z$8) {
77 - const items$9 = [z$8];
78 - items$9.push(x$6);
79 - const items2$10 = [];
80 - bb1: if (x$6) {
81 - items2$10.push(y$7);
82 - }
83 -
84 - bb3: if (y$7) {
77 + const $ = React.useMemoCache();
78 + const c_0 = $[0] !== z$8;
79 + const c_1 = $[1] !== x$6;
80 + const c_2 = $[2] !== y$7;
81 + if (c_0 || c_1 || c_2) {
82 + const items$9 = [z$8];
83 items$9.push(x$6);
84 + const c_3 = $[3] !== x$6;
85 + const c_4 = $[4] !== y$7;
86 + let items2$10;
87 +
88 + if (c_3 || c_4) {
89 + items2$10 = [];
90 +
91 + bb1: if (x$6) {
92 + items2$10.push(y$7);
93 + }
94 +
95 + $[3] = x$6;
96 + $[4] = y$7;
97 + $[5] = items2$10;
98 + } else {
99 + items2$10 = $[5];
100 + }
101 +
102 + bb3: if (y$7) {
103 + items$9.push(x$6);
104 + }
105 +
106 + $[0] = z$8;
107 + $[1] = x$6;
108 + $[2] = y$7;
109 + } else {
110 }
111
112 return items2$10;
compiler/forget/src/__tests__/fixtures/hir/extend-scopes-if.expect.md
+17 -5
@@ -80,13 +80,25 @@ function foo(
80
81 ```javascript
82 function foo$0(a$7, b$8, c$9) {
83 - const x$10 = [];
84 - bb1: if (a$7) {
85 - if (b$8) {
86 - if (c$9) {
87 - x$10.push(0);
83 + const $ = React.useMemoCache();
84 + const c_0 = $[0] !== a$7;
85 + const c_1 = $[1] !== b$8;
86 + const c_2 = $[2] !== c$9;
87 + if (c_0 || c_1 || c_2) {
88 + const x$10 = [];
89 +
90 + bb1: if (a$7) {
91 + if (b$8) {
92 + if (c$9) {
93 + x$10.push(0);
94 + }
95 }
96 }
97 +
98 + $[0] = a$7;
99 + $[1] = b$8;
100 + $[2] = c$9;
101 + } else {
102 }
103
104 bb7: if (a$7.length) {
compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md
+9 -1
@@ -45,7 +45,15 @@ function Component(
45
46 ```javascript
47 function Component$0() {
48 - const a$5 = [];
48 + const $ = React.useMemoCache();
49 + let a$5;
50 + if (true) {
51 + a$5 = [];
52 + $[0] = a$5;
53 + } else {
54 + a$5 = $[0];
55 + }
56 +
57 const b$6 = a$5;
58 useFreeze$3(a$5);
59 foo$4(b$6);
compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md
+41 -10
@@ -75,8 +75,8 @@ bb0:
75 [4] Const mutate $13 = "\n "
76 [5] Const mutate $14 = "\n "
77 [6] Const mutate $15 = "\n "
78 - [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>
79 - [8] Return read $16_@2
78 + [7] Const mutate t5$16_@2 = JSX <read Component$0>{read $13}{read x$11_@0}{read $14}{read y$12_@1}{read $15}</read Component$0>
79 + [8] Return read t5$16_@2
80 ```
81
82 ## Reactive Scopes
@@ -107,15 +107,46 @@ function Component(
107
108 ```javascript
109 function Component$0(props$10) {
110 - const x$11 = [];
111 - const y$12 = useFreeze$4(x$11);
110 + const $ = React.useMemoCache();
111 + let x$11;
112 + if (true) {
113 + x$11 = [];
114 + $[0] = x$11;
115 + } else {
116 + x$11 = $[0];
117 + }
118 +
119 + const c_1 = $[1] !== x$11;
120 + let y$12;
121 +
122 + if (c_1) {
123 + y$12 = useFreeze$4(x$11);
124 + $[1] = x$11;
125 + $[2] = y$12;
126 + } else {
127 + y$12 = $[2];
128 + }
129 +
130 foo$5(y$12, x$11);
113 - return (
114 - <Component$0>
115 - {x$11}
116 - {y$12}
117 - </Component$0>
118 - );
131 + const c_3 = $[3] !== x$11;
132 + const c_4 = $[4] !== y$12;
133 + let t5$16;
134 +
135 + if (c_3 || c_4) {
136 + t5$16 = (
137 + <Component$0>
138 + {x$11}
139 + {y$12}
140 + </Component$0>
141 + );
142 + $[3] = x$11;
143 + $[4] = y$12;
144 + $[5] = t5$16;
145 + } else {
146 + t5$16 = $[5];
147 + }
148 +
149 + return t5$16;
150 }
151
152 ```
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md
+9 -1
@@ -46,7 +46,15 @@ function Component(
46
47 ```javascript
48 function Component$0() {
49 - const a$4 = [];
49 + const $ = React.useMemoCache();
50 + let a$4;
51 + if (true) {
52 + a$4 = [];
53 + $[0] = a$4;
54 + } else {
55 + a$4 = $[0];
56 + }
57 +
58 useFreeze$2(a$4);
59 useFreeze$2(a$4);
60 call$3(a$4);
compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md
+17 -4
@@ -76,14 +76,27 @@ function Component(
76
77 ```javascript
78 function Component$0(props$7) {
79 + const $ = React.useMemoCache();
80 const cond$8 = props$7.cond;
81 const x$9 = props$7.x;
82 const a$10 = undefined;
82 - let a$11 = undefined;
83 - bb1: if (cond$8) {
84 - a$11 = x$9;
83 + const c_0 = $[0] !== cond$8;
84 + const c_1 = $[1] !== x$9;
85 + let a$11;
86 + if (c_0 || c_1) {
87 + a$11 = undefined;
88 +
89 + bb1: if (cond$8) {
90 + a$11 = x$9;
91 + } else {
92 + a$11 = [];
93 + }
94 +
95 + $[0] = cond$8;
96 + $[1] = x$9;
97 + $[2] = a$11;
98 } else {
86 - a$11 = [];
99 + a$11 = $[2];
100 }
101
102 useFreeze$5(a$11);
compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md
+36 -8
@@ -139,8 +139,8 @@ bb2:
139 [6] Goto bb1
140 bb1:
141 predecessor blocks: bb2 bb0
142 - [7] Const mutate $14_@2 = JSX <read Foo$6 a={freeze a$9_@1} b={freeze b$10_@1} ></read Foo$6>
143 - [8] Return read $14_@2
142 + [7] Const mutate t6$14_@2 = JSX <read Foo$6 a={freeze a$9_@1} b={freeze b$10_@1} ></read Foo$6>
143 + [8] Return read t6$14_@2
144 ```
145
146 ## Reactive Scopes
@@ -169,14 +169,42 @@ function Component(
169
170 ```javascript
171 function Component$0(props$8) {
172 - const a$9 = compute$3(props$8.a);
173 - const b$10 = compute$3(props$8.b);
174 - bb1: if (props$8.c) {
175 - mutate$5(a$9);
176 - mutate$5(b$10);
172 + const $ = React.useMemoCache();
173 + const c_0 = $[0] !== props$8.a;
174 + const c_1 = $[1] !== props$8.b;
175 + const c_2 = $[2] !== props$8.c;
176 + let a$9;
177 + if (c_0 || c_1 || c_2) {
178 + a$9 = compute$3(props$8.a);
179 + const b$10 = compute$3(props$8.b);
180 +
181 + bb1: if (props$8.c) {
182 + mutate$5(a$9);
183 + mutate$5(b$10);
184 + }
185 +
186 + $[0] = props$8.a;
187 + $[1] = props$8.b;
188 + $[2] = props$8.c;
189 + $[3] = a$9;
190 + } else {
191 + a$9 = $[3];
192 + }
193 +
194 + const c_4 = $[4] !== a$9;
195 + const c_5 = $[5] !== b$10;
196 + let t6$14;
197 +
198 + if (c_4 || c_5) {
199 + t6$14 = <Foo$6 a={a$9} b={b$10}></Foo$6>;
200 + $[4] = a$9;
201 + $[5] = b$10;
202 + $[6] = t6$14;
203 + } else {
204 + t6$14 = $[6];
205 }
206
179 - return <Foo$6 a={a$9} b={b$10}></Foo$6>;
207 + return t6$14;
208 }
209
210 ```
compiler/forget/src/__tests__/fixtures/hir/independent.expect.md
+38 -5
@@ -30,8 +30,8 @@ function Foo() {}
30 bb0:
31 [1] Const mutate a$8_@0 = Call mutate compute$3:TFunction(read props$7.a)
32 [2] Const mutate b$9_@1 = Call mutate compute$3:TFunction(read props$7.b)
33 - [3] Const mutate $10_@2 = JSX <read Foo$5 a={freeze a$8_@0} b={freeze b$9_@1} ></read Foo$5>
34 - [4] Return read $10_@2
33 + [3] Const mutate t6$10_@2 = JSX <read Foo$5 a={freeze a$8_@0} b={freeze b$9_@1} ></read Foo$5>
34 + [4] Return read t6$10_@2
35 ```
36
37 ## Reactive Scopes
@@ -58,9 +58,42 @@ function Component(
58
59 ```javascript
60 function Component$0(props$7) {
61 - const a$8 = compute$3(props$7.a);
62 - const b$9 = compute$3(props$7.b);
63 - return <Foo$5 a={a$8} b={b$9}></Foo$5>;
61 + const $ = React.useMemoCache();
62 + const c_0 = $[0] !== props$7.a;
63 + let a$8;
64 + if (c_0) {
65 + a$8 = compute$3(props$7.a);
66 + $[0] = props$7.a;
67 + $[1] = a$8;
68 + } else {
69 + a$8 = $[1];
70 + }
71 +
72 + const c_2 = $[2] !== props$7.b;
73 + let b$9;
74 +
75 + if (c_2) {
76 + b$9 = compute$3(props$7.b);
77 + $[2] = props$7.b;
78 + $[3] = b$9;
79 + } else {
80 + b$9 = $[3];
81 + }
82 +
83 + const c_4 = $[4] !== a$8;
84 + const c_5 = $[5] !== b$9;
85 + let t6$10;
86 +
87 + if (c_4 || c_5) {
88 + t6$10 = <Foo$5 a={a$8} b={b$9}></Foo$5>;
89 + $[4] = a$8;
90 + $[5] = b$9;
91 + $[6] = t6$10;
92 + } else {
93 + t6$10 = $[6];
94 + }
95 +
96 + return t6$10;
97 }
98
99 ```
compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md
+38 -7
@@ -109,8 +109,8 @@ bb2:
109 [5] Goto bb1
110 bb1:
111 predecessor blocks: bb2 bb0
112 - [6] Const mutate $14_@1 = JSX <read Foo$6 a={freeze a$9_@0} b={freeze b$10_@0} ></read Foo$6>
113 - [7] Return read $14_@1
112 + [6] Const mutate t7$14_@1 = JSX <read Foo$6 a={freeze a$9_@0} b={freeze b$10_@0} ></read Foo$6>
113 + [7] Return read t7$14_@1
114 ```
115
116 ## Reactive Scopes
@@ -138,13 +138,44 @@ function Component(
138
139 ```javascript
140 function Component$0(props$8) {
141 - const a$9 = compute$3(props$8.a);
142 - const b$10 = compute$3(props$8.b);
143 - bb1: if (props$8.c) {
144 - foo$5(a$9, b$10);
141 + const $ = React.useMemoCache();
142 + const c_0 = $[0] !== props$8.a;
143 + const c_1 = $[1] !== props$8.b;
144 + const c_2 = $[2] !== props$8.c;
145 + let a$9;
146 + let b$10;
147 + if (c_0 || c_1 || c_2) {
148 + a$9 = compute$3(props$8.a);
149 + b$10 = compute$3(props$8.b);
150 +
151 + bb1: if (props$8.c) {
152 + foo$5(a$9, b$10);
153 + }
154 +
155 + $[0] = props$8.a;
156 + $[1] = props$8.b;
157 + $[2] = props$8.c;
158 + $[3] = a$9;
159 + $[4] = b$10;
160 + } else {
161 + a$9 = $[3];
162 + b$10 = $[4];
163 + }
164 +
165 + const c_5 = $[5] !== a$9;
166 + const c_6 = $[6] !== b$10;
167 + let t7$14;
168 +
169 + if (c_5 || c_6) {
170 + t7$14 = <Foo$6 a={a$9} b={b$10}></Foo$6>;
171 + $[5] = a$9;
172 + $[6] = b$10;
173 + $[7] = t7$14;
174 + } else {
175 + t7$14 = $[7];
176 }
177
147 - return <Foo$6 a={a$9} b={b$10}></Foo$6>;
178 + return t7$14;
179 }
180
181 ```
compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md
+34 -6
@@ -31,8 +31,8 @@ bb0:
31 [1] Const mutate a$9_@0[1:4] = Call mutate compute$3:TFunction(read props$8.a)
32 [2] Const mutate b$10_@0[1:4] = Call mutate compute$3:TFunction(read props$8.b)
33 [3] Call mutate foo$5:TFunction(mutate a$9_@0, mutate b$10_@0)
34 - [4] Const mutate $11_@1 = JSX <read Foo$6 a={freeze a$9_@0} b={freeze b$10_@0} ></read Foo$6>
35 - [5] Return read $11_@1
34 + [4] Const mutate t6$11_@1 = JSX <read Foo$6 a={freeze a$9_@0} b={freeze b$10_@0} ></read Foo$6>
35 + [5] Return read t6$11_@1
36 ```
37
38 ## Reactive Scopes
@@ -58,10 +58,38 @@ function Component(
58
59 ```javascript
60 function Component$0(props$8) {
61 - const a$9 = compute$3(props$8.a);
62 - const b$10 = compute$3(props$8.b);
63 - foo$5(a$9, b$10);
64 - return <Foo$6 a={a$9} b={b$10}></Foo$6>;
61 + const $ = React.useMemoCache();
62 + const c_0 = $[0] !== props$8.a;
63 + const c_1 = $[1] !== props$8.b;
64 + let a$9;
65 + let b$10;
66 + if (c_0 || c_1) {
67 + a$9 = compute$3(props$8.a);
68 + b$10 = compute$3(props$8.b);
69 + foo$5(a$9, b$10);
70 + $[0] = props$8.a;
71 + $[1] = props$8.b;
72 + $[2] = a$9;
73 + $[3] = b$10;
74 + } else {
75 + a$9 = $[2];
76 + b$10 = $[3];
77 + }
78 +
79 + const c_4 = $[4] !== a$9;
80 + const c_5 = $[5] !== b$10;
81 + let t6$11;
82 +
83 + if (c_4 || c_5) {
84 + t6$11 = <Foo$6 a={a$9} b={b$10}></Foo$6>;
85 + $[4] = a$9;
86 + $[5] = b$10;
87 + $[6] = t6$11;
88 + } else {
89 + t6$11 = $[6];
90 + }
91 +
92 + return t6$11;
93 }
94
95 ```
compiler/forget/src/__tests__/fixtures/hir/inverted-if.expect.md
+16 -4
@@ -57,11 +57,23 @@ function foo(
57
58 ```javascript
59 function foo$0(a$5, b$6, c$7) {
60 - const y$8 = [];
61 - bb1: if (a$5) {
62 - if (b$6) {
63 - y$8.push(c$7);
60 + const $ = React.useMemoCache();
61 + const c_0 = $[0] !== a$5;
62 + const c_1 = $[1] !== b$6;
63 + const c_2 = $[2] !== c$7;
64 + if (c_0 || c_1 || c_2) {
65 + const y$8 = [];
66 +
67 + bb1: if (a$5) {
68 + if (b$6) {
69 + y$8.push(c$7);
70 + }
71 }
72 +
73 + $[0] = a$5;
74 + $[1] = b$6;
75 + $[2] = c$7;
76 + } else {
77 }
78 }
79
compiler/forget/src/__tests__/fixtures/hir/issue852.expect.md
+14 -4
@@ -43,10 +43,20 @@ function Component(
43
44 ```javascript
45 function Component$0(c$6) {
46 - const x$7 = {
47 - c: c$6,
48 - };
49 - mutate$3(x$7);
46 + const $ = React.useMemoCache();
47 + const c_0 = $[0] !== c$6;
48 + let x$7;
49 + if (c_0) {
50 + x$7 = {
51 + c: c$6,
52 + };
53 + mutate$3(x$7);
54 + $[0] = c$6;
55 + $[1] = x$7;
56 + } else {
57 + x$7 = $[1];
58 + }
59 +
60 const a$8 = x$7;
61 const b$9 = a$8;
62 }
compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md
+43 -10
@@ -25,12 +25,12 @@ bb0:
25 [4] Const mutate $17:TPrimitive = "div"
26 [5] Const mutate $18 = "\n "
27 [6] Const mutate $19 = "Text"
28 - [7] Const mutate $20_@0 = JsxFragment [read $19]
28 + [7] Const mutate t0$20_@0 = JsxFragment [read $19]
29 [8] Const mutate $21 = "\n "
30 - [9] Const mutate $22_@1 = JSX <read $17:TPrimitive>{read $18}{read $20_@0}{read $21}</read $17:TPrimitive>
30 + [9] Const mutate t2$22_@1 = JSX <read $17:TPrimitive>{read $18}{read t0$20_@0}{read $21}</read $17:TPrimitive>
31 [10] Const mutate $23 = "\n "
32 - [11] Const mutate $24_@2 = JsxFragment [read $14, read props$13.greeting, read $15:TPrimitive, read $16, read $22_@1, read $23]
33 - [12] Return read $24_@2
32 + [11] Const mutate t5$24_@2 = JsxFragment [read $14, read props$13.greeting, read $15:TPrimitive, read $16, read t2$22_@1, read $23]
33 + [12] Return read t5$24_@2
34 ```
35
36 ## Reactive Scopes
@@ -65,12 +65,45 @@ function Foo(
65
66 ```javascript
67 function Foo$0(props$13) {
68 - return (
69 - <>
70 - Hello {props$13.greeting}
71 - {<div>{<>Text</>}</div>}
72 - </>
73 - );
68 + const $ = React.useMemoCache();
69 + let t0$20;
70 + if (true) {
71 + t0$20 = <>Text</>;
72 + $[0] = t0$20;
73 + } else {
74 + t0$20 = $[0];
75 + }
76 +
77 + const c_1 = $[1] !== t0$20;
78 + let t2$22;
79 +
80 + if (c_1) {
81 + t2$22 = <div>{t0$20}</div>;
82 + $[1] = t0$20;
83 + $[2] = t2$22;
84 + } else {
85 + t2$22 = $[2];
86 + }
87 +
88 + const c_3 = $[3] !== props$13.greeting;
89 + const c_4 = $[4] !== t2$22;
90 + let t5$24;
91 +
92 + if (c_3 || c_4) {
93 + t5$24 = (
94 + <>
95 + Hello {props$13.greeting}
96 + {t2$22}
97 + </>
98 + );
99 + $[3] = props$13.greeting;
100 + $[4] = t2$22;
101 + $[5] = t5$24;
102 + } else {
103 + t5$24 = $[5];
104 + }
105 +
106 + return t5$24;
107 }
108
109 ```
compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md
+96 -24
@@ -23,20 +23,20 @@ function g() {}
23
24 ```
25 bb0:
26 - [1] Const mutate $5_@0 = Call mutate f$1:TFunction()
27 - [2] Let mutate $6_@1[2:7] = undefined
28 - [2] If (read $5_@0) then:bb2 else:bb3 fallthrough=bb1
26 + [1] Const mutate t0$5_@0 = Call mutate f$1:TFunction()
27 + [2] Let mutate t2$6_@1[2:7] = undefined
28 + [2] If (read t0$5_@0) then:bb2 else:bb3 fallthrough=bb1
29 bb2:
30 predecessor blocks: bb0
31 - [3] Const mutate $6_@1[2:7] = Call mutate g$4:TFunction()
31 + [3] Const mutate t2$6_@1[2:7] = Call mutate g$4:TFunction()
32 [4] Goto bb1
33 bb3:
34 predecessor blocks: bb0
35 - [5] Const mutate $6_@1[2:7] = read $5_@0
35 + [5] Const mutate t2$6_@1[2:7] = read t0$5_@0
36 [6] Goto bb1
37 bb1:
38 predecessor blocks: bb2 bb3
39 - [7] Return freeze $6_@1
39 + [7] Return freeze t2$6_@1
40 ```
41
42 ## Reactive Scopes
@@ -64,10 +64,34 @@ function And(
64
65 ```javascript
66 function And$0() {
67 - bb1: if (f$1()) {
67 + const $ = React.useMemoCache();
68 + let t0$5;
69 + if (true) {
70 + t0$5 = f$1();
71 + $[0] = t0$5;
72 } else {
73 + t0$5 = $[0];
74 }
70 - return f$1();
75 +
76 + const c_1 = $[1] !== t0$5;
77 + let t2$6;
78 +
79 + if (c_1) {
80 + t2$6 = undefined;
81 +
82 + bb1: if (t0$5) {
83 + t2$6 = g$4();
84 + } else {
85 + t2$6 = t0$5;
86 + }
87 +
88 + $[1] = t0$5;
89 + $[2] = t2$6;
90 + } else {
91 + t2$6 = $[2];
92 + }
93 +
94 + return t2$6;
95 }
96
97 ```
@@ -75,20 +99,20 @@ function And$0() {
99
100 ```
101 bb0:
78 - [1] Const mutate $5_@0 = Call mutate f$1:TFunction()
79 - [2] Let mutate $6_@1[2:7] = undefined
80 - [2] If (read $5_@0) then:bb2 else:bb3 fallthrough=bb1
102 + [1] Const mutate t0$5_@0 = Call mutate f$1:TFunction()
103 + [2] Let mutate t2$6_@1[2:7] = undefined
104 + [2] If (read t0$5_@0) then:bb2 else:bb3 fallthrough=bb1
105 bb2:
106 predecessor blocks: bb0
83 - [3] Const mutate $6_@1[2:7] = read $5_@0
107 + [3] Const mutate t2$6_@1[2:7] = read t0$5_@0
108 [4] Goto bb1
109 bb3:
110 predecessor blocks: bb0
87 - [5] Const mutate $6_@1[2:7] = Call mutate g$4:TFunction()
111 + [5] Const mutate t2$6_@1[2:7] = Call mutate g$4:TFunction()
112 [6] Goto bb1
113 bb1:
114 predecessor blocks: bb2 bb3
91 - [7] Return freeze $6_@1
115 + [7] Return freeze t2$6_@1
116 ```
117
118 ## Reactive Scopes
@@ -116,10 +140,34 @@ function Or(
140
141 ```javascript
142 function Or$0() {
119 - bb1: if (f$1()) {
143 + const $ = React.useMemoCache();
144 + let t0$5;
145 + if (true) {
146 + t0$5 = f$1();
147 + $[0] = t0$5;
148 + } else {
149 + t0$5 = $[0];
150 + }
151 +
152 + const c_1 = $[1] !== t0$5;
153 + let t2$6;
154 +
155 + if (c_1) {
156 + t2$6 = undefined;
157 +
158 + bb1: if (t0$5) {
159 + t2$6 = t0$5;
160 + } else {
161 + t2$6 = g$4();
162 + }
163 +
164 + $[1] = t0$5;
165 + $[2] = t2$6;
166 } else {
167 + t2$6 = $[2];
168 }
122 - return g$4();
169 +
170 + return t2$6;
171 }
172
173 ```
@@ -127,22 +175,22 @@ function Or$0() {
175
176 ```
177 bb0:
130 - [1] Const mutate $9_@0:TPrimitive = Call mutate f$2:TFunction()
178 + [1] Const mutate t0$9_@0:TPrimitive = Call mutate f$2:TFunction()
179 [2] Const mutate $10:TPrimitive = null
132 - [3] Const mutate $11:TPrimitive = Binary read $9_@0:TPrimitive != read $10:TPrimitive
133 - [4] Let mutate $12_@1:TPrimitive[4:9] = undefined
180 + [3] Const mutate $11:TPrimitive = Binary read t0$9_@0:TPrimitive != read $10:TPrimitive
181 + [4] Let mutate t2$12_@1:TPrimitive[4:9] = undefined
182 [4] If (read $11:TPrimitive) then:bb2 else:bb3 fallthrough=bb1
183 bb2:
184 predecessor blocks: bb0
137 - [5] Const mutate $12_@1:TPrimitive[4:9] = read $9_@0:TPrimitive
185 + [5] Const mutate t2$12_@1:TPrimitive[4:9] = read t0$9_@0:TPrimitive
186 [6] Goto bb1
187 bb3:
188 predecessor blocks: bb0
141 - [7] Const mutate $12_@1:TPrimitive[4:9] = Call mutate g$7:TFunction()
189 + [7] Const mutate t2$12_@1:TPrimitive[4:9] = Call mutate g$7:TFunction()
190 [8] Goto bb1
191 bb1:
192 predecessor blocks: bb2 bb3
145 - [9] Return freeze $12_@1:TPrimitive
193 + [9] Return freeze t2$12_@1:TPrimitive
194 ```
195
196 ## Reactive Scopes
@@ -173,10 +221,34 @@ function QuestionQuestion(
221
222 ```javascript
223 function QuestionQuestion$0(props$8) {
176 - bb1: if (f$2() != null) {
224 + const $ = React.useMemoCache();
225 + let t0$9;
226 + if (true) {
227 + t0$9 = f$2();
228 + $[0] = t0$9;
229 + } else {
230 + t0$9 = $[0];
231 + }
232 +
233 + const c_1 = $[1] !== t0$9;
234 + let t2$12;
235 +
236 + if (c_1) {
237 + t2$12 = undefined;
238 +
239 + bb1: if (t0$9 != null) {
240 + t2$12 = t0$9;
241 + } else {
242 + t2$12 = g$7();
243 + }
244 +
245 + $[1] = t0$9;
246 + $[2] = t2$12;
247 } else {
248 + t2$12 = $[2];
249 }
179 - return g$7();
250 +
251 + return t2$12;
252 }
253
254 ```
compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md
+27 -24
@@ -179,36 +179,39 @@ function Component(
179
180 ```javascript
181 function Component$0(props$12) {
182 - let a$18 = {};
183 - let b$20 = {};
184 - let c$22 = {};
185 - let d$24 = {};
186 - bb2: while (true) {
187 - const z$19 = a$18;
188 - a$18 = b$20;
189 - b$20 = c$22;
190 - c$22 = d$24;
191 - d$24 = z$19;
192 - mutate$7(a$18, b$20);
193 -
194 - bb4: if (cond$8(a$18)) {
195 - break;
182 + if (true) {
183 + let a$18 = {};
184 + let b$20 = {};
185 + let c$22 = {};
186 + let d$24 = {};
187 + bb2: while (true) {
188 + const z$19 = a$18;
189 + a$18 = b$20;
190 + b$20 = c$22;
191 + c$22 = d$24;
192 + d$24 = z$19;
193 + mutate$7(a$18, b$20);
194 +
195 + bb4: if (cond$8(a$18)) {
196 + break;
197 + }
198 }
197 - }
199
199 - bb7: if (a$18) {
200 - }
200 + bb7: if (a$18) {
201 + }
202
202 - bb9: if (b$20) {
203 - }
203 + bb9: if (b$20) {
204 + }
205
205 - bb11: if (c$22) {
206 - }
206 + bb11: if (c$22) {
207 + }
208
208 - bb13: if (d$24) {
209 - }
209 + bb13: if (d$24) {
210 + }
211
211 - mutate$7(d$24, null);
212 + mutate$7(d$24, null);
213 + } else {
214 + }
215 }
216
217 ```
compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md
+39 -19
@@ -131,31 +131,51 @@ function Component(
131
132 ```javascript
133 function Component$0(props$10) {
134 - const a$11 = {};
135 - const b$12 = [a$11];
136 - const c$13 = {};
137 - const d$14 = {
138 - c: c$13,
139 - };
140 - const x$15 = {};
141 - x$15.b = b$12;
142 - const y$16 = mutate$8(x$15, d$14);
143 - bb1: if (a$11) {
134 + const $ = React.useMemoCache();
135 + let a$11;
136 + if (true) {
137 + a$11 = {};
138 + $[0] = a$11;
139 + } else {
140 + a$11 = $[0];
141 }
142
146 - bb3: if (b$12) {
147 - }
143 + const c_1 = $[1] !== a$11;
144
149 - bb5: if (c$13) {
150 - }
145 + if (c_1) {
146 + const b$12 = [a$11];
147
152 - bb7: if (d$14) {
153 - }
148 + if (true) {
149 + const c$13 = {};
150 + } else {
151 + }
152
155 - bb9: if (y$16) {
156 - }
153 + const d$14 = {
154 + c: c$13,
155 + };
156 + const x$15 = {};
157 + x$15.b = b$12;
158 + const y$16 = mutate$8(x$15, d$14);
159 +
160 + bb1: if (a$11) {
161 + }
162 +
163 + bb3: if (b$12) {
164 + }
165 +
166 + bb5: if (c$13) {
167 + }
168 +
169 + bb7: if (d$14) {
170 + }
171 +
172 + bb9: if (y$16) {
173 + }
174
158 - mutate$8(x$15, null);
175 + mutate$8(x$15, null);
176 + $[1] = a$11;
177 + } else {
178 + }
179 }
180
181 ```
compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md
+27 -19
@@ -163,31 +163,39 @@ function Component(
163
164 ```javascript
165 function Component$0(props$11) {
166 - const a$12 = {};
167 - const b$13 = {};
168 - const c$14 = {};
169 - const d$15 = {};
170 - bb2: while (true) {
171 - mutate$6(a$12, b$13);
172 -
173 - bb4: if (cond$7(a$12)) {
174 - break;
166 + if (true) {
167 + const a$12 = {};
168 + const b$13 = {};
169 + if (true) {
170 + const c$14 = {};
171 + } else {
172 }
176 - }
173
178 - bb7: if (a$12) {
179 - }
174 + const d$15 = {};
175
181 - bb9: if (b$13) {
182 - }
176 + bb2: while (true) {
177 + mutate$6(a$12, b$13);
178
184 - bb11: if (c$14) {
185 - }
179 + bb4: if (cond$7(a$12)) {
180 + break;
181 + }
182 + }
183
187 - bb13: if (d$15) {
188 - }
184 + bb7: if (a$12) {
185 + }
186 +
187 + bb9: if (b$13) {
188 + }
189 +
190 + bb11: if (c$14) {
191 + }
192 +
193 + bb13: if (d$15) {
194 + }
195
190 - mutate$6(d$15, null);
196 + mutate$6(d$15, null);
197 + } else {
198 + }
199 }
200
201 ```
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved-by-terminal.expect.md
+15 -6
@@ -54,13 +54,22 @@ function foo(
54
55 ```javascript
56 function foo$0(a$6, b$7, c$8) {
57 - const x$9 = [];
58 - const y$10 = [];
59 - bb1: if (x$9) {
60 - }
57 + const $ = React.useMemoCache();
58 + const c_0 = $[0] !== a$6;
59 + const c_1 = $[1] !== b$7;
60 + if (c_0 || c_1) {
61 + const x$9 = [];
62 + const y$10 = [];
63 +
64 + bb1: if (x$9) {
65 + }
66
62 - y$10.push(a$6);
63 - x$9.push(b$7);
67 + y$10.push(a$6);
68 + x$9.push(b$7);
69 + $[0] = a$6;
70 + $[1] = b$7;
71 + } else {
72 + }
73 }
74
75 ```
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved.expect.md
+12 -4
@@ -44,10 +44,18 @@ function foo(
44
45 ```javascript
46 function foo$0(a$5, b$6) {
47 - const x$7 = [];
48 - const y$8 = [];
49 - x$7.push(a$5);
50 - y$8.push(b$6);
47 + const $ = React.useMemoCache();
48 + const c_0 = $[0] !== a$5;
49 + const c_1 = $[1] !== b$6;
50 + if (c_0 || c_1) {
51 + const x$7 = [];
52 + const y$8 = [];
53 + x$7.push(a$5);
54 + y$8.push(b$6);
55 + $[0] = a$5;
56 + $[1] = b$6;
57 + } else {
58 + }
59 }
60
61 ```
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowed.expect.md
+19 -4
@@ -46,10 +46,25 @@ function foo(
46
47 ```javascript
48 function foo$0(a$5, b$6) {
49 - const x$7 = [];
50 - const y$8 = [];
51 - y$8.push(b$6);
52 - x$7.push(a$5);
49 + const $ = React.useMemoCache();
50 + const c_0 = $[0] !== b$6;
51 + const c_1 = $[1] !== a$5;
52 + if (c_0 || c_1) {
53 + const x$7 = [];
54 + const c_2 = $[2] !== b$6;
55 +
56 + if (c_2) {
57 + const y$8 = [];
58 + y$8.push(b$6);
59 + $[2] = b$6;
60 + } else {
61 + }
62 +
63 + x$7.push(a$5);
64 + $[0] = b$6;
65 + $[1] = a$5;
66 + } else {
67 + }
68 }
69
70 ```
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md
+40 -6
@@ -75,15 +75,49 @@ function foo(
75
76 ```javascript
77 function foo$0(a$8, b$9, c$10) {
78 - const x$11 = [];
79 - bb1: if (a$8) {
80 - const y$12 = [];
78 + const $ = React.useMemoCache();
79 + const c_0 = $[0] !== a$8;
80 + const c_1 = $[1] !== b$9;
81 + const c_2 = $[2] !== c$10;
82 + let x$11;
83 + if (c_0 || c_1 || c_2) {
84 + x$11 = [];
85
82 - bb3: if (b$9) {
83 - y$12.push(c$10);
86 + bb1: if (a$8) {
87 + const c_4 = $[4] !== b$9;
88 + const c_5 = $[5] !== c$10;
89 + let y$12;
90 +
91 + if (c_4 || c_5) {
92 + y$12 = [];
93 +
94 + bb3: if (b$9) {
95 + y$12.push(c$10);
96 + }
97 +
98 + $[4] = b$9;
99 + $[5] = c$10;
100 + $[6] = y$12;
101 + } else {
102 + y$12 = $[6];
103 + }
104 +
105 + const c_7 = $[7] !== y$12;
106 +
107 + if (c_7) {
108 + $[7] = y$12;
109 + } else {
110 + }
111 +
112 + x$11.push(<div>{y$12}</div>);
113 }
114
86 - x$11.push(<div>{y$12}</div>);
115 + $[0] = a$8;
116 + $[1] = b$9;
117 + $[2] = c$10;
118 + $[3] = x$11;
119 + } else {
120 + x$11 = $[3];
121 }
122
123 return x$11;
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-while.expect.md
+17 -5
@@ -60,11 +60,23 @@ function foo(
60
61 ```javascript
62 function foo$0(a$6, b$7, c$8) {
63 - const x$9 = [];
64 - const y$10 = [];
65 - bb2: while (c$8) {
66 - y$10.push(b$7);
67 - x$9.push(a$6);
63 + const $ = React.useMemoCache();
64 + const c_0 = $[0] !== c$8;
65 + const c_1 = $[1] !== b$7;
66 + const c_2 = $[2] !== a$6;
67 + if (c_0 || c_1 || c_2) {
68 + const x$9 = [];
69 + const y$10 = [];
70 +
71 + bb2: while (c$8) {
72 + y$10.push(b$7);
73 + x$9.push(a$6);
74 + }
75 +
76 + $[0] = c$8;
77 + $[1] = b$7;
78 + $[2] = a$6;
79 + } else {
80 }
81 }
82
compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-within-block.expect.md
+21 -6
@@ -67,15 +67,30 @@ function foo(
67
68 ```javascript
69 function foo$0(a$6, b$7, c$8) {
70 - const x$9 = [];
71 - bb1: if (a$6) {
72 - const y$10 = [];
70 + const $ = React.useMemoCache();
71 + const c_0 = $[0] !== a$6;
72 + const c_1 = $[1] !== b$7;
73 + const c_2 = $[2] !== c$8;
74 + let x$9;
75 + if (c_0 || c_1 || c_2) {
76 + x$9 = [];
77
74 - bb3: if (b$7) {
75 - y$10.push(c$8);
78 + bb1: if (a$6) {
79 + const y$10 = [];
80 +
81 + bb3: if (b$7) {
82 + y$10.push(c$8);
83 + }
84 +
85 + x$9.push(y$10);
86 }
87
78 - x$9.push(y$10);
88 + $[0] = a$6;
89 + $[1] = b$7;
90 + $[2] = c$8;
91 + $[3] = x$9;
92 + } else {
93 + x$9 = $[3];
94 }
95
96 return x$9;
compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md
+34 -8
@@ -22,8 +22,8 @@ bb0:
22 [3] Reassign mutate x$7_@0.y[1:6] = read y$8_@0
23 [4] Const mutate child$9_@0[1:6] = JSX <read Component$0 data={freeze y$8_@0} ></read Component$0>
24 [5] Call mutate x$7_@0.y.push(read props$6.p0)
25 - [6] Const mutate $10_@1 = JSX <read Component$0 data={freeze x$7_@0:TObject} >{read child$9_@0}</read Component$0>
26 - [7] Return read $10_@1
25 + [6] Const mutate t5$10_@1 = JSX <read Component$0 data={freeze x$7_@0:TObject} >{read child$9_@0}</read Component$0>
26 + [7] Return read t5$10_@1
27 ```
28
29 ## Reactive Scopes
@@ -51,12 +51,38 @@ function Component(
51
52 ```javascript
53 function Component$0(props$6) {
54 - const x$7 = {};
55 - const y$8 = [];
56 - x$7.y = y$8;
57 - const child$9 = <Component$0 data={y$8}></Component$0>;
58 - x$7.y.push(props$6.p0);
59 - return <Component$0 data={x$7}>{child$9}</Component$0>;
54 + const $ = React.useMemoCache();
55 + const c_0 = $[0] !== props$6.p0;
56 + let x$7;
57 + let child$9;
58 + if (c_0) {
59 + x$7 = {};
60 + const y$8 = [];
61 + x$7.y = y$8;
62 + child$9 = <Component$0 data={y$8}></Component$0>;
63 + x$7.y.push(props$6.p0);
64 + $[0] = props$6.p0;
65 + $[1] = x$7;
66 + $[2] = child$9;
67 + } else {
68 + x$7 = $[1];
69 + child$9 = $[2];
70 + }
71 +
72 + const c_3 = $[3] !== x$7;
73 + const c_4 = $[4] !== child$9;
74 + let t5$10;
75 +
76 + if (c_3 || c_4) {
77 + t5$10 = <Component$0 data={x$7}>{child$9}</Component$0>;
78 + $[3] = x$7;
79 + $[4] = child$9;
80 + $[5] = t5$10;
81 + } else {
82 + t5$10 = $[5];
83 + }
84 +
85 + return t5$10;
86 }
87
88 ```
compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md
+18 -5
@@ -49,11 +49,24 @@ function foo(
49
50 ```javascript
51 function foo$0() {
52 - const x$4 = {};
53 - const y$5 = [];
54 - const z$6 = {};
55 - y$5.push(z$6);
56 - x$4.y = y$5;
52 + const $ = React.useMemoCache();
53 + let x$4;
54 + if (true) {
55 + x$4 = {};
56 +
57 + if (true) {
58 + const y$5 = [];
59 + const z$6 = {};
60 + y$5.push(z$6);
61 + } else {
62 + }
63 +
64 + x$4.y = y$5;
65 + $[0] = x$4;
66 + } else {
67 + x$4 = $[0];
68 + }
69 +
70 return x$4;
71 }
72
compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md
+38 -6
@@ -72,13 +72,45 @@ function foo(
72
73 ```javascript
74 function foo$0(a$8, b$9, c$10) {
75 - const x$11 = [];
76 - bb1: if (a$8) {
77 - const y$12 = [];
78 - y$12.push(b$9);
79 - x$11.push(<div>{y$12}</div>);
75 + const $ = React.useMemoCache();
76 + const c_0 = $[0] !== a$8;
77 + const c_1 = $[1] !== b$9;
78 + const c_2 = $[2] !== c$10;
79 + let x$11;
80 + if (c_0 || c_1 || c_2) {
81 + x$11 = [];
82 +
83 + bb1: if (a$8) {
84 + const c_4 = $[4] !== b$9;
85 + let y$12;
86 +
87 + if (c_4) {
88 + y$12 = [];
89 + y$12.push(b$9);
90 + $[4] = b$9;
91 + $[5] = y$12;
92 + } else {
93 + y$12 = $[5];
94 + }
95 +
96 + const c_6 = $[6] !== y$12;
97 +
98 + if (c_6) {
99 + $[6] = y$12;
100 + } else {
101 + }
102 +
103 + x$11.push(<div>{y$12}</div>);
104 + } else {
105 + x$11.push(c$10);
106 + }
107 +
108 + $[0] = a$8;
109 + $[1] = b$9;
110 + $[2] = c$10;
111 + $[3] = x$11;
112 } else {
81 - x$11.push(c$10);
113 + x$11 = $[3];
114 }
115
116 return x$11;
compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md
+31 -7
@@ -33,8 +33,8 @@ bb4:
33 bb1:
34 predecessor blocks: bb4 bb2 bb0
35 [8] Const mutate $13:TPrimitive = "div"
36 - [9] Const mutate $15_@1 = JSX <read $13:TPrimitive>{freeze x$10_@0:TFunction}</read $13:TPrimitive>
37 - [10] Return read $15_@1
36 + [9] Const mutate t4$15_@1 = JSX <read $13:TPrimitive>{freeze x$10_@0:TFunction}</read $13:TPrimitive>
37 + [10] Return read t4$15_@1
38 ```
39
40 ## Reactive Scopes
@@ -67,14 +67,38 @@ function f(
67
68 ```javascript
69 function f$0(a$8, b$9) {
70 - const x$10 = [];
71 - bb1: if (a$8.length === 1) {
72 - if (b$9) {
73 - x$10.push(b$9);
70 + const $ = React.useMemoCache();
71 + const c_0 = $[0] !== a$8.length;
72 + const c_1 = $[1] !== b$9;
73 + let x$10;
74 + if (c_0 || c_1) {
75 + x$10 = [];
76 +
77 + bb1: if (a$8.length === 1) {
78 + if (b$9) {
79 + x$10.push(b$9);
80 + }
81 }
82 +
83 + $[0] = a$8.length;
84 + $[1] = b$9;
85 + $[2] = x$10;
86 + } else {
87 + x$10 = $[2];
88 + }
89 +
90 + const c_3 = $[3] !== x$10;
91 + let t4$15;
92 +
93 + if (c_3) {
94 + t4$15 = <div>{x$10}</div>;
95 + $[3] = x$10;
96 + $[4] = t4$15;
97 + } else {
98 + t4$15 = $[4];
99 }
100
77 - return <div>{x$10}</div>;
101 + return t4$15;
102 }
103
104 ```
compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md
+41 -8
@@ -35,8 +35,8 @@ bb1:
35 predecessor blocks: bb2 bb0
36 [7] Const mutate _$12_@1 = JSX <read Component$0 x={freeze x$7_@0:TFunction} ></read Component$0>
37 [8] Call read y$8.push(read props$6.p2)
38 - [9] Const mutate $15_@2 = JSX <read Component$0 x={read x$7_@0:TFunction} y={read y$8:TFunction} ></read Component$0>
39 - [10] Return read $15_@2
38 + [9] Const mutate t6$15_@2 = JSX <read Component$0 x={read x$7_@0:TFunction} y={read y$8:TFunction} ></read Component$0>
39 + [10] Return read t6$15_@2
40 ```
41
42 ## Reactive Scopes
@@ -69,17 +69,50 @@ function Component(
69
70 ```javascript
71 function Component$0(props$6) {
72 - let x$7 = [];
73 - x$7.push(props$6.p0);
74 - const y$8 = x$7;
75 - bb1: if (props$6.p1) {
72 + const $ = React.useMemoCache();
73 + const c_0 = $[0] !== props$6.p0;
74 + const c_1 = $[1] !== props$6.p1;
75 + let x$7;
76 + if (c_0 || c_1) {
77 x$7 = [];
78 + x$7.push(props$6.p0);
79 + const y$8 = x$7;
80 +
81 + bb1: if (props$6.p1) {
82 + x$7 = [];
83 + }
84 +
85 + $[0] = props$6.p0;
86 + $[1] = props$6.p1;
87 + $[2] = x$7;
88 + } else {
89 + x$7 = $[2];
90 }
91
79 - const _$12 = <Component$0 x={x$7}></Component$0>;
92 + const c_3 = $[3] !== x$7;
93 +
94 + if (c_3) {
95 + const _$12 = <Component$0 x={x$7}></Component$0>;
96 +
97 + $[3] = x$7;
98 + } else {
99 + }
100
101 y$8.push(props$6.p2);
82 - return <Component$0 x={x$7} y={y$8}></Component$0>;
102 + const c_4 = $[4] !== x$7;
103 + const c_5 = $[5] !== y$8;
104 + let t6$15;
105 +
106 + if (c_4 || c_5) {
107 + t6$15 = <Component$0 x={x$7} y={y$8}></Component$0>;
108 + $[4] = x$7;
109 + $[5] = y$8;
110 + $[6] = t6$15;
111 + } else {
112 + t6$15 = $[6];
113 + }
114 +
115 + return t6$15;
116 }
117
118 ```
compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md
+68 -22
@@ -66,8 +66,8 @@ bb3:
66 [16] Const mutate $26 = "\n "
67 [17] Const mutate $27 = "\n "
68 [18] Const mutate $28 = "\n "
69 - [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>
70 - [20] Return read $31_@3
69 + [19] Const mutate t9$31_@3 = JSX <read $25:TPrimitive>{read $26}{read y$19_@1}{read $27}{freeze x$22_@2:TFunction}{read $28}</read $25:TPrimitive>
70 + [20] Return read t9$31_@3
71 ```
72
73 ## Reactive Scopes
@@ -119,33 +119,79 @@ function foo(
119
120 ```javascript
121 function foo$0(a$13, b$14, c$15) {
122 - const x$16 = [];
123 - bb1: if (a$13) {
124 - x$16.push(a$13);
122 + const $ = React.useMemoCache();
123 + const c_0 = $[0] !== a$13;
124 + let x$16;
125 + if (c_0) {
126 + x$16 = [];
127 +
128 + bb1: if (a$13) {
129 + x$16.push(a$13);
130 + }
131 +
132 + $[0] = a$13;
133 + $[1] = x$16;
134 + } else {
135 + x$16 = $[1];
136 }
137
127 - const y$19 = <div>{x$16}</div>;
128 - let x$22 = undefined;
138 + const c_2 = $[2] !== x$16;
139 + let y$19;
140
130 - bb3: switch (b$14) {
131 - case 0: {
132 - x$22 = [];
133 - x$22.push(b$14);
134 - break bb3;
135 - }
141 + if (c_2) {
142 + y$19 = <div>{x$16}</div>;
143 + $[2] = x$16;
144 + $[3] = y$19;
145 + } else {
146 + y$19 = $[3];
147 + }
148
137 - default: {
138 - x$22 = [];
139 - x$22.push(c$15);
149 + const c_4 = $[4] !== b$14;
150 + const c_5 = $[5] !== c$15;
151 + let x$22;
152 +
153 + if (c_4 || c_5) {
154 + x$22 = undefined;
155 +
156 + bb3: switch (b$14) {
157 + case 0: {
158 + x$22 = [];
159 + x$22.push(b$14);
160 + break bb3;
161 + }
162 +
163 + default: {
164 + x$22 = [];
165 + x$22.push(c$15);
166 + }
167 }
168 +
169 + $[4] = b$14;
170 + $[5] = c$15;
171 + $[6] = x$22;
172 + } else {
173 + x$22 = $[6];
174 }
175
143 - return (
144 - <div>
145 - {y$19}
146 - {x$22}
147 - </div>
148 - );
176 + const c_7 = $[7] !== y$19;
177 + const c_8 = $[8] !== x$22;
178 + let t9$31;
179 +
180 + if (c_7 || c_8) {
181 + t9$31 = (
182 + <div>
183 + {y$19}
184 + {x$22}
185 + </div>
186 + );
187 + $[7] = y$19;
188 + $[8] = x$22;
189 + $[9] = t9$31;
190 + } else {
191 + t9$31 = $[9];
192 + }
193 +
194 + return t9$31;
195 }
196
197 ```
compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md
+50 -10
@@ -27,8 +27,8 @@ bb0:
27 [4] Const mutate x$9_@1 = Array []
28 [5] Const mutate _$10_@2 = JSX <read Component$0 x={freeze x$9_@1} ></read Component$0>
29 [6] Call mutate y$8_@0.push(read props$6.p1)
30 - [7] Const mutate $11_@3 = JSX <read Component$0 x={read x$9_@1} y={freeze y$8_@0:TFunction} ></read Component$0>
31 - [8] Return read $11_@3
30 + [7] Const mutate t7$11_@3 = JSX <read Component$0 x={read x$9_@1} y={freeze y$8_@0:TFunction} ></read Component$0>
31 + [8] Return read t7$11_@3
32 ```
33
34 ## Reactive Scopes
@@ -61,14 +61,54 @@ function Component(
61
62 ```javascript
63 function Component$0(props$6) {
64 - const x$7 = [];
65 - x$7.push(props$6.p0);
66 - const y$8 = x$7;
67 - const x$9 = [];
68 - const _$10 = <Component$0 x={x$9}></Component$0>;
69 -
70 - y$8.push(props$6.p1);
71 - return <Component$0 x={x$9} y={y$8}></Component$0>;
64 + const $ = React.useMemoCache();
65 + const c_0 = $[0] !== props$6.p0;
66 + const c_1 = $[1] !== props$6.p1;
67 + let y$8;
68 + if (c_0 || c_1) {
69 + const x$7 = [];
70 + x$7.push(props$6.p0);
71 + y$8 = x$7;
72 + let x$9;
73 +
74 + if (true) {
75 + x$9 = [];
76 + $[3] = x$9;
77 + } else {
78 + x$9 = $[3];
79 + }
80 +
81 + const c_4 = $[4] !== x$9;
82 +
83 + if (c_4) {
84 + const _$10 = <Component$0 x={x$9}></Component$0>;
85 +
86 + $[4] = x$9;
87 + } else {
88 + }
89 +
90 + y$8.push(props$6.p1);
91 + $[0] = props$6.p0;
92 + $[1] = props$6.p1;
93 + $[2] = y$8;
94 + } else {
95 + y$8 = $[2];
96 + }
97 +
98 + const c_5 = $[5] !== x$9;
99 + const c_6 = $[6] !== y$8;
100 + let t7$11;
101 +
102 + if (c_5 || c_6) {
103 + t7$11 = <Component$0 x={x$9} y={y$8}></Component$0>;
104 + $[5] = x$9;
105 + $[6] = y$8;
106 + $[7] = t7$11;
107 + } else {
108 + t7$11 = $[7];
109 + }
110 +
111 + return t7$11;
112 }
113
114 ```
compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md
+45 -20
@@ -125,33 +125,58 @@ function Component(
125
126 ```javascript
127 function Component$0(props$6) {
128 + const $ = React.useMemoCache();
129 const x$7 = undefined;
129 - let x$11 = undefined;
130 - bb1: if (props$6.cond) {
131 - switch (props$6.test) {
132 - case 0: {
133 - x$11 = props$6.v0;
134 - break bb1;
135 - }
130 + const c_0 = $[0] !== props$6.cond;
131 + const c_1 = $[1] !== props$6.test;
132 + const c_2 = $[2] !== props$6.v0;
133 + const c_3 = $[3] !== props$6.v1;
134 + const c_4 = $[4] !== props$6.v2;
135 + const c_5 = $[5] !== props$6.cond2;
136 + const c_6 = $[6] !== props$6.b;
137 + const c_7 = $[7] !== props$6.c;
138 + let x$11;
139 + if (c_0 || c_1 || c_2 || c_3 || c_4 || c_5 || c_6 || c_7) {
140 + x$11 = undefined;
141
137 - case 1: {
138 - x$11 = props$6.v1;
139 - break bb1;
140 - }
142 + bb1: if (props$6.cond) {
143 + switch (props$6.test) {
144 + case 0: {
145 + x$11 = props$6.v0;
146 + break bb1;
147 + }
148
142 - case 2: {
143 - }
149 + case 1: {
150 + x$11 = props$6.v1;
151 + break bb1;
152 + }
153
145 - default: {
146 - x$11 = props$6.v2;
154 + case 2: {
155 + }
156 +
157 + default: {
158 + x$11 = props$6.v2;
159 + }
160 }
148 - }
149 - } else {
150 - if (props$6.cond2) {
151 - x$11 = props$6.b;
161 } else {
153 - x$11 = props$6.c;
162 + if (props$6.cond2) {
163 + x$11 = props$6.b;
164 + } else {
165 + x$11 = props$6.c;
166 + }
167 }
168 +
169 + $[0] = props$6.cond;
170 + $[1] = props$6.test;
171 + $[2] = props$6.v0;
172 + $[3] = props$6.v1;
173 + $[4] = props$6.v2;
174 + $[5] = props$6.cond2;
175 + $[6] = props$6.b;
176 + $[7] = props$6.c;
177 + $[8] = x$11;
178 + } else {
179 + x$11 = $[8];
180 }
181
182 x$11;
compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md
+20 -7
@@ -78,13 +78,26 @@ function foo(
78
79 ```javascript
80 function foo$0() {
81 - const a$5 = {};
82 - const b$6 = {};
83 - const c$7 = {};
84 - const a$8 = b$6;
85 - const b$9 = c$7;
86 - const c$10 = a$8;
87 - mutate$4(a$8, b$9);
81 + const $ = React.useMemoCache();
82 + if (true) {
83 + const a$5 = {};
84 + } else {
85 + }
86 +
87 + let c$10;
88 +
89 + if (true) {
90 + const b$6 = {};
91 + const c$7 = {};
92 + const a$8 = b$6;
93 + const b$9 = c$7;
94 + c$10 = a$8;
95 + mutate$4(a$8, b$9);
96 + $[0] = c$10;
97 + } else {
98 + c$10 = $[0];
99 + }
100 +
101 return c$10;
102 }
103
compiler/forget/src/__tests__/fixtures/hir/simple.expect.md
+28 -6
@@ -19,14 +19,14 @@ bb0:
19 bb2:
20 predecessor blocks: bb0
21 [2] Const mutate $10:TPrimitive = false
22 - [3] Const mutate $11_@0 = Call read foo$0:TFunction(read $10:TPrimitive, read y$9:TPrimitive)
23 - [4] Return freeze $11_@0
22 + [3] Const mutate t1$11_@0 = Call read foo$0:TFunction(read $10:TPrimitive, read y$9:TPrimitive)
23 + [4] Return freeze t1$11_@0
24 bb1:
25 predecessor blocks: bb0
26 [5] Const mutate $12:TPrimitive = 10
27 [6] Const mutate $13:TPrimitive = Binary read y$9:TPrimitive * read $12:TPrimitive
28 - [7] Const mutate $14_@1 = Array [read $13:TPrimitive]
29 - [8] Return freeze $14_@1
28 + [7] Const mutate t2$14_@1 = Array [read $13:TPrimitive]
29 + [8] Return freeze t2$14_@1
30 ```
31
32 ## Reactive Scopes
@@ -57,10 +57,32 @@ function foo(
57
58 ```javascript
59 function foo$0(x$8, y$9) {
60 + const $ = React.useMemoCache();
61 bb1: if (x$8) {
61 - return foo$0(false, y$9);
62 + const c_0 = $[0] !== y$9;
63 + let t1$11;
64 +
65 + if (c_0) {
66 + t1$11 = foo$0(false, y$9);
67 + $[0] = y$9;
68 + $[1] = t1$11;
69 + } else {
70 + t1$11 = $[1];
71 + }
72 +
73 + return t1$11;
74 }
63 - return [y$9 * 10];
75 +
76 + let t2$14;
77 +
78 + if (true) {
79 + t2$14 = [y$9 * 10];
80 + $[2] = t2$14;
81 + } else {
82 + t2$14 = $[2];
83 + }
84 +
85 + return t2$14;
86 }
87
88 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md
+9 -1
@@ -41,9 +41,17 @@ function Component(
41
42 ```javascript
43 function Component$0(props$5) {
44 + const $ = React.useMemoCache();
45 const a$6 = 1;
46 const b$7 = 2;
46 - const x$8 = [a$6, b$7];
47 + let x$8;
48 + if (true) {
49 + x$8 = [a$6, b$7];
50 + $[0] = x$8;
51 + } else {
52 + x$8 = $[0];
53 + }
54 +
55 return x$8;
56 }
57
compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md
+45 -9
@@ -59,8 +59,8 @@ bb1:
59 predecessor blocks: bb2 bb0
60 [9] Call mutate foo$4:TFunction(read a$11_@0, mutate b$12_@0:TObject)
61 [10] Const mutate $19:TPrimitive = "div"
62 - [11] Const mutate $20_@3 = JSX <read $19:TPrimitive a={freeze a$11_@0} b={freeze b$12_@0:TObject} ></read $19:TPrimitive>
63 - [12] Return read $20_@3
62 + [11] Const mutate t5$20_@3 = JSX <read $19:TPrimitive a={freeze a$11_@0} b={freeze b$12_@0:TObject} ></read $19:TPrimitive>
63 + [12] Return read t5$20_@3
64 ```
65
66 ## Reactive Scopes
@@ -97,15 +97,51 @@ function Component(
97
98 ```javascript
99 function Component$0(props$10) {
100 - const a$11 = [];
101 - const b$12 = {};
102 - foo$4(a$11, b$12);
103 - bb1: if (foo$4()) {
104 - const _$15 = <div a={a$11}></div>;
100 + const $ = React.useMemoCache();
101 + let a$11;
102 + let b$12;
103 + if (true) {
104 + a$11 = [];
105 + b$12 = {};
106 + foo$4(a$11, b$12);
107 +
108 + if (true) {
109 + } else {
110 + }
111 +
112 + bb1: if (foo$4()) {
113 + const c_2 = $[2] !== a$11;
114 +
115 + if (c_2) {
116 + const _$15 = <div a={a$11}></div>;
117 +
118 + $[2] = a$11;
119 + } else {
120 + }
121 + }
122 +
123 + foo$4(a$11, b$12);
124 + $[0] = a$11;
125 + $[1] = b$12;
126 + } else {
127 + a$11 = $[0];
128 + b$12 = $[1];
129 + }
130 +
131 + const c_3 = $[3] !== a$11;
132 + const c_4 = $[4] !== b$12;
133 + let t5$20;
134 +
135 + if (c_3 || c_4) {
136 + t5$20 = <div a={a$11} b={b$12}></div>;
137 + $[3] = a$11;
138 + $[4] = b$12;
139 + $[5] = t5$20;
140 + } else {
141 + t5$20 = $[5];
142 }
143
107 - foo$4(a$11, b$12);
108 - return <div a={a$11} b={b$12}></div>;
144 + return t5$20;
145 }
146
147 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md
+39 -8
@@ -49,8 +49,8 @@ bb0:
49 [5] Const mutate _$13_@1 = JSX <read $12:TPrimitive a={freeze a$10_@0} ></read $12:TPrimitive>
50 [6] Call mutate foo$4:TFunction(read a$10_@0, mutate b$11_@0:TObject)
51 [7] Const mutate $14:TPrimitive = "div"
52 - [8] Const mutate $15_@2 = JSX <read $14:TPrimitive a={read a$10_@0} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
53 - [9] Return read $15_@2
52 + [8] Const mutate t5$15_@2 = JSX <read $14:TPrimitive a={read a$10_@0} b={freeze b$11_@0:TObject} ></read $14:TPrimitive>
53 + [9] Return read t5$15_@2
54 ```
55
56 ## Reactive Scopes
@@ -82,13 +82,44 @@ function Component(
82
83 ```javascript
84 function Component$0(props$9) {
85 - const a$10 = [];
86 - const b$11 = {};
87 - foo$4(a$10, b$11);
88 - const _$13 = <div a={a$10}></div>;
85 + const $ = React.useMemoCache();
86 + let a$10;
87 + let b$11;
88 + if (true) {
89 + a$10 = [];
90 + b$11 = {};
91 + foo$4(a$10, b$11);
92 + const c_2 = $[2] !== a$10;
93 +
94 + if (c_2) {
95 + const _$13 = <div a={a$10}></div>;
96 +
97 + $[2] = a$10;
98 + } else {
99 + }
100 +
101 + foo$4(a$10, b$11);
102 + $[0] = a$10;
103 + $[1] = b$11;
104 + } else {
105 + a$10 = $[0];
106 + b$11 = $[1];
107 + }
108 +
109 + const c_3 = $[3] !== a$10;
110 + const c_4 = $[4] !== b$11;
111 + let t5$15;
112 +
113 + if (c_3 || c_4) {
114 + t5$15 = <div a={a$10} b={b$11}></div>;
115 + $[3] = a$10;
116 + $[4] = b$11;
117 + $[5] = t5$15;
118 + } else {
119 + t5$15 = $[5];
120 + }
121
90 - foo$4(a$10, b$11);
91 - return <div a={a$10} b={b$11}></div>;
122 + return t5$15;
123 }
124
125 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md
+16 -7
@@ -74,14 +74,23 @@ function foo(
74
75 ```javascript
76 function foo$0() {
77 - let x$7 = 1;
78 - const y$8 = 2;
79 - bb1: if (y$8 === 2) {
80 - x$7 = 3;
81 - }
77 + const $ = React.useMemoCache();
78 + let x$7;
79 + if (true) {
80 + x$7 = 1;
81 + const y$8 = 2;
82 +
83 + bb1: if (y$8 === 2) {
84 + x$7 = 3;
85 + }
86 +
87 + bb3: if (y$8 === 3) {
88 + x$7 = 5;
89 + }
90
83 - bb3: if (y$8 === 3) {
84 - x$7 = 5;
91 + $[0] = x$7;
92 + } else {
93 + x$7 = $[0];
94 }
95
96 const y$18 = x$7;
compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md
+13 -4
@@ -57,10 +57,19 @@ function foo(
57
58 ```javascript
59 function foo$0() {
60 - let x$5 = 1;
61 - const y$6 = 2;
62 - bb1: if (y$6 === 2) {
63 - x$5 = 3;
60 + const $ = React.useMemoCache();
61 + let x$5;
62 + if (true) {
63 + x$5 = 1;
64 + const y$6 = 2;
65 +
66 + bb1: if (y$6 === 2) {
67 + x$5 = 3;
68 + }
69 +
70 + $[0] = x$5;
71 + } else {
72 + x$5 = $[0];
73 }
74
75 const y$11 = x$5;
compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md
+4 -1
@@ -57,7 +57,10 @@ function foo(
57
58 ```javascript
59 function foo$0(cond$4) {
60 - const items$5 = [];
60 + if (true) {
61 + const items$5 = [];
62 + } else {
63 + }
64 }
65
66 ```
compiler/forget/src/__tests__/fixtures/hir/ssa-for-trivial-update.expect.md
+12 -3
@@ -70,9 +70,18 @@ function foo(
70
71 ```javascript
72 function foo$0() {
73 - let x$6 = 1;
74 - bb2: for (const i$7 = 0; i$7 < 10; i$7) {
75 - x$6 = x$6 + 1;
73 + const $ = React.useMemoCache();
74 + let x$6;
75 + if (true) {
76 + x$6 = 1;
77 +
78 + bb2: for (const i$7 = 0; i$7 < 10; i$7) {
79 + x$6 = x$6 + 1;
80 + }
81 +
82 + $[0] = x$6;
83 + } else {
84 + x$6 = $[0];
85 }
86
87 return x$6;
compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md
+12 -3
@@ -74,9 +74,18 @@ function foo(
74
75 ```javascript
76 function foo$0() {
77 - let x$7 = 1;
78 - bb2: for (let i$8 = 0; i$8 < 10; i$8 = i$8 + 1, i$8) {
79 - x$7 = x$7 + 1;
77 + const $ = React.useMemoCache();
78 + let x$7;
79 + if (true) {
80 + x$7 = 1;
81 +
82 + bb2: for (let i$8 = 0; i$8 < 10; i$8 = i$8 + 1, i$8) {
83 + x$7 = x$7 + 1;
84 + }
85 +
86 + $[0] = x$7;
87 + } else {
88 + x$7 = $[0];
89 }
90
91 return x$7;
compiler/forget/src/__tests__/fixtures/hir/ssa-multiple-phis.expect.md
+30 -13
@@ -109,24 +109,41 @@ function foo(
109
110 ```javascript
111 function foo$0(a$9, b$10, c$11, d$12) {
112 + const $ = React.useMemoCache();
113 const x$13 = 0;
113 - let x$18 = undefined;
114 - bb1: if (true) {
115 - bb3: if (true) {
116 - x$18 = a$9;
117 - } else {
118 - x$18 = b$10;
119 - }
114 + const c_0 = $[0] !== a$9;
115 + const c_1 = $[1] !== b$10;
116 + const c_2 = $[2] !== c$11;
117 + const c_3 = $[3] !== d$12;
118 + let x$18;
119 + if (c_0 || c_1 || c_2 || c_3) {
120 + x$18 = undefined;
121
121 - x$18;
122 - } else {
123 - bb7: if (true) {
124 - x$18 = c$11;
122 + bb1: if (true) {
123 + bb3: if (true) {
124 + x$18 = a$9;
125 + } else {
126 + x$18 = b$10;
127 + }
128 +
129 + x$18;
130 } else {
126 - x$18 = d$12;
131 + bb7: if (true) {
132 + x$18 = c$11;
133 + } else {
134 + x$18 = d$12;
135 + }
136 +
137 + x$18;
138 }
139
129 - x$18;
140 + $[0] = a$9;
141 + $[1] = b$10;
142 + $[2] = c$11;
143 + $[3] = d$12;
144 + $[4] = x$18;
145 + } else {
146 + x$18 = $[4];
147 }
148
149 return x$18;
compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-phi.expect.md
+17 -5
@@ -62,13 +62,25 @@ function foo(
62
63 ```javascript
64 function foo$0(a$5, b$6, c$7) {
65 - const x$8 = a$5;
66 - bb1: if (b$6) {
67 - bb3: if (c$7) {
68 - x$8 = c$7;
65 + const $ = React.useMemoCache();
66 + const c_0 = $[0] !== a$5;
67 + const c_1 = $[1] !== b$6;
68 + const c_2 = $[2] !== c$7;
69 + if (c_0 || c_1 || c_2) {
70 + const x$8 = a$5;
71 +
72 + bb1: if (b$6) {
73 + bb3: if (c$7) {
74 + x$8 = c$7;
75 + }
76 +
77 + x$8;
78 }
79
71 - x$8;
80 + $[0] = a$5;
81 + $[1] = b$6;
82 + $[2] = c$7;
83 + } else {
84 }
85 }
86
compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-reassignment.expect.md
+23 -6
@@ -67,13 +67,30 @@ function foo(
67
68 ```javascript
69 function foo$0(a$7, b$8, c$9, d$10, e$11) {
70 - let x$12 = null;
71 - bb1: if (a$7) {
72 - x$12 = b$8;
73 - } else {
74 - if (c$9) {
75 - x$12 = d$10;
70 + const $ = React.useMemoCache();
71 + const c_0 = $[0] !== a$7;
72 + const c_1 = $[1] !== b$8;
73 + const c_2 = $[2] !== c$9;
74 + const c_3 = $[3] !== d$10;
75 + let x$12;
76 + if (c_0 || c_1 || c_2 || c_3) {
77 + x$12 = null;
78 +
79 + bb1: if (a$7) {
80 + x$12 = b$8;
81 + } else {
82 + if (c$9) {
83 + x$12 = d$10;
84 + }
85 }
86 +
87 + $[0] = a$7;
88 + $[1] = b$8;
89 + $[2] = c$9;
90 + $[3] = d$10;
91 + $[4] = x$12;
92 + } else {
93 + x$12 = $[4];
94 }
95
96 return x$12;
compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md
+11 -3
@@ -66,9 +66,17 @@ function Component(
66
67 ```javascript
68 function Component$0(props$6) {
69 - const a$7 = [];
70 - const b$8 = {};
71 - const c$9 = new Foo$5(a$7, b$8);
69 + const $ = React.useMemoCache();
70 + let c$9;
71 + if (true) {
72 + const a$7 = [];
73 + const b$8 = {};
74 + c$9 = new Foo$5(a$7, b$8);
75 + $[0] = c$9;
76 + } else {
77 + c$9 = $[0];
78 + }
79 +
80 return c$9;
81 }
82
compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md
+30 -9
@@ -69,18 +69,39 @@ function foo(
69
70 ```javascript
71 function foo$0() {
72 - let x$6 = 1;
73 - let y$7 = 2;
74 - bb1: if (x$6 > 1) {
75 - x$6 = 2;
72 + const $ = React.useMemoCache();
73 + let x$6;
74 + if (true) {
75 + x$6 = 1;
76 + let y$7 = 2;
77 +
78 + bb1: if (x$6 > 1) {
79 + x$6 = 2;
80 + } else {
81 + y$7 = 3;
82 + }
83 +
84 + $[0] = x$6;
85 + } else {
86 + x$6 = $[0];
87 + }
88 +
89 + const c_1 = $[1] !== x$6;
90 + const c_2 = $[2] !== y$7;
91 + let t$14;
92 +
93 + if (c_1 || c_2) {
94 + t$14 = {
95 + x: x$6,
96 + y: y$7,
97 + };
98 + $[1] = x$6;
99 + $[2] = y$7;
100 + $[3] = t$14;
101 } else {
77 - y$7 = 3;
102 + t$14 = $[3];
103 }
104
80 - const t$14 = {
81 - x: x$6,
82 - y: y$7,
83 - };
105 return t$14;
106 }
107
compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md
+12 -4
@@ -41,12 +41,20 @@ function Component(
41
42 ```javascript
43 function Component$0(props$5) {
44 + const $ = React.useMemoCache();
45 const a$6 = 1;
46 const b$7 = 2;
46 - const x$8 = {
47 - a: a$6,
48 - b: b$7,
49 - };
47 + let x$8;
48 + if (true) {
49 + x$8 = {
50 + a: a$6,
51 + b: b$7,
52 + };
53 + $[0] = x$8;
54 + } else {
55 + x$8 = $[0];
56 + }
57 +
58 return x$8;
59 }
60
compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-alias-mutate-if.expect.md
+19 -8
@@ -68,17 +68,28 @@ function foo(
68
69 ```javascript
70 function foo$0(a$7) {
71 - const b$8 = {};
72 - const x$9 = b$8;
73 - bb1: if (a$7) {
74 - const y$10 = {};
75 - x$9.y = y$10;
71 + const $ = React.useMemoCache();
72 + const c_0 = $[0] !== a$7;
73 + let x$9;
74 + if (c_0) {
75 + const b$8 = {};
76 + x$9 = b$8;
77 +
78 + bb1: if (a$7) {
79 + const y$10 = {};
80 + x$9.y = y$10;
81 + } else {
82 + const z$11 = {};
83 + x$9.z = z$11;
84 + }
85 +
86 + mutate$6(b$8);
87 + $[0] = a$7;
88 + $[1] = x$9;
89 } else {
77 - const z$11 = {};
78 - x$9.z = z$11;
90 + x$9 = $[1];
91 }
92
81 - mutate$6(b$8);
93 return x$9;
94 }
95
compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md
+25 -6
@@ -66,13 +66,32 @@ function foo(
66
67 ```javascript
68 function foo$0(a$5) {
69 - const x$6 = {};
70 - bb1: if (a$5) {
71 - const y$7 = {};
72 - x$6.y = y$7;
69 + const $ = React.useMemoCache();
70 + const c_0 = $[0] !== a$5;
71 + let x$6;
72 + if (c_0) {
73 + x$6 = {};
74 +
75 + bb1: if (a$5) {
76 + if (true) {
77 + const y$7 = {};
78 + } else {
79 + }
80 +
81 + x$6.y = y$7;
82 + } else {
83 + if (true) {
84 + const z$8 = {};
85 + } else {
86 + }
87 +
88 + x$6.z = z$8;
89 + }
90 +
91 + $[0] = a$5;
92 + $[1] = x$6;
93 } else {
74 - const z$8 = {};
75 - x$6.z = z$8;
94 + x$6 = $[1];
95 }
96
97 return x$6;
compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-if.expect.md
+18 -7
@@ -65,16 +65,27 @@ function foo(
65
66 ```javascript
67 function foo$0(a$6) {
68 - const x$7 = {};
69 - bb1: if (a$6) {
70 - const y$8 = {};
71 - x$7.y = y$8;
68 + const $ = React.useMemoCache();
69 + const c_0 = $[0] !== a$6;
70 + let x$7;
71 + if (c_0) {
72 + x$7 = {};
73 +
74 + bb1: if (a$6) {
75 + const y$8 = {};
76 + x$7.y = y$8;
77 + } else {
78 + const z$9 = {};
79 + x$7.z = z$9;
80 + }
81 +
82 + mutate$5(x$7);
83 + $[0] = a$6;
84 + $[1] = x$7;
85 } else {
73 - const z$9 = {};
74 - x$7.z = z$9;
86 + x$7 = $[1];
87 }
88
77 - mutate$5(x$7);
89 return x$7;
90 }
91
compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md
+22 -7
@@ -67,14 +67,29 @@ function foo(
67
68 ```javascript
69 function foo$0(a$6) {
70 - const x$7 = {};
71 - bb1: if (a$6) {
72 - const y$8 = {};
73 - x$7.y = y$8;
74 - mutate$4(y$8);
70 + const $ = React.useMemoCache();
71 + const c_0 = $[0] !== a$6;
72 + let x$7;
73 + if (c_0) {
74 + x$7 = {};
75 +
76 + bb1: if (a$6) {
77 + const y$8 = {};
78 + x$7.y = y$8;
79 + mutate$4(y$8);
80 + } else {
81 + if (true) {
82 + const z$9 = {};
83 + } else {
84 + }
85 +
86 + x$7.z = z$9;
87 + }
88 +
89 + $[0] = a$6;
90 + $[1] = x$7;
91 } else {
76 - const z$9 = {};
77 - x$7.z = z$9;
92 + x$7 = $[1];
93 }
94
95 return x$7;
compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate.expect.md
+13 -5
@@ -48,11 +48,19 @@ function foo(
48
49 ```javascript
50 function foo$0() {
51 - const a$5 = {};
52 - const x$6 = a$5;
53 - const y$7 = {};
54 - y$7.x = x$6;
55 - mutate$4(a$5);
51 + const $ = React.useMemoCache();
52 + let y$7;
53 + if (true) {
54 + const a$5 = {};
55 + const x$6 = a$5;
56 + y$7 = {};
57 + y$7.x = x$6;
58 + mutate$4(a$5);
59 + $[0] = y$7;
60 + } else {
61 + y$7 = $[0];
62 + }
63 +
64 return y$7;
65 }
66
compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md
+23 -5
@@ -44,11 +44,29 @@ function foo(
44
45 ```javascript
46 function foo$0() {
47 - const x$4 = [];
48 - const y$5 = {
49 - x: x$4,
50 - };
51 - y$5.x.push([]);
47 + const $ = React.useMemoCache();
48 + let x$4;
49 + if (true) {
50 + x$4 = [];
51 + $[0] = x$4;
52 + } else {
53 + x$4 = $[0];
54 + }
55 +
56 + const c_1 = $[1] !== x$4;
57 + let y$5;
58 +
59 + if (c_1) {
60 + y$5 = {
61 + x: x$4,
62 + };
63 + y$5.x.push([]);
64 + $[1] = x$4;
65 + $[2] = y$5;
66 + } else {
67 + y$5 = $[2];
68 + }
69 +
70 return y$5;
71 }
72
compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-2.expect.md
+12 -4
@@ -43,10 +43,18 @@ function foo(
43
44 ```javascript
45 function foo$0() {
46 - const x$4 = [];
47 - const y$5 = {};
48 - y$5.x = x$4;
49 - mutate$3(x$4);
46 + const $ = React.useMemoCache();
47 + let y$5;
48 + if (true) {
49 + const x$4 = [];
50 + y$5 = {};
51 + y$5.x = x$4;
52 + mutate$3(x$4);
53 + $[0] = y$5;
54 + } else {
55 + y$5 = $[0];
56 + }
57 +
58 return y$5;
59 }
60
compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-alias.expect.md
+13 -5
@@ -48,11 +48,19 @@ function foo(
48
49 ```javascript
50 function foo$0() {
51 - const a$5 = {};
52 - const y$6 = a$5;
53 - const x$7 = [];
54 - y$6.x = x$7;
55 - mutate$4(a$5);
51 + const $ = React.useMemoCache();
52 + let y$6;
53 + if (true) {
54 + const a$5 = {};
55 + y$6 = a$5;
56 + const x$7 = [];
57 + y$6.x = x$7;
58 + mutate$4(a$5);
59 + $[0] = y$6;
60 + } else {
61 + y$6 = $[0];
62 + }
63 +
64 return y$6;
65 }
66
compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate.expect.md
+12 -4
@@ -43,10 +43,18 @@ function foo(
43
44 ```javascript
45 function foo$0() {
46 - const x$4 = [];
47 - const y$5 = {};
48 - y$5.x = x$4;
49 - mutate$3(y$5);
46 + const $ = React.useMemoCache();
47 + let y$5;
48 + if (true) {
49 + const x$4 = [];
50 + y$5 = {};
51 + y$5.x = x$4;
52 + mutate$3(y$5);
53 + $[0] = y$5;
54 + } else {
55 + y$5 = $[0];
56 + }
57 +
58 return y$5;
59 }
60
compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md
+21 -3
@@ -42,9 +42,27 @@ function foo(
42
43 ```javascript
44 function foo$0() {
45 - const x$3 = [];
46 - const y$4 = {};
47 - y$4.x = x$3;
45 + const $ = React.useMemoCache();
46 + let x$3;
47 + if (true) {
48 + x$3 = [];
49 + $[0] = x$3;
50 + } else {
51 + x$3 = $[0];
52 + }
53 +
54 + const c_1 = $[1] !== x$3;
55 + let y$4;
56 +
57 + if (c_1) {
58 + y$4 = {};
59 + y$4.x = x$3;
60 + $[1] = x$3;
61 + $[2] = y$4;
62 + } else {
63 + y$4 = $[2];
64 + }
65 +
66 return y$4;
67 }
68
compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md
+12 -3
@@ -52,9 +52,18 @@ function foo(
52
53 ```javascript
54 function foo$0() {
55 - let x$4 = 1;
56 - bb1: if (x$4 === 1) {
57 - x$4 = 2;
55 + const $ = React.useMemoCache();
56 + let x$4;
57 + if (true) {
58 + x$4 = 1;
59 +
60 + bb1: if (x$4 === 1) {
61 + x$4 = 2;
62 + }
63 +
64 + $[0] = x$4;
65 + } else {
66 + x$4 = $[0];
67 }
68
69 return x$4;
compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md
+16 -5
@@ -86,12 +86,23 @@ function Foo(
86
87 ```javascript
88 function Foo$0(cond$5) {
89 - let str$6 = "";
90 - bb1: if (cond$5) {
91 - const str$7 = "other test";
92 - log$4(str$7);
89 + const $ = React.useMemoCache();
90 + const c_0 = $[0] !== cond$5;
91 + let str$6;
92 + if (c_0) {
93 + str$6 = "";
94 +
95 + bb1: if (cond$5) {
96 + const str$7 = "other test";
97 + log$4(str$7);
98 + } else {
99 + str$6 = "fallthrough test";
100 + }
101 +
102 + $[0] = cond$5;
103 + $[1] = str$6;
104 } else {
94 - str$6 = "fallthrough test";
105 + str$6 = $[1];
106 }
107
108 log$4(str$6);
compiler/forget/src/__tests__/fixtures/hir/ssa-sibling-phis.expect.md
+33 -8
@@ -113,24 +113,49 @@ function foo(
113
114 ```javascript
115 function foo$0(a$9, b$10, c$11, d$12) {
116 + const $ = React.useMemoCache();
117 const x$13 = 0;
118 bb1: if (true) {
118 - let x$16 = undefined;
119 + const c_0 = $[0] !== a$9;
120 + const c_1 = $[1] !== b$10;
121 + let x$16;
122
120 - bb3: if (true) {
121 - x$16 = a$9;
123 + if (c_0 || c_1) {
124 + x$16 = undefined;
125 +
126 + bb3: if (true) {
127 + x$16 = a$9;
128 + } else {
129 + x$16 = b$10;
130 + }
131 +
132 + $[0] = a$9;
133 + $[1] = b$10;
134 + $[2] = x$16;
135 } else {
123 - x$16 = b$10;
136 + x$16 = $[2];
137 }
138
139 x$16;
140 } else {
128 - let x$20 = undefined;
141 + const c_3 = $[3] !== c$11;
142 + const c_4 = $[4] !== d$12;
143 + let x$20;
144 +
145 + if (c_3 || c_4) {
146 + x$20 = undefined;
147 +
148 + bb7: if (true) {
149 + x$20 = c$11;
150 + } else {
151 + x$20 = d$12;
152 + }
153
130 - bb7: if (true) {
131 - x$20 = c$11;
154 + $[3] = c$11;
155 + $[4] = d$12;
156 + $[5] = x$20;
157 } else {
133 - x$20 = d$12;
158 + x$20 = $[5];
159 }
160
161 x$20;
compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md
+13 -4
@@ -65,12 +65,21 @@ function foo(
65
66 ```javascript
67 function foo$0() {
68 + const $ = React.useMemoCache();
69 const y$5 = 2;
69 - let y$8 = undefined;
70 - bb1: if (y$5 > 1) {
71 - y$8 = 1;
70 + let y$8;
71 + if (true) {
72 + y$8 = undefined;
73 +
74 + bb1: if (y$5 > 1) {
75 + y$8 = 1;
76 + } else {
77 + y$8 = 2;
78 + }
79 +
80 + $[0] = y$8;
81 } else {
73 - y$8 = 2;
82 + y$8 = $[0];
83 }
84
85 const x$11 = y$8;
compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md
+21 -12
@@ -99,22 +99,31 @@ function foo(
99
100 ```javascript
101 function foo$0() {
102 + const $ = React.useMemoCache();
103 const x$10 = 1;
103 - let x$16 = undefined;
104 - bb1: switch (x$10) {
105 - case x$10 === 1: {
106 - x$16 = x$10 + 1;
107 - break bb1;
108 - }
104 + let x$16;
105 + if (true) {
106 + x$16 = undefined;
107 +
108 + bb1: switch (x$10) {
109 + case x$10 === 1: {
110 + x$16 = x$10 + 1;
111 + break bb1;
112 + }
113
110 - case x$10 === 2: {
111 - x$16 = x$10 + 2;
112 - break bb1;
113 - }
114 + case x$10 === 2: {
115 + x$16 = x$10 + 2;
116 + break bb1;
117 + }
118
115 - default: {
116 - x$16 = x$10 + 3;
119 + default: {
120 + x$16 = x$10 + 3;
121 + }
122 }
123 +
124 + $[0] = x$16;
125 + } else {
126 + x$16 = $[0];
127 }
128
129 const y$22 = x$16;
compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md
+12 -3
@@ -51,9 +51,18 @@ function foo(
51
52 ```javascript
53 function foo$0() {
54 - let x$4 = 1;
55 - bb1: if (x$4 === 1) {
56 - x$4 = 2;
54 + const $ = React.useMemoCache();
55 + let x$4;
56 + if (true) {
57 + x$4 = 1;
58 +
59 + bb1: if (x$4 === 1) {
60 + x$4 = 2;
61 + }
62 +
63 + $[0] = x$4;
64 + } else {
65 + x$4 = $[0];
66 }
67
68 throw x$4;
compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md
+12 -3
@@ -59,9 +59,18 @@ function foo(
59
60 ```javascript
61 function foo$0() {
62 - let x$5 = 1;
63 - bb2: while (x$5 < 10) {
64 - x$5 = x$5 + 1;
62 + const $ = React.useMemoCache();
63 + let x$5;
64 + if (true) {
65 + x$5 = 1;
66 +
67 + bb2: while (x$5 < 10) {
68 + x$5 = x$5 + 1;
69 + }
70 +
71 + $[0] = x$5;
72 + } else {
73 + x$5 = $[0];
74 }
75
76 return x$5;
compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md
+56 -20
@@ -56,8 +56,8 @@ bb1:
56 predecessor blocks: bb0 bb6 bb2
57 [12] Const mutate child$19_@2 = JSX <read Component$0 data={freeze x$10_@1:TFunction} ></read Component$0>
58 [13] Call read y$11_@1.push(read props$9.p4)
59 - [14] Const mutate $22_@3 = JSX <read Component$0 data={freeze y$11_@1:TPrimitive} >{read child$19_@2}</read Component$0>
60 - [15] Return read $22_@3
59 + [14] Const mutate t7$22_@3 = JSX <read Component$0 data={freeze y$11_@1:TPrimitive} >{read child$19_@2}</read Component$0>
60 + [15] Return read t7$22_@3
61 ```
62
63 ## Reactive Scopes
@@ -105,31 +105,67 @@ function Component(
105
106 ```javascript
107 function Component$0(props$9) {
108 - const x$10 = [];
109 - let y$11 = undefined;
110 - bb1: switch (props$9.p0) {
111 - case 1: {
112 - break bb1;
113 - }
108 + const $ = React.useMemoCache();
109 + const c_0 = $[0] !== props$9.p0;
110 + const c_1 = $[1] !== props$9.p2;
111 + let x$10;
112 + if (c_0 || c_1) {
113 + x$10 = [];
114 + let y$11 = undefined;
115
115 - case true: {
116 - x$10.push(props$9.p2);
117 - y$11 = [];
118 - break bb1;
119 - }
116 + bb1: switch (props$9.p0) {
117 + case 1: {
118 + break bb1;
119 + }
120
121 - default: {
122 - break bb1;
123 - }
121 + case true: {
122 + x$10.push(props$9.p2);
123 + y$11 = [];
124 + break bb1;
125 + }
126
125 - case false: {
126 - y$11 = x$10;
127 + default: {
128 + break bb1;
129 + }
130 +
131 + case false: {
132 + y$11 = x$10;
133 + }
134 }
135 +
136 + $[0] = props$9.p0;
137 + $[1] = props$9.p2;
138 + $[2] = x$10;
139 + } else {
140 + x$10 = $[2];
141 + }
142 +
143 + const c_3 = $[3] !== x$10;
144 + let child$19;
145 +
146 + if (c_3) {
147 + child$19 = <Component$0 data={x$10}></Component$0>;
148 + $[3] = x$10;
149 + $[4] = child$19;
150 + } else {
151 + child$19 = $[4];
152 }
153
130 - const child$19 = <Component$0 data={x$10}></Component$0>;
154 y$11.push(props$9.p4);
132 - return <Component$0 data={y$11}>{child$19}</Component$0>;
155 + const c_5 = $[5] !== y$11;
156 + const c_6 = $[6] !== child$19;
157 + let t7$22;
158 +
159 + if (c_5 || c_6) {
160 + t7$22 = <Component$0 data={y$11}>{child$19}</Component$0>;
161 + $[5] = y$11;
162 + $[6] = child$19;
163 + $[7] = t7$22;
164 + } else {
165 + t7$22 = $[7];
166 + }
167 +
168 + return t7$22;
169 }
170
171 ```
compiler/forget/src/__tests__/fixtures/hir/switch.expect.md
+56 -14
@@ -50,8 +50,8 @@ bb1:
50 predecessor blocks: bb2 bb0
51 [12] Const mutate child$19_@3 = JSX <read Component$0 data={freeze x$9_@1:TFunction} ></read Component$0>
52 [13] Call read y$10_@1.push(read props$8.p4)
53 - [14] Const mutate $23_@4 = JSX <read Component$0 data={read y$10_@1:TPrimitive} >{read child$19_@3}</read Component$0>
54 - [15] Return read $23_@4
53 + [14] Const mutate t8$23_@4 = JSX <read Component$0 data={read y$10_@1:TPrimitive} >{read child$19_@3}</read Component$0>
54 + [15] Return read t8$23_@4
55 ```
56
57 ## Reactive Scopes
@@ -94,23 +94,65 @@ function Component(
94
95 ```javascript
96 function Component$0(props$8) {
97 - const x$9 = [];
98 - let y$10 = undefined;
99 - bb1: switch (props$8.p0) {
100 - case true: {
101 - x$9.push(props$8.p2);
102 - x$9.push(props$8.p3);
103 - const y$13 = [];
104 - }
97 + const $ = React.useMemoCache();
98 + const c_0 = $[0] !== props$8.p0;
99 + const c_1 = $[1] !== props$8.p2;
100 + const c_2 = $[2] !== props$8.p3;
101 + let x$9;
102 + if (c_0 || c_1 || c_2) {
103 + x$9 = [];
104 + let y$10 = undefined;
105
106 - case false: {
107 - y$10 = x$9;
106 + bb1: switch (props$8.p0) {
107 + case true: {
108 + x$9.push(props$8.p2);
109 + x$9.push(props$8.p3);
110 +
111 + if (true) {
112 + const y$13 = [];
113 + } else {
114 + }
115 + }
116 +
117 + case false: {
118 + y$10 = x$9;
119 + }
120 }
121 +
122 + $[0] = props$8.p0;
123 + $[1] = props$8.p2;
124 + $[2] = props$8.p3;
125 + $[3] = x$9;
126 + } else {
127 + x$9 = $[3];
128 + }
129 +
130 + const c_4 = $[4] !== x$9;
131 + let child$19;
132 +
133 + if (c_4) {
134 + child$19 = <Component$0 data={x$9}></Component$0>;
135 + $[4] = x$9;
136 + $[5] = child$19;
137 + } else {
138 + child$19 = $[5];
139 }
140
111 - const child$19 = <Component$0 data={x$9}></Component$0>;
141 y$10.push(props$8.p4);
113 - return <Component$0 data={y$10}>{child$19}</Component$0>;
142 + const c_6 = $[6] !== y$10;
143 + const c_7 = $[7] !== child$19;
144 + let t8$23;
145 +
146 + if (c_6 || c_7) {
147 + t8$23 = <Component$0 data={y$10}>{child$19}</Component$0>;
148 + $[6] = y$10;
149 + $[7] = child$19;
150 + $[8] = t8$23;
151 + } else {
152 + t8$23 = $[8];
153 + }
154 +
155 + return t8$23;
156 }
157
158 ```
compiler/forget/src/__tests__/fixtures/hir/transitive-alias-fields.expect.md
+11 -8
@@ -56,14 +56,17 @@ function component(
56
57 ```javascript
58 function component$0() {
59 - const x$6 = {};
60 - const p$7 = {};
61 - const q$8 = {};
62 - const y$9 = {};
63 - x$6.y = y$9;
64 - p$7.y = x$6.y;
65 - q$8.y = p$7.y;
66 - mutate$5(q$8);
59 + if (true) {
60 + const x$6 = {};
61 + const p$7 = {};
62 + const q$8 = {};
63 + const y$9 = {};
64 + x$6.y = y$9;
65 + p$7.y = x$6.y;
66 + q$8.y = p$7.y;
67 + mutate$5(q$8);
68 + } else {
69 + }
70 }
71
72 ```
compiler/forget/src/__tests__/fixtures/hir/type-args-test-binary-operator.expect.md
+4 -1
@@ -48,7 +48,10 @@ function component(
48 ```javascript
49 function component$0(a$5, b$6) {
50 bb1: if (a$5 > b$6) {
51 - const m$8 = {};
51 + if (true) {
52 + const m$8 = {};
53 + } else {
54 + }
55 }
56 }
57
compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md
+22 -3
@@ -55,10 +55,29 @@ function component(
55
56 ```javascript
57 function component$0() {
58 - const a$7 = some$2();
59 - const b$8 = someOther$4();
58 + const $ = React.useMemoCache();
59 + let a$7;
60 + if (true) {
61 + a$7 = some$2();
62 + $[0] = a$7;
63 + } else {
64 + a$7 = $[0];
65 + }
66 +
67 + let b$8;
68 +
69 + if (true) {
70 + b$8 = someOther$4();
71 + $[1] = b$8;
72 + } else {
73 + b$8 = $[1];
74 + }
75 +
76 bb1: if (a$7 > b$8) {
61 - const m$10 = {};
77 + if (true) {
78 + const m$10 = {};
79 + } else {
80 + }
81 }
82 }
83
compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md
+11 -3
@@ -38,9 +38,17 @@ function component(
38
39 ```javascript
40 function component$0() {
41 - const x$5 = {
42 - t: 1,
43 - };
41 + const $ = React.useMemoCache();
42 + let x$5;
43 + if (true) {
44 + x$5 = {
45 + t: 1,
46 + };
47 + $[0] = x$5;
48 + } else {
49 + x$5 = $[0];
50 + }
51 +
52 const p$6 = x$5.t;
53 }
54
compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md
+38 -7
@@ -19,9 +19,9 @@ function component() {
19
20 ```
21 bb0:
22 - [1] Const mutate $10_@0:TPrimitive = Call mutate makeSomePrimitive$2:TFunction()
23 - [2] Const mutate $11_@1:TPrimitive = Call mutate makeSomePrimitive$2:TFunction()
24 - [3] Const mutate x$12_@2:TObject = Object { u: read $10_@0:TPrimitive, v: read $11_@1:TPrimitive }
22 + [1] Const mutate t0$10_@0:TPrimitive = Call mutate makeSomePrimitive$2:TFunction()
23 + [2] Const mutate t1$11_@1:TPrimitive = Call mutate makeSomePrimitive$2:TFunction()
24 + [3] Const mutate x$12_@2:TObject = Object { u: read t0$10_@0:TPrimitive, v: read t1$11_@1:TPrimitive }
25 [4] Const mutate u$13:TPrimitive = read x$12_@2.u
26 [5] Const mutate v$14:TPrimitive = read x$12_@2.v
27 [6] Const mutate $15:TPrimitive = Binary read u$13:TPrimitive > read v$14:TPrimitive
@@ -63,12 +63,43 @@ function component(
63
64 ```javascript
65 function component$0() {
66 - const x$12 = {
67 - u: makeSomePrimitive$2(),
68 - v: makeSomePrimitive$2(),
69 - };
66 + const $ = React.useMemoCache();
67 + let t0$10;
68 + if (true) {
69 + t0$10 = makeSomePrimitive$2();
70 + $[0] = t0$10;
71 + } else {
72 + t0$10 = $[0];
73 + }
74 +
75 + let t1$11;
76 +
77 + if (true) {
78 + t1$11 = makeSomePrimitive$2();
79 + $[1] = t1$11;
80 + } else {
81 + t1$11 = $[1];
82 + }
83 +
84 + const c_2 = $[2] !== t0$10;
85 + const c_3 = $[3] !== t1$11;
86 + let x$12;
87 +
88 + if (c_2 || c_3) {
89 + x$12 = {
90 + u: t0$10,
91 + v: t1$11,
92 + };
93 + $[2] = t0$10;
94 + $[3] = t1$11;
95 + $[4] = x$12;
96 + } else {
97 + x$12 = $[4];
98 + }
99 +
100 const u$13 = x$12.u;
101 const v$14 = x$12.v;
102 +
103 bb1: if (u$13 > v$14) {
104 }
105
compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md
+16 -3
@@ -44,9 +44,22 @@ function component(
44
45 ```javascript
46 function component$0() {
47 - const x$4 = {};
48 - const q$5 = {};
49 - x$4.t = q$5;
47 + const $ = React.useMemoCache();
48 + let x$4;
49 + if (true) {
50 + x$4 = {};
51 +
52 + if (true) {
53 + const q$5 = {};
54 + } else {
55 + }
56 +
57 + x$4.t = q$5;
58 + $[0] = x$4;
59 + } else {
60 + x$4 = $[0];
61 + }
62 +
63 const z$6 = x$4.t;
64 }
65
compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md
+34 -6
@@ -61,13 +61,41 @@ function component(
61
62 ```javascript
63 function component$0() {
64 - const p$7 = makePrimitive$2();
64 + const $ = React.useMemoCache();
65 + let p$7;
66 + if (true) {
67 + p$7 = makePrimitive$2();
68 + $[0] = p$7;
69 + } else {
70 + p$7 = $[0];
71 + }
72 +
73 p$7 + p$7;
66 - const o$8 = {};
67 - const x$9 = {};
68 - x$9.t = p$7;
69 - const z$10 = x$9.t;
70 - x$9.t = o$8;
74 + let o$8;
75 +
76 + if (true) {
77 + o$8 = {};
78 + $[1] = o$8;
79 + } else {
80 + o$8 = $[1];
81 + }
82 +
83 + const c_2 = $[2] !== p$7;
84 + const c_3 = $[3] !== o$8;
85 + let x$9;
86 +
87 + if (c_2 || c_3) {
88 + x$9 = {};
89 + x$9.t = p$7;
90 + const z$10 = x$9.t;
91 + x$9.t = o$8;
92 + $[2] = p$7;
93 + $[3] = o$8;
94 + $[4] = x$9;
95 + } else {
96 + x$9 = $[4];
97 + }
98 +
99 const y$11 = x$9.t;
100 }
101
compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md
+26 -4
@@ -61,13 +61,35 @@ function component(
61
62 ```javascript
63 function component$0() {
64 - const x$7 = foo$2();
65 - const y$8 = foo$2();
64 + const $ = React.useMemoCache();
65 + let x$7;
66 + if (true) {
67 + x$7 = foo$2();
68 + $[0] = x$7;
69 + } else {
70 + x$7 = $[0];
71 + }
72 +
73 + let y$8;
74 +
75 + if (true) {
76 + y$8 = foo$2();
77 + $[1] = y$8;
78 + } else {
79 + y$8 = $[1];
80 + }
81 +
82 bb1: if (x$7 > y$8) {
67 - const z$10 = {};
83 + if (true) {
84 + const z$10 = {};
85 + } else {
86 + }
87 }
88
70 - const z$12 = foo$2();
89 + if (true) {
90 + const z$12 = foo$2();
91 + } else {
92 + }
93 }
94
95 ```