From 575db2b4ea7213badc3a0be2b58330a0918091cc Mon Sep 17 00:00:00 2001 From: Joe Savona Date: Wed, 14 Dec 2022 16:12:36 -0800 Subject: [PATCH] [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. --- .../forget/src/HIR/CodegenReactiveFunction.ts | 138 +++++++++++++++++- .../_bug_conditional-break-labeled.expect.md | 27 +++- .../alias-nested-member-path-mutate.expect.md | 15 +- .../hir/alias-nested-member-path.expect.md | 38 ++++- .../fixtures/hir/alias-while.expect.md | 35 +++-- .../hir/assignment-variations.expect.md | 7 +- .../src/__tests__/fixtures/hir/call.expect.md | 47 +++++- .../fixtures/hir/component.expect.md | 91 +++++++++--- .../fixtures/hir/conditional-break.expect.md | 137 +++++++++++++---- .../hir/conditional-on-mutable.expect.md | 92 +++++++++--- .../fixtures/hir/constructor.expect.md | 47 +++++- .../hir/dependencies-outputs.expect.md | 36 ++++- .../fixtures/hir/dependencies.expect.md | 40 ++++- .../fixtures/hir/extend-scopes-if.expect.md | 22 ++- .../fixtures/hir/frozen-after-alias.expect.md | 10 +- .../fixtures/hir/hook-call.expect.md | 51 +++++-- .../hir/hooks-freeze-arguments.expect.md | 10 +- ...reeze-possibly-mutable-arguments.expect.md | 21 ++- .../hir/independent-across-if.expect.md | 44 +++++- .../fixtures/hir/independent.expect.md | 43 +++++- .../hir/interdependent-across-if.expect.md | 45 +++++- .../fixtures/hir/interdependent.expect.md | 40 ++++- .../fixtures/hir/inverted-if.expect.md | 20 ++- .../__tests__/fixtures/hir/issue852.expect.md | 18 ++- .../fixtures/hir/jsx-fragment.expect.md | 53 +++++-- .../fixtures/hir/logical-expression.expect.md | 120 ++++++++++++--- .../hir/mutable-lifetime-loops.expect.md | 49 ++++--- .../mutable-lifetime-with-aliasing.expect.md | 58 +++++--- .../hir/mutable-liverange-loop.expect.md | 46 +++--- ...g-scopes-interleaved-by-terminal.expect.md | 21 ++- .../overlapping-scopes-interleaved.expect.md | 16 +- .../hir/overlapping-scopes-shadowed.expect.md | 23 ++- ...ng-scopes-shadowing-within-block.expect.md | 46 +++++- .../hir/overlapping-scopes-while.expect.md | 22 ++- .../overlapping-scopes-within-block.expect.md | 27 +++- .../hir/property-assignment.expect.md | 42 +++++- .../hir/reactive-scope-grouping.expect.md | 23 ++- .../fixtures/hir/reactive-scopes-if.expect.md | 44 +++++- .../fixtures/hir/reactive-scopes.expect.md | 38 ++++- .../hir/reassignment-conditional.expect.md | 49 ++++++- .../reassignment-separate-scopes.expect.md | 94 +++++++++--- .../fixtures/hir/reassignment.expect.md | 58 ++++++-- .../fixtures/hir/reverse-postorder.expect.md | 65 ++++++--- .../fixtures/hir/simple-alias.expect.md | 27 +++- .../__tests__/fixtures/hir/simple.expect.md | 34 ++++- .../hir/ssa-arrayexpression.expect.md | 10 +- .../fixtures/hir/ssa-call-jsx-2.expect.md | 54 +++++-- .../fixtures/hir/ssa-call-jsx.expect.md | 47 +++++- .../hir/ssa-complex-multiple-if.expect.md | 23 ++- .../hir/ssa-complex-single-if.expect.md | 17 ++- .../fixtures/hir/ssa-for-of.expect.md | 5 +- .../hir/ssa-for-trivial-update.expect.md | 15 +- .../__tests__/fixtures/hir/ssa-for.expect.md | 15 +- .../fixtures/hir/ssa-multiple-phis.expect.md | 43 ++++-- .../hir/ssa-nested-partial-phi.expect.md | 22 ++- .../ssa-nested-partial-reassignment.expect.md | 29 +++- .../fixtures/hir/ssa-newexpression.expect.md | 14 +- .../hir/ssa-objectexpression-phi.expect.md | 39 +++-- .../hir/ssa-objectexpression.expect.md | 16 +- ...a-property-alias-alias-mutate-if.expect.md | 27 +++- .../hir/ssa-property-alias-if.expect.md | 31 +++- .../ssa-property-alias-mutate-if.expect.md | 25 +++- ...-property-alias-mutate-inside-if.expect.md | 29 +++- .../hir/ssa-property-alias-mutate.expect.md | 18 ++- .../fixtures/hir/ssa-property-call.expect.md | 28 +++- .../hir/ssa-property-mutate-2.expect.md | 16 +- .../hir/ssa-property-mutate-alias.expect.md | 18 ++- .../hir/ssa-property-mutate.expect.md | 16 +- .../fixtures/hir/ssa-property.expect.md | 24 ++- .../fixtures/hir/ssa-return.expect.md | 15 +- .../fixtures/hir/ssa-shadowing.expect.md | 21 ++- .../fixtures/hir/ssa-sibling-phis.expect.md | 41 +++++- .../fixtures/hir/ssa-simple-phi.expect.md | 17 ++- .../fixtures/hir/ssa-switch.expect.md | 35 +++-- .../fixtures/hir/ssa-throw.expect.md | 15 +- .../fixtures/hir/ssa-while.expect.md | 15 +- .../hir/switch-non-final-default.expect.md | 76 +++++++--- .../__tests__/fixtures/hir/switch.expect.md | 70 +++++++-- .../hir/transitive-alias-fields.expect.md | 19 ++- .../type-args-test-binary-operator.expect.md | 5 +- .../hir/type-binary-operator.expect.md | 25 +++- .../fixtures/hir/type-field-load.expect.md | 14 +- .../type-test-field-load-binary-op.expect.md | 45 +++++- .../hir/type-test-field-store.expect.md | 19 ++- .../hir/type-test-polymorphic.expect.md | 40 ++++- .../type-test-return-type-inference.expect.md | 32 +++- 86 files changed, 2457 insertions(+), 657 deletions(-) diff --git a/compiler/forget/src/HIR/CodegenReactiveFunction.ts b/compiler/forget/src/HIR/CodegenReactiveFunction.ts index 375e47c289..31465729e2 100644 --- a/compiler/forget/src/HIR/CodegenReactiveFunction.ts +++ b/compiler/forget/src/HIR/CodegenReactiveFunction.ts @@ -18,7 +18,9 @@ import { Temporaries, } from "./Codegen"; import { + Identifier, Instruction, + InstructionKind, ReactiveBasicBlock, ReactiveFunction, ReactiveScope, @@ -38,6 +40,22 @@ export function codegenReactiveFunction(fn: ReactiveFunction): t.Function { statements.pop(); } } + if (cx.nextCacheIndex !== 0) { + statements.unshift( + t.variableDeclaration("const", [ + t.variableDeclarator( + t.identifier("$"), + t.callExpression( + t.memberExpression( + t.identifier("React"), + t.identifier("useMemoCache") + ), + [] + ) + ), + ]) + ); + } return createFunctionDeclaration( fn.loc, fn.id !== null ? convertIdentifier(fn.id) : null, @@ -49,7 +67,21 @@ export function codegenReactiveFunction(fn: ReactiveFunction): t.Function { } class Context { + #nextCacheIndex: number = 0; + #identifiers: Set = new Set(); temp: Temporaries = new Map(); + + get nextCacheIndex(): number { + return this.#nextCacheIndex++; + } + + declare(identifier: Identifier): void { + this.#identifiers.add(identifier); + } + + declared(identifier: Identifier): boolean { + return this.#identifiers.has(identifier); + } } function codegenBlock( @@ -61,7 +93,7 @@ function codegenBlock( switch (item.kind) { case "instruction": { const statement = codegenInstructionNullable( - cx.temp, + cx, item.instruction, codegenInstructionValue(cx.temp, item.instruction.value) ); @@ -102,9 +134,84 @@ function codegenReactiveScope( scope: ReactiveScope, block: ReactiveBasicBlock ): void { - // TODO @josephsavona: Emit memoized blocks! - const body = codegenBlock(cx, block).body; - statements.push(...body); + const cacheStoreStatements: Array = []; + const cacheLoadStatements: Array = []; + const changeIdentifiers: Array = []; + for (const dep of scope.dependencies) { + const index = cx.nextCacheIndex; + const changeIdentifier = t.identifier(`c_${index}`); + const depValue = codegenPlace(cx.temp, dep); + + changeIdentifiers.push(changeIdentifier); + statements.push( + t.variableDeclaration("const", [ + t.variableDeclarator( + changeIdentifier, + t.binaryExpression( + "!==", + t.memberExpression( + t.identifier("$"), + t.numericLiteral(index), + true + ), + depValue + ) + ), + ]) + ); + cacheStoreStatements.push( + t.expressionStatement( + t.assignmentExpression( + "=", + t.memberExpression(t.identifier("$"), t.numericLiteral(index), true), + depValue + ) + ) + ); + } + for (const output of scope.outputs) { + const index = cx.nextCacheIndex; + + // TODO @josephsavona: ensure change and temp variables have non-conflicting names + output.name ??= `t${index}`; + + const name = convertIdentifier(output); + cx.declare(output); + statements.push(t.variableDeclaration("let", [t.variableDeclarator(name)])); + cacheStoreStatements.push( + t.expressionStatement( + t.assignmentExpression( + "=", + t.memberExpression(t.identifier("$"), t.numericLiteral(index), true), + name + ) + ) + ); + cacheLoadStatements.push( + t.expressionStatement( + t.assignmentExpression( + "=", + name, + t.memberExpression(t.identifier("$"), t.numericLiteral(index), true) + ) + ) + ); + } + const testCondition = + (changeIdentifiers as Array).reduce( + (acc: t.Expression | null, ident: t.Expression) => { + if (acc == null) { + return ident; + } + return t.logicalExpression("||", acc, ident); + }, + null as t.Expression | null + ) ?? t.booleanLiteral(true); // TODO @josephsavona handle case of empty dependencies + + const computationBlock = codegenBlock(cx, block); + computationBlock.body.push(...cacheStoreStatements); + const memoBlock = t.blockStatement(cacheLoadStatements); + statements.push(t.ifStatement(testCondition, computationBlock, memoBlock)); } function codegenTerminal(cx: Context, terminal: ReactiveTerminal): t.Statement { @@ -173,11 +280,30 @@ function codegenTerminal(cx: Context, terminal: ReactiveTerminal): t.Statement { } export function codegenInstructionNullable( - temp: Temporaries, + cx: Context, instr: Instruction, value: t.Expression ): t.Statement | null { - const statement = codegenInstruction(temp, instr, value); + let statement; + if ( + instr.lvalue !== null && + instr.lvalue.place.memberPath === null && + cx.declared(instr.lvalue.place.identifier) + ) { + statement = codegenInstruction( + cx.temp, + { + ...instr, + lvalue: { + ...instr.lvalue, + kind: InstructionKind.Reassign, + }, + }, + value + ); + } else { + statement = codegenInstruction(cx.temp, instr, value); + } if (statement.type === "EmptyStatement") { return null; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/_bug_conditional-break-labeled.expect.md b/compiler/forget/src/__tests__/fixtures/hir/_bug_conditional-break-labeled.expect.md index 4e88e1c29f..7e70e51c75 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/_bug_conditional-break-labeled.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/_bug_conditional-break-labeled.expect.md @@ -60,14 +60,27 @@ function Component( ```javascript function Component$0(props$3) { - const a$4 = []; - a$4.push(props$3.a); - bb2: if (props$3.b) { - a$4.push(props$3.d); - return a$4; - } + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$3.a; + const c_1 = $[1] !== props$3.b; + const c_2 = $[2] !== props$3.d; + const c_3 = $[3] !== props$3.c; + if (c_0 || c_1 || c_2 || c_3) { + const a$4 = []; + a$4.push(props$3.a); - a$4.push(props$3.c); + bb2: if (props$3.b) { + a$4.push(props$3.d); + return a$4; + } + + a$4.push(props$3.c); + $[0] = props$3.a; + $[1] = props$3.b; + $[2] = props$3.d; + $[3] = props$3.c; + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path-mutate.expect.md b/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path-mutate.expect.md index 51bc196e95..1bfec4ea09 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path-mutate.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path-mutate.expect.md @@ -48,12 +48,15 @@ function component( ```javascript function component$0() { - const z$5 = []; - const y$6 = {}; - y$6.z = z$5; - const x$7 = {}; - x$7.y = y$6; - mutate$4(x$7.y.z); + if (true) { + const z$5 = []; + const y$6 = {}; + y$6.z = z$5; + const x$7 = {}; + x$7.y = y$6; + mutate$4(x$7.y.z); + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md b/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md index 510ab0996e..b1167bf4d6 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/alias-nested-member-path.expect.md @@ -50,11 +50,39 @@ function component( ```javascript function component$0() { - const z$4 = []; - const y$5 = {}; - y$5.z = z$4; - const x$6 = {}; - x$6.y = y$5; + const $ = React.useMemoCache(); + let z$4; + if (true) { + z$4 = []; + $[0] = z$4; + } else { + z$4 = $[0]; + } + + const c_1 = $[1] !== z$4; + let y$5; + + if (c_1) { + y$5 = {}; + y$5.z = z$4; + $[1] = z$4; + $[2] = y$5; + } else { + y$5 = $[2]; + } + + const c_3 = $[3] !== y$5; + let x$6; + + if (c_3) { + x$6 = {}; + x$6.y = y$5; + $[3] = y$5; + $[4] = x$6; + } else { + x$6 = $[4]; + } + return x$6; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md b/compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md index 383d268868..341dab9869 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md @@ -82,15 +82,32 @@ function foo( ```javascript function foo$0(cond$7) { - let a$8 = {}; - let b$9 = {}; - let c$10 = {}; - bb2: while (cond$7) { - const z$13 = a$8; - a$8 = b$9; - b$9 = c$10; - c$10 = z$13; - mutate$6(a$8, b$9); + const $ = React.useMemoCache(); + const c_0 = $[0] !== cond$7; + let a$8; + let b$9; + let c$10; + if (c_0) { + a$8 = {}; + b$9 = {}; + c$10 = {}; + + bb2: while (cond$7) { + const z$13 = a$8; + a$8 = b$9; + b$9 = c$10; + c$10 = z$13; + mutate$6(a$8, b$9); + } + + $[0] = cond$7; + $[1] = a$8; + $[2] = b$9; + $[3] = c$10; + } else { + a$8 = $[1]; + b$9 = $[2]; + c$10 = $[3]; } a$8; diff --git a/compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md b/compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md index fed569a1aa..83308f069f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/assignment-variations.expect.md @@ -90,8 +90,11 @@ function g( ```javascript function g$0(a$4) { - a$4.c.b = a$4.b.c + 1; - a$4.c.b = a$4.b.c * 2; + if (true) { + a$4.c.b = a$4.b.c + 1; + a$4.c.b = a$4.b.c * 2; + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/call.expect.md index 686659d021..7befef4675 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/call.expect.md @@ -49,8 +49,8 @@ bb0: [5] Const mutate _$13_@1 = JSX [6] Call mutate foo$4:TFunction(mutate b$11_@0:TObject) [7] Const mutate $14:TPrimitive = "div" - [8] Const mutate $15_@2 = JSX - [9] Return read $15_@2 + [8] Const mutate t5$15_@2 = JSX + [9] Return read t5$15_@2 ``` ## Reactive Scopes @@ -82,13 +82,44 @@ function Component( ```javascript function Component$0(props$9) { - const a$10 = []; - const b$11 = {}; - foo$4(a$10, b$11); - const _$13 =
; + const $ = React.useMemoCache(); + let a$10; + let b$11; + if (true) { + a$10 = []; + b$11 = {}; + foo$4(a$10, b$11); + const c_2 = $[2] !== a$10; - foo$4(b$11); - return
; + if (c_2) { + const _$13 =
; + + $[2] = a$10; + } else { + } + + foo$4(b$11); + $[0] = a$10; + $[1] = b$11; + } else { + a$10 = $[0]; + b$11 = $[1]; + } + + const c_3 = $[3] !== a$10; + const c_4 = $[4] !== b$11; + let t5$15; + + if (c_3 || c_4) { + t5$15 =
; + $[3] = a$10; + $[4] = b$11; + $[5] = t5$15; + } else { + t5$15 = $[5]; + } + + return t5$15; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md index bff9601a28..cf20cc5304 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md @@ -95,11 +95,11 @@ bb2: [35] Const mutate $68 = "\n " [36] Const mutate $69:TPrimitive = "h1" [37] Const mutate $70 = " Items" - [38] Const mutate $71_@4 = JSX {freeze count$66:TProp}{read $70} + [38] Const mutate t6$71_@4 = JSX {freeze count$66:TProp}{read $70} [39] Const mutate $72 = "\n " [40] Const mutate $73 = "\n " - [41] Const mutate $74_@5 = JSX {read $68}{read $71_@4}{read $72}{freeze renderedItems$32_@0:TFunction}{read $73} - [42] Return read $74_@5 + [41] Const mutate t9$74_@5 = JSX {read $68}{read t6$71_@4}{read $72}{freeze renderedItems$32_@0:TFunction}{read $73} + [42] Return read t9$74_@5 ``` ## Reactive Scopes @@ -171,37 +171,82 @@ function Component( ```javascript function Component$0(props$29) { + const $ = React.useMemoCache(); const items$30 = props$29.items; const maxItems$31 = props$29.maxItems; - const renderedItems$32 = []; - const seen$33 = new Set$6(); - const max$35 = Math$8.max(0, maxItems$31); - bb2: for (let i$36 = 0; i$36 < items$30.length; i$36 = i$36 + 1, i$36) { - const item$40 = items$30.at(i$36); + const c_0 = $[0] !== maxItems$31; + const c_1 = $[1] !== items$30.length; + const c_2 = $[2] !== items$30; + let renderedItems$32; + if (c_0 || c_1 || c_2) { + renderedItems$32 = []; + const seen$33 = new Set$6(); + const c_4 = $[4] !== maxItems$31; - bb9: if (item$40 == null) { + if (c_4) { + const max$35 = Math$8.max(0, maxItems$31); + $[4] = maxItems$31; } else { } - bb6: if (seen$33.has(item$40)) { - continue; + bb2: for (let i$36 = 0; i$36 < items$30.length; i$36 = i$36 + 1, i$36) { + const item$40 = items$30.at(i$36); + + bb9: if (item$40 == null) { + } else { + } + + bb6: if (seen$33.has(item$40)) { + continue; + } + + seen$33.add(item$40); + renderedItems$32.push(
{item$40}
); + + bb12: if (renderedItems$32.length >= max$35) { + break; + } } - seen$33.add(item$40); - renderedItems$32.push(
{item$40}
); - - bb12: if (renderedItems$32.length >= max$35) { - break; - } + $[0] = maxItems$31; + $[1] = items$30.length; + $[2] = items$30; + $[3] = renderedItems$32; + } else { + renderedItems$32 = $[3]; } const count$66 = renderedItems$32.length; - return ( -
- {

{count$66} Items

} - {renderedItems$32} -
- ); + const c_5 = $[5] !== count$66; + let t6$71; + + if (c_5) { + t6$71 =

{count$66} Items

; + $[5] = count$66; + $[6] = t6$71; + } else { + t6$71 = $[6]; + } + + const c_7 = $[7] !== t6$71; + const c_8 = $[8] !== renderedItems$32; + let t9$74; + + if (c_7 || c_8) { + t9$74 = ( +
+ {t6$71} + {renderedItems$32} +
+ ); + $[7] = t6$71; + $[8] = renderedItems$32; + $[9] = t9$74; + } else { + t9$74 = $[9]; + } + + return t9$74; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md b/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md index c20f385a13..2da39867af 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md @@ -115,13 +115,28 @@ function Component( ```javascript function Component$0(props$4) { - const a_DEBUG$5 = []; - a_DEBUG$5.push(props$4.a); - bb1: if (props$4.b) { - return null; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$4.a; + const c_1 = $[1] !== props$4.b; + const c_2 = $[2] !== props$4.d; + let a_DEBUG$5; + if (c_0 || c_1 || c_2) { + a_DEBUG$5 = []; + a_DEBUG$5.push(props$4.a); + + bb1: if (props$4.b) { + return null; + } + + a_DEBUG$5.push(props$4.d); + $[0] = props$4.a; + $[1] = props$4.b; + $[2] = props$4.d; + $[3] = a_DEBUG$5; + } else { + a_DEBUG$5 = $[3]; } - a_DEBUG$5.push(props$4.d); return a_DEBUG$5; } @@ -166,13 +181,30 @@ function Component( ```javascript function Component$0(props$3) { - const a$4 = []; - a$4.push(props$3.a); - bb1: if (props$3.b) { - a$4.push(props$3.c); + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$3.a; + const c_1 = $[1] !== props$3.b; + const c_2 = $[2] !== props$3.c; + const c_3 = $[3] !== props$3.d; + let a$4; + if (c_0 || c_1 || c_2 || c_3) { + a$4 = []; + a$4.push(props$3.a); + + bb1: if (props$3.b) { + a$4.push(props$3.c); + } + + a$4.push(props$3.d); + $[0] = props$3.a; + $[1] = props$3.b; + $[2] = props$3.c; + $[3] = props$3.d; + $[4] = a$4; + } else { + a$4 = $[4]; } - a$4.push(props$3.d); return a$4; } @@ -220,14 +252,31 @@ function Component( ```javascript function Component$0(props$4) { - const a$5 = []; - a$5.push(props$4.a); - bb1: if (props$4.b) { - a$5.push(props$4.c); - return null; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$4.a; + const c_1 = $[1] !== props$4.b; + const c_2 = $[2] !== props$4.c; + const c_3 = $[3] !== props$4.d; + let a$5; + if (c_0 || c_1 || c_2 || c_3) { + a$5 = []; + a$5.push(props$4.a); + + bb1: if (props$4.b) { + a$5.push(props$4.c); + return null; + } + + a$5.push(props$4.d); + $[0] = props$4.a; + $[1] = props$4.b; + $[2] = props$4.c; + $[3] = props$4.d; + $[4] = a$5; + } else { + a$5 = $[4]; } - a$5.push(props$4.d); return a$5; } @@ -273,14 +322,31 @@ function Component( ```javascript function Component$0(props$3) { - const a$4 = []; - a$4.push(props$3.a); - bb1: if (props$3.b) { - a$4.push(props$3.c); - return a$4; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$3.a; + const c_1 = $[1] !== props$3.b; + const c_2 = $[2] !== props$3.c; + const c_3 = $[3] !== props$3.d; + let a$4; + if (c_0 || c_1 || c_2 || c_3) { + a$4 = []; + a$4.push(props$3.a); + + bb1: if (props$3.b) { + a$4.push(props$3.c); + return a$4; + } + + a$4.push(props$3.d); + $[0] = props$3.a; + $[1] = props$3.b; + $[2] = props$3.c; + $[3] = props$3.d; + $[4] = a$4; + } else { + a$4 = $[4]; } - a$4.push(props$3.d); return a$4; } @@ -325,14 +391,27 @@ function Component( ```javascript function Component$0(props$3) { - const a$4 = []; - a$4.push(props$3.a); - bb2: if (props$3.b) { - a$4.push(props$3.d); - return a$4; - } + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$3.a; + const c_1 = $[1] !== props$3.b; + const c_2 = $[2] !== props$3.d; + const c_3 = $[3] !== props$3.c; + if (c_0 || c_1 || c_2 || c_3) { + const a$4 = []; + a$4.push(props$3.a); - a$4.push(props$3.c); + bb2: if (props$3.b) { + a$4.push(props$3.d); + return a$4; + } + + a$4.push(props$3.c); + $[0] = props$3.a; + $[1] = props$3.b; + $[2] = props$3.d; + $[3] = props$3.c; + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md b/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md index 4249d69515..70e3f6f5fe 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md @@ -51,8 +51,8 @@ bb4: [8] Goto bb3 bb3: predecessor blocks: bb4 bb1 - [9] Const mutate $16_@2 = JSX - [10] Return read $16_@2 + [9] Const mutate t6$16_@2 = JSX + [10] Return read t6$16_@2 ``` ## Reactive Scopes @@ -83,17 +83,45 @@ function Component( ```javascript function Component$0(props$6) { - const a$7 = []; - const b$8 = []; - bb1: if (b$8) { - a$7.push(props$6.p0); + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$6.p0; + const c_1 = $[1] !== props$6.p1; + const c_2 = $[2] !== props$6.p2; + let a$7; + if (c_0 || c_1 || c_2) { + a$7 = []; + const b$8 = []; + + bb1: if (b$8) { + a$7.push(props$6.p0); + } + + bb3: if (props$6.p1) { + b$8.push(props$6.p2); + } + + $[0] = props$6.p0; + $[1] = props$6.p1; + $[2] = props$6.p2; + $[3] = a$7; + } else { + a$7 = $[3]; } - bb3: if (props$6.p1) { - b$8.push(props$6.p2); + const c_4 = $[4] !== a$7; + const c_5 = $[5] !== b$8; + let t6$16; + + if (c_4 || c_5) { + t6$16 = ; + $[4] = a$7; + $[5] = b$8; + $[6] = t6$16; + } else { + t6$16 = $[6]; } - return ; + return t6$16; } ``` @@ -118,8 +146,8 @@ bb4: [9] Goto bb3 bb3: predecessor blocks: bb4 bb1 - [10] Const mutate $19_@2 = JSX - [11] Return read $19_@2 + [10] Const mutate t6$19_@2 = JSX + [11] Return read t6$19_@2 ``` ## Reactive Scopes @@ -151,17 +179,45 @@ function Component( ```javascript function Component$0(props$8) { - const a$9 = []; - const b$10 = []; - bb1: if (mayMutate$4(b$10)) { - a$9.push(props$8.p0); + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$8.p0; + const c_1 = $[1] !== props$8.p1; + const c_2 = $[2] !== props$8.p2; + let a$9; + if (c_0 || c_1 || c_2) { + a$9 = []; + const b$10 = []; + + bb1: if (mayMutate$4(b$10)) { + a$9.push(props$8.p0); + } + + bb3: if (props$8.p1) { + b$10.push(props$8.p2); + } + + $[0] = props$8.p0; + $[1] = props$8.p1; + $[2] = props$8.p2; + $[3] = a$9; + } else { + a$9 = $[3]; } - bb3: if (props$8.p1) { - b$10.push(props$8.p2); + const c_4 = $[4] !== a$9; + const c_5 = $[5] !== b$10; + let t6$19; + + if (c_4 || c_5) { + t6$19 = ; + $[4] = a$9; + $[5] = b$10; + $[6] = t6$19; + } else { + t6$19 = $[6]; } - return ; + return t6$19; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md b/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md index 0b94a0a52a..4584a93f7e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md @@ -49,8 +49,8 @@ bb0: [5] Const mutate _$13_@1 = JSX [6] New mutate Foo$4(mutate b$11_@0:TObject) [7] Const mutate $14:TPrimitive = "div" - [8] Const mutate $15_@2 = JSX - [9] Return read $15_@2 + [8] Const mutate t5$15_@2 = JSX + [9] Return read t5$15_@2 ``` ## Reactive Scopes @@ -82,13 +82,44 @@ function Component( ```javascript function Component$0(props$9) { - const a$10 = []; - const b$11 = {}; - new Foo$4(a$10, b$11); - const _$13 =
; + const $ = React.useMemoCache(); + let a$10; + let b$11; + if (true) { + a$10 = []; + b$11 = {}; + new Foo$4(a$10, b$11); + const c_2 = $[2] !== a$10; - new Foo$4(b$11); - return
; + if (c_2) { + const _$13 =
; + + $[2] = a$10; + } else { + } + + new Foo$4(b$11); + $[0] = a$10; + $[1] = b$11; + } else { + a$10 = $[0]; + b$11 = $[1]; + } + + const c_3 = $[3] !== a$10; + const c_4 = $[4] !== b$11; + let t5$15; + + if (c_3 || c_4) { + t5$15 =
; + $[3] = a$10; + $[4] = b$11; + $[5] = t5$15; + } else { + t5$15 = $[5]; + } + + return t5$15; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/dependencies-outputs.expect.md b/compiler/forget/src/__tests__/fixtures/hir/dependencies-outputs.expect.md index 96605a5047..3663aad4ec 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/dependencies-outputs.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/dependencies-outputs.expect.md @@ -75,16 +75,36 @@ function foo( ```javascript function foo$0(a$6, b$7) { - const x$8 = []; - x$8.push(a$6); -
{x$8}
; - const y$10 = []; - bb1: if (x$8.length) { - y$10.push(x$8); + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$6; + let x$8; + if (c_0) { + x$8 = []; + x$8.push(a$6); + $[0] = a$6; + $[1] = x$8; + } else { + x$8 = $[1]; } - bb3: if (b$7) { - y$10.push(b$7); +
{x$8}
; + const c_2 = $[2] !== x$8; + const c_3 = $[3] !== b$7; + + if (c_2 || c_3) { + const y$10 = []; + + bb1: if (x$8.length) { + y$10.push(x$8); + } + + bb3: if (b$7) { + y$10.push(b$7); + } + + $[2] = x$8; + $[3] = b$7; + } else { } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/dependencies.expect.md b/compiler/forget/src/__tests__/fixtures/hir/dependencies.expect.md index 1b0823e983..15dc3e671c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/dependencies.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/dependencies.expect.md @@ -74,15 +74,39 @@ function foo( ```javascript function foo$0(x$6, y$7, z$8) { - const items$9 = [z$8]; - items$9.push(x$6); - const items2$10 = []; - bb1: if (x$6) { - items2$10.push(y$7); - } - - bb3: if (y$7) { + const $ = React.useMemoCache(); + const c_0 = $[0] !== z$8; + const c_1 = $[1] !== x$6; + const c_2 = $[2] !== y$7; + if (c_0 || c_1 || c_2) { + const items$9 = [z$8]; items$9.push(x$6); + const c_3 = $[3] !== x$6; + const c_4 = $[4] !== y$7; + let items2$10; + + if (c_3 || c_4) { + items2$10 = []; + + bb1: if (x$6) { + items2$10.push(y$7); + } + + $[3] = x$6; + $[4] = y$7; + $[5] = items2$10; + } else { + items2$10 = $[5]; + } + + bb3: if (y$7) { + items$9.push(x$6); + } + + $[0] = z$8; + $[1] = x$6; + $[2] = y$7; + } else { } return items2$10; diff --git a/compiler/forget/src/__tests__/fixtures/hir/extend-scopes-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/extend-scopes-if.expect.md index 928d5e61fe..1e63ced36a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/extend-scopes-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/extend-scopes-if.expect.md @@ -80,13 +80,25 @@ function foo( ```javascript function foo$0(a$7, b$8, c$9) { - const x$10 = []; - bb1: if (a$7) { - if (b$8) { - if (c$9) { - x$10.push(0); + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$7; + const c_1 = $[1] !== b$8; + const c_2 = $[2] !== c$9; + if (c_0 || c_1 || c_2) { + const x$10 = []; + + bb1: if (a$7) { + if (b$8) { + if (c$9) { + x$10.push(0); + } } } + + $[0] = a$7; + $[1] = b$8; + $[2] = c$9; + } else { } bb7: if (a$7.length) { diff --git a/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md index d92c35d054..24358e3c87 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md @@ -45,7 +45,15 @@ function Component( ```javascript function Component$0() { - const a$5 = []; + const $ = React.useMemoCache(); + let a$5; + if (true) { + a$5 = []; + $[0] = a$5; + } else { + a$5 = $[0]; + } + const b$6 = a$5; useFreeze$3(a$5); foo$4(b$6); diff --git a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md index 7ab3f752dc..a1b5b6913b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md @@ -75,8 +75,8 @@ bb0: [4] Const mutate $13 = "\n " [5] Const mutate $14 = "\n " [6] Const mutate $15 = "\n " - [7] Const mutate $16_@2 = JSX {read $13}{read x$11_@0}{read $14}{read y$12_@1}{read $15} - [8] Return read $16_@2 + [7] Const mutate t5$16_@2 = JSX {read $13}{read x$11_@0}{read $14}{read y$12_@1}{read $15} + [8] Return read t5$16_@2 ``` ## Reactive Scopes @@ -107,15 +107,46 @@ function Component( ```javascript function Component$0(props$10) { - const x$11 = []; - const y$12 = useFreeze$4(x$11); + const $ = React.useMemoCache(); + let x$11; + if (true) { + x$11 = []; + $[0] = x$11; + } else { + x$11 = $[0]; + } + + const c_1 = $[1] !== x$11; + let y$12; + + if (c_1) { + y$12 = useFreeze$4(x$11); + $[1] = x$11; + $[2] = y$12; + } else { + y$12 = $[2]; + } + foo$5(y$12, x$11); - return ( - - {x$11} - {y$12} - - ); + const c_3 = $[3] !== x$11; + const c_4 = $[4] !== y$12; + let t5$16; + + if (c_3 || c_4) { + t5$16 = ( + + {x$11} + {y$12} + + ); + $[3] = x$11; + $[4] = y$12; + $[5] = t5$16; + } else { + t5$16 = $[5]; + } + + return t5$16; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md index b68687b000..7f823b29eb 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md @@ -46,7 +46,15 @@ function Component( ```javascript function Component$0() { - const a$4 = []; + const $ = React.useMemoCache(); + let a$4; + if (true) { + a$4 = []; + $[0] = a$4; + } else { + a$4 = $[0]; + } + useFreeze$2(a$4); useFreeze$2(a$4); call$3(a$4); diff --git a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md index 860fa154a3..26a03d7c49 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md @@ -76,14 +76,27 @@ function Component( ```javascript function Component$0(props$7) { + const $ = React.useMemoCache(); const cond$8 = props$7.cond; const x$9 = props$7.x; const a$10 = undefined; - let a$11 = undefined; - bb1: if (cond$8) { - a$11 = x$9; + const c_0 = $[0] !== cond$8; + const c_1 = $[1] !== x$9; + let a$11; + if (c_0 || c_1) { + a$11 = undefined; + + bb1: if (cond$8) { + a$11 = x$9; + } else { + a$11 = []; + } + + $[0] = cond$8; + $[1] = x$9; + $[2] = a$11; } else { - a$11 = []; + a$11 = $[2]; } useFreeze$5(a$11); diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md index 25f12658ec..45b33281da 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md @@ -139,8 +139,8 @@ bb2: [6] Goto bb1 bb1: predecessor blocks: bb2 bb0 - [7] Const mutate $14_@2 = JSX - [8] Return read $14_@2 + [7] Const mutate t6$14_@2 = JSX + [8] Return read t6$14_@2 ``` ## Reactive Scopes @@ -169,14 +169,42 @@ function Component( ```javascript function Component$0(props$8) { - const a$9 = compute$3(props$8.a); - const b$10 = compute$3(props$8.b); - bb1: if (props$8.c) { - mutate$5(a$9); - mutate$5(b$10); + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$8.a; + const c_1 = $[1] !== props$8.b; + const c_2 = $[2] !== props$8.c; + let a$9; + if (c_0 || c_1 || c_2) { + a$9 = compute$3(props$8.a); + const b$10 = compute$3(props$8.b); + + bb1: if (props$8.c) { + mutate$5(a$9); + mutate$5(b$10); + } + + $[0] = props$8.a; + $[1] = props$8.b; + $[2] = props$8.c; + $[3] = a$9; + } else { + a$9 = $[3]; } - return ; + const c_4 = $[4] !== a$9; + const c_5 = $[5] !== b$10; + let t6$14; + + if (c_4 || c_5) { + t6$14 = ; + $[4] = a$9; + $[5] = b$10; + $[6] = t6$14; + } else { + t6$14 = $[6]; + } + + return t6$14; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md index 22a13ea6f7..d350395eee 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md @@ -30,8 +30,8 @@ function Foo() {} bb0: [1] Const mutate a$8_@0 = Call mutate compute$3:TFunction(read props$7.a) [2] Const mutate b$9_@1 = Call mutate compute$3:TFunction(read props$7.b) - [3] Const mutate $10_@2 = JSX - [4] Return read $10_@2 + [3] Const mutate t6$10_@2 = JSX + [4] Return read t6$10_@2 ``` ## Reactive Scopes @@ -58,9 +58,42 @@ function Component( ```javascript function Component$0(props$7) { - const a$8 = compute$3(props$7.a); - const b$9 = compute$3(props$7.b); - return ; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$7.a; + let a$8; + if (c_0) { + a$8 = compute$3(props$7.a); + $[0] = props$7.a; + $[1] = a$8; + } else { + a$8 = $[1]; + } + + const c_2 = $[2] !== props$7.b; + let b$9; + + if (c_2) { + b$9 = compute$3(props$7.b); + $[2] = props$7.b; + $[3] = b$9; + } else { + b$9 = $[3]; + } + + const c_4 = $[4] !== a$8; + const c_5 = $[5] !== b$9; + let t6$10; + + if (c_4 || c_5) { + t6$10 = ; + $[4] = a$8; + $[5] = b$9; + $[6] = t6$10; + } else { + t6$10 = $[6]; + } + + return t6$10; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md index ec0a78b478..0dd2e1d943 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md @@ -109,8 +109,8 @@ bb2: [5] Goto bb1 bb1: predecessor blocks: bb2 bb0 - [6] Const mutate $14_@1 = JSX - [7] Return read $14_@1 + [6] Const mutate t7$14_@1 = JSX + [7] Return read t7$14_@1 ``` ## Reactive Scopes @@ -138,13 +138,44 @@ function Component( ```javascript function Component$0(props$8) { - const a$9 = compute$3(props$8.a); - const b$10 = compute$3(props$8.b); - bb1: if (props$8.c) { - foo$5(a$9, b$10); + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$8.a; + const c_1 = $[1] !== props$8.b; + const c_2 = $[2] !== props$8.c; + let a$9; + let b$10; + if (c_0 || c_1 || c_2) { + a$9 = compute$3(props$8.a); + b$10 = compute$3(props$8.b); + + bb1: if (props$8.c) { + foo$5(a$9, b$10); + } + + $[0] = props$8.a; + $[1] = props$8.b; + $[2] = props$8.c; + $[3] = a$9; + $[4] = b$10; + } else { + a$9 = $[3]; + b$10 = $[4]; } - return ; + const c_5 = $[5] !== a$9; + const c_6 = $[6] !== b$10; + let t7$14; + + if (c_5 || c_6) { + t7$14 = ; + $[5] = a$9; + $[6] = b$10; + $[7] = t7$14; + } else { + t7$14 = $[7]; + } + + return t7$14; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md index 106a931835..f03b116dfd 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md @@ -31,8 +31,8 @@ bb0: [1] Const mutate a$9_@0[1:4] = Call mutate compute$3:TFunction(read props$8.a) [2] Const mutate b$10_@0[1:4] = Call mutate compute$3:TFunction(read props$8.b) [3] Call mutate foo$5:TFunction(mutate a$9_@0, mutate b$10_@0) - [4] Const mutate $11_@1 = JSX - [5] Return read $11_@1 + [4] Const mutate t6$11_@1 = JSX + [5] Return read t6$11_@1 ``` ## Reactive Scopes @@ -58,10 +58,38 @@ function Component( ```javascript function Component$0(props$8) { - const a$9 = compute$3(props$8.a); - const b$10 = compute$3(props$8.b); - foo$5(a$9, b$10); - return ; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$8.a; + const c_1 = $[1] !== props$8.b; + let a$9; + let b$10; + if (c_0 || c_1) { + a$9 = compute$3(props$8.a); + b$10 = compute$3(props$8.b); + foo$5(a$9, b$10); + $[0] = props$8.a; + $[1] = props$8.b; + $[2] = a$9; + $[3] = b$10; + } else { + a$9 = $[2]; + b$10 = $[3]; + } + + const c_4 = $[4] !== a$9; + const c_5 = $[5] !== b$10; + let t6$11; + + if (c_4 || c_5) { + t6$11 = ; + $[4] = a$9; + $[5] = b$10; + $[6] = t6$11; + } else { + t6$11 = $[6]; + } + + return t6$11; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/inverted-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/inverted-if.expect.md index 8f1799b432..b540b008f1 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/inverted-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/inverted-if.expect.md @@ -57,11 +57,23 @@ function foo( ```javascript function foo$0(a$5, b$6, c$7) { - const y$8 = []; - bb1: if (a$5) { - if (b$6) { - y$8.push(c$7); + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$5; + const c_1 = $[1] !== b$6; + const c_2 = $[2] !== c$7; + if (c_0 || c_1 || c_2) { + const y$8 = []; + + bb1: if (a$5) { + if (b$6) { + y$8.push(c$7); + } } + + $[0] = a$5; + $[1] = b$6; + $[2] = c$7; + } else { } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/issue852.expect.md b/compiler/forget/src/__tests__/fixtures/hir/issue852.expect.md index 11e417c4c8..3a11ccefdd 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/issue852.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/issue852.expect.md @@ -43,10 +43,20 @@ function Component( ```javascript function Component$0(c$6) { - const x$7 = { - c: c$6, - }; - mutate$3(x$7); + const $ = React.useMemoCache(); + const c_0 = $[0] !== c$6; + let x$7; + if (c_0) { + x$7 = { + c: c$6, + }; + mutate$3(x$7); + $[0] = c$6; + $[1] = x$7; + } else { + x$7 = $[1]; + } + const a$8 = x$7; const b$9 = a$8; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md index 63e865b98e..3adea1d4f9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md @@ -25,12 +25,12 @@ bb0: [4] Const mutate $17:TPrimitive = "div" [5] Const mutate $18 = "\n " [6] Const mutate $19 = "Text" - [7] Const mutate $20_@0 = JsxFragment [read $19] + [7] Const mutate t0$20_@0 = JsxFragment [read $19] [8] Const mutate $21 = "\n " - [9] Const mutate $22_@1 = JSX {read $18}{read $20_@0}{read $21} + [9] Const mutate t2$22_@1 = JSX {read $18}{read t0$20_@0}{read $21} [10] Const mutate $23 = "\n " - [11] Const mutate $24_@2 = JsxFragment [read $14, read props$13.greeting, read $15:TPrimitive, read $16, read $22_@1, read $23] - [12] Return read $24_@2 + [11] Const mutate t5$24_@2 = JsxFragment [read $14, read props$13.greeting, read $15:TPrimitive, read $16, read t2$22_@1, read $23] + [12] Return read t5$24_@2 ``` ## Reactive Scopes @@ -65,12 +65,45 @@ function Foo( ```javascript function Foo$0(props$13) { - return ( - <> - Hello {props$13.greeting} - {
{<>Text}
} - - ); + const $ = React.useMemoCache(); + let t0$20; + if (true) { + t0$20 = <>Text; + $[0] = t0$20; + } else { + t0$20 = $[0]; + } + + const c_1 = $[1] !== t0$20; + let t2$22; + + if (c_1) { + t2$22 =
{t0$20}
; + $[1] = t0$20; + $[2] = t2$22; + } else { + t2$22 = $[2]; + } + + const c_3 = $[3] !== props$13.greeting; + const c_4 = $[4] !== t2$22; + let t5$24; + + if (c_3 || c_4) { + t5$24 = ( + <> + Hello {props$13.greeting} + {t2$22} + + ); + $[3] = props$13.greeting; + $[4] = t2$22; + $[5] = t5$24; + } else { + t5$24 = $[5]; + } + + return t5$24; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md index b15a39d2df..62865d74a7 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md @@ -23,20 +23,20 @@ function g() {} ``` bb0: - [1] Const mutate $5_@0 = Call mutate f$1:TFunction() - [2] Let mutate $6_@1[2:7] = undefined - [2] If (read $5_@0) then:bb2 else:bb3 fallthrough=bb1 + [1] Const mutate t0$5_@0 = Call mutate f$1:TFunction() + [2] Let mutate t2$6_@1[2:7] = undefined + [2] If (read t0$5_@0) then:bb2 else:bb3 fallthrough=bb1 bb2: predecessor blocks: bb0 - [3] Const mutate $6_@1[2:7] = Call mutate g$4:TFunction() + [3] Const mutate t2$6_@1[2:7] = Call mutate g$4:TFunction() [4] Goto bb1 bb3: predecessor blocks: bb0 - [5] Const mutate $6_@1[2:7] = read $5_@0 + [5] Const mutate t2$6_@1[2:7] = read t0$5_@0 [6] Goto bb1 bb1: predecessor blocks: bb2 bb3 - [7] Return freeze $6_@1 + [7] Return freeze t2$6_@1 ``` ## Reactive Scopes @@ -64,10 +64,34 @@ function And( ```javascript function And$0() { - bb1: if (f$1()) { + const $ = React.useMemoCache(); + let t0$5; + if (true) { + t0$5 = f$1(); + $[0] = t0$5; } else { + t0$5 = $[0]; } - return f$1(); + + const c_1 = $[1] !== t0$5; + let t2$6; + + if (c_1) { + t2$6 = undefined; + + bb1: if (t0$5) { + t2$6 = g$4(); + } else { + t2$6 = t0$5; + } + + $[1] = t0$5; + $[2] = t2$6; + } else { + t2$6 = $[2]; + } + + return t2$6; } ``` @@ -75,20 +99,20 @@ function And$0() { ``` bb0: - [1] Const mutate $5_@0 = Call mutate f$1:TFunction() - [2] Let mutate $6_@1[2:7] = undefined - [2] If (read $5_@0) then:bb2 else:bb3 fallthrough=bb1 + [1] Const mutate t0$5_@0 = Call mutate f$1:TFunction() + [2] Let mutate t2$6_@1[2:7] = undefined + [2] If (read t0$5_@0) then:bb2 else:bb3 fallthrough=bb1 bb2: predecessor blocks: bb0 - [3] Const mutate $6_@1[2:7] = read $5_@0 + [3] Const mutate t2$6_@1[2:7] = read t0$5_@0 [4] Goto bb1 bb3: predecessor blocks: bb0 - [5] Const mutate $6_@1[2:7] = Call mutate g$4:TFunction() + [5] Const mutate t2$6_@1[2:7] = Call mutate g$4:TFunction() [6] Goto bb1 bb1: predecessor blocks: bb2 bb3 - [7] Return freeze $6_@1 + [7] Return freeze t2$6_@1 ``` ## Reactive Scopes @@ -116,10 +140,34 @@ function Or( ```javascript function Or$0() { - bb1: if (f$1()) { + const $ = React.useMemoCache(); + let t0$5; + if (true) { + t0$5 = f$1(); + $[0] = t0$5; } else { + t0$5 = $[0]; } - return g$4(); + + const c_1 = $[1] !== t0$5; + let t2$6; + + if (c_1) { + t2$6 = undefined; + + bb1: if (t0$5) { + t2$6 = t0$5; + } else { + t2$6 = g$4(); + } + + $[1] = t0$5; + $[2] = t2$6; + } else { + t2$6 = $[2]; + } + + return t2$6; } ``` @@ -127,22 +175,22 @@ function Or$0() { ``` bb0: - [1] Const mutate $9_@0:TPrimitive = Call mutate f$2:TFunction() + [1] Const mutate t0$9_@0:TPrimitive = Call mutate f$2:TFunction() [2] Const mutate $10:TPrimitive = null - [3] Const mutate $11:TPrimitive = Binary read $9_@0:TPrimitive != read $10:TPrimitive - [4] Let mutate $12_@1:TPrimitive[4:9] = undefined + [3] Const mutate $11:TPrimitive = Binary read t0$9_@0:TPrimitive != read $10:TPrimitive + [4] Let mutate t2$12_@1:TPrimitive[4:9] = undefined [4] If (read $11:TPrimitive) then:bb2 else:bb3 fallthrough=bb1 bb2: predecessor blocks: bb0 - [5] Const mutate $12_@1:TPrimitive[4:9] = read $9_@0:TPrimitive + [5] Const mutate t2$12_@1:TPrimitive[4:9] = read t0$9_@0:TPrimitive [6] Goto bb1 bb3: predecessor blocks: bb0 - [7] Const mutate $12_@1:TPrimitive[4:9] = Call mutate g$7:TFunction() + [7] Const mutate t2$12_@1:TPrimitive[4:9] = Call mutate g$7:TFunction() [8] Goto bb1 bb1: predecessor blocks: bb2 bb3 - [9] Return freeze $12_@1:TPrimitive + [9] Return freeze t2$12_@1:TPrimitive ``` ## Reactive Scopes @@ -173,10 +221,34 @@ function QuestionQuestion( ```javascript function QuestionQuestion$0(props$8) { - bb1: if (f$2() != null) { + const $ = React.useMemoCache(); + let t0$9; + if (true) { + t0$9 = f$2(); + $[0] = t0$9; } else { + t0$9 = $[0]; } - return g$7(); + + const c_1 = $[1] !== t0$9; + let t2$12; + + if (c_1) { + t2$12 = undefined; + + bb1: if (t0$9 != null) { + t2$12 = t0$9; + } else { + t2$12 = g$7(); + } + + $[1] = t0$9; + $[2] = t2$12; + } else { + t2$12 = $[2]; + } + + return t2$12; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md index 8961ccc148..ae96275d8c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md @@ -179,36 +179,39 @@ function Component( ```javascript function Component$0(props$12) { - let a$18 = {}; - let b$20 = {}; - let c$22 = {}; - let d$24 = {}; - bb2: while (true) { - const z$19 = a$18; - a$18 = b$20; - b$20 = c$22; - c$22 = d$24; - d$24 = z$19; - mutate$7(a$18, b$20); + if (true) { + let a$18 = {}; + let b$20 = {}; + let c$22 = {}; + let d$24 = {}; + bb2: while (true) { + const z$19 = a$18; + a$18 = b$20; + b$20 = c$22; + c$22 = d$24; + d$24 = z$19; + mutate$7(a$18, b$20); - bb4: if (cond$8(a$18)) { - break; + bb4: if (cond$8(a$18)) { + break; + } } - } - bb7: if (a$18) { - } + bb7: if (a$18) { + } - bb9: if (b$20) { - } + bb9: if (b$20) { + } - bb11: if (c$22) { - } + bb11: if (c$22) { + } - bb13: if (d$24) { - } + bb13: if (d$24) { + } - mutate$7(d$24, null); + mutate$7(d$24, null); + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md index 05eae8e2d0..17ecf712d0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md @@ -131,31 +131,51 @@ function Component( ```javascript function Component$0(props$10) { - const a$11 = {}; - const b$12 = [a$11]; - const c$13 = {}; - const d$14 = { - c: c$13, - }; - const x$15 = {}; - x$15.b = b$12; - const y$16 = mutate$8(x$15, d$14); - bb1: if (a$11) { + const $ = React.useMemoCache(); + let a$11; + if (true) { + a$11 = {}; + $[0] = a$11; + } else { + a$11 = $[0]; } - bb3: if (b$12) { - } + const c_1 = $[1] !== a$11; - bb5: if (c$13) { - } + if (c_1) { + const b$12 = [a$11]; - bb7: if (d$14) { - } + if (true) { + const c$13 = {}; + } else { + } - bb9: if (y$16) { - } + const d$14 = { + c: c$13, + }; + const x$15 = {}; + x$15.b = b$12; + const y$16 = mutate$8(x$15, d$14); - mutate$8(x$15, null); + bb1: if (a$11) { + } + + bb3: if (b$12) { + } + + bb5: if (c$13) { + } + + bb7: if (d$14) { + } + + bb9: if (y$16) { + } + + mutate$8(x$15, null); + $[1] = a$11; + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md index 14706ac49f..4b6e9e6dff 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md @@ -163,31 +163,39 @@ function Component( ```javascript function Component$0(props$11) { - const a$12 = {}; - const b$13 = {}; - const c$14 = {}; - const d$15 = {}; - bb2: while (true) { - mutate$6(a$12, b$13); - - bb4: if (cond$7(a$12)) { - break; + if (true) { + const a$12 = {}; + const b$13 = {}; + if (true) { + const c$14 = {}; + } else { } - } - bb7: if (a$12) { - } + const d$15 = {}; - bb9: if (b$13) { - } + bb2: while (true) { + mutate$6(a$12, b$13); - bb11: if (c$14) { - } + bb4: if (cond$7(a$12)) { + break; + } + } - bb13: if (d$15) { - } + bb7: if (a$12) { + } - mutate$6(d$15, null); + bb9: if (b$13) { + } + + bb11: if (c$14) { + } + + bb13: if (d$15) { + } + + mutate$6(d$15, null); + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved-by-terminal.expect.md b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved-by-terminal.expect.md index f0399b0f48..3ab4c7a018 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved-by-terminal.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved-by-terminal.expect.md @@ -54,13 +54,22 @@ function foo( ```javascript function foo$0(a$6, b$7, c$8) { - const x$9 = []; - const y$10 = []; - bb1: if (x$9) { - } + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$6; + const c_1 = $[1] !== b$7; + if (c_0 || c_1) { + const x$9 = []; + const y$10 = []; - y$10.push(a$6); - x$9.push(b$7); + bb1: if (x$9) { + } + + y$10.push(a$6); + x$9.push(b$7); + $[0] = a$6; + $[1] = b$7; + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved.expect.md b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved.expect.md index 7795c34f0f..0bd8257fe4 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-interleaved.expect.md @@ -44,10 +44,18 @@ function foo( ```javascript function foo$0(a$5, b$6) { - const x$7 = []; - const y$8 = []; - x$7.push(a$5); - y$8.push(b$6); + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$5; + const c_1 = $[1] !== b$6; + if (c_0 || c_1) { + const x$7 = []; + const y$8 = []; + x$7.push(a$5); + y$8.push(b$6); + $[0] = a$5; + $[1] = b$6; + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowed.expect.md b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowed.expect.md index c1eb51199c..285117121f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowed.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowed.expect.md @@ -46,10 +46,25 @@ function foo( ```javascript function foo$0(a$5, b$6) { - const x$7 = []; - const y$8 = []; - y$8.push(b$6); - x$7.push(a$5); + const $ = React.useMemoCache(); + const c_0 = $[0] !== b$6; + const c_1 = $[1] !== a$5; + if (c_0 || c_1) { + const x$7 = []; + const c_2 = $[2] !== b$6; + + if (c_2) { + const y$8 = []; + y$8.push(b$6); + $[2] = b$6; + } else { + } + + x$7.push(a$5); + $[0] = b$6; + $[1] = a$5; + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md index db1bc7326c..deb85038e3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-shadowing-within-block.expect.md @@ -75,15 +75,49 @@ function foo( ```javascript function foo$0(a$8, b$9, c$10) { - const x$11 = []; - bb1: if (a$8) { - const y$12 = []; + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$8; + const c_1 = $[1] !== b$9; + const c_2 = $[2] !== c$10; + let x$11; + if (c_0 || c_1 || c_2) { + x$11 = []; - bb3: if (b$9) { - y$12.push(c$10); + bb1: if (a$8) { + const c_4 = $[4] !== b$9; + const c_5 = $[5] !== c$10; + let y$12; + + if (c_4 || c_5) { + y$12 = []; + + bb3: if (b$9) { + y$12.push(c$10); + } + + $[4] = b$9; + $[5] = c$10; + $[6] = y$12; + } else { + y$12 = $[6]; + } + + const c_7 = $[7] !== y$12; + + if (c_7) { + $[7] = y$12; + } else { + } + + x$11.push(
{y$12}
); } - x$11.push(
{y$12}
); + $[0] = a$8; + $[1] = b$9; + $[2] = c$10; + $[3] = x$11; + } else { + x$11 = $[3]; } return x$11; diff --git a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-while.expect.md b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-while.expect.md index 58ad3f18e5..0782dfb646 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-while.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-while.expect.md @@ -60,11 +60,23 @@ function foo( ```javascript function foo$0(a$6, b$7, c$8) { - const x$9 = []; - const y$10 = []; - bb2: while (c$8) { - y$10.push(b$7); - x$9.push(a$6); + const $ = React.useMemoCache(); + const c_0 = $[0] !== c$8; + const c_1 = $[1] !== b$7; + const c_2 = $[2] !== a$6; + if (c_0 || c_1 || c_2) { + const x$9 = []; + const y$10 = []; + + bb2: while (c$8) { + y$10.push(b$7); + x$9.push(a$6); + } + + $[0] = c$8; + $[1] = b$7; + $[2] = a$6; + } else { } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-within-block.expect.md b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-within-block.expect.md index 4efb1bcbc1..918ab87271 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-within-block.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/overlapping-scopes-within-block.expect.md @@ -67,15 +67,30 @@ function foo( ```javascript function foo$0(a$6, b$7, c$8) { - const x$9 = []; - bb1: if (a$6) { - const y$10 = []; + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$6; + const c_1 = $[1] !== b$7; + const c_2 = $[2] !== c$8; + let x$9; + if (c_0 || c_1 || c_2) { + x$9 = []; - bb3: if (b$7) { - y$10.push(c$8); + bb1: if (a$6) { + const y$10 = []; + + bb3: if (b$7) { + y$10.push(c$8); + } + + x$9.push(y$10); } - x$9.push(y$10); + $[0] = a$6; + $[1] = b$7; + $[2] = c$8; + $[3] = x$9; + } else { + x$9 = $[3]; } return x$9; diff --git a/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md index 4d0438eba0..52e4fd4fd8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md @@ -22,8 +22,8 @@ bb0: [3] Reassign mutate x$7_@0.y[1:6] = read y$8_@0 [4] Const mutate child$9_@0[1:6] = JSX [5] Call mutate x$7_@0.y.push(read props$6.p0) - [6] Const mutate $10_@1 = JSX {read child$9_@0} - [7] Return read $10_@1 + [6] Const mutate t5$10_@1 = JSX {read child$9_@0} + [7] Return read t5$10_@1 ``` ## Reactive Scopes @@ -51,12 +51,38 @@ function Component( ```javascript function Component$0(props$6) { - const x$7 = {}; - const y$8 = []; - x$7.y = y$8; - const child$9 = ; - x$7.y.push(props$6.p0); - return {child$9}; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$6.p0; + let x$7; + let child$9; + if (c_0) { + x$7 = {}; + const y$8 = []; + x$7.y = y$8; + child$9 = ; + x$7.y.push(props$6.p0); + $[0] = props$6.p0; + $[1] = x$7; + $[2] = child$9; + } else { + x$7 = $[1]; + child$9 = $[2]; + } + + const c_3 = $[3] !== x$7; + const c_4 = $[4] !== child$9; + let t5$10; + + if (c_3 || c_4) { + t5$10 = {child$9}; + $[3] = x$7; + $[4] = child$9; + $[5] = t5$10; + } else { + t5$10 = $[5]; + } + + return t5$10; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md index 1f7c9f701d..f470a53c60 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reactive-scope-grouping.expect.md @@ -49,11 +49,24 @@ function foo( ```javascript function foo$0() { - const x$4 = {}; - const y$5 = []; - const z$6 = {}; - y$5.push(z$6); - x$4.y = y$5; + const $ = React.useMemoCache(); + let x$4; + if (true) { + x$4 = {}; + + if (true) { + const y$5 = []; + const z$6 = {}; + y$5.push(z$6); + } else { + } + + x$4.y = y$5; + $[0] = x$4; + } else { + x$4 = $[0]; + } + return x$4; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md index 91f0be7329..de75cfb57b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes-if.expect.md @@ -72,13 +72,45 @@ function foo( ```javascript function foo$0(a$8, b$9, c$10) { - const x$11 = []; - bb1: if (a$8) { - const y$12 = []; - y$12.push(b$9); - x$11.push(
{y$12}
); + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$8; + const c_1 = $[1] !== b$9; + const c_2 = $[2] !== c$10; + let x$11; + if (c_0 || c_1 || c_2) { + x$11 = []; + + bb1: if (a$8) { + const c_4 = $[4] !== b$9; + let y$12; + + if (c_4) { + y$12 = []; + y$12.push(b$9); + $[4] = b$9; + $[5] = y$12; + } else { + y$12 = $[5]; + } + + const c_6 = $[6] !== y$12; + + if (c_6) { + $[6] = y$12; + } else { + } + + x$11.push(
{y$12}
); + } else { + x$11.push(c$10); + } + + $[0] = a$8; + $[1] = b$9; + $[2] = c$10; + $[3] = x$11; } else { - x$11.push(c$10); + x$11 = $[3]; } return x$11; diff --git a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md index 0b9655d034..e56d0ef294 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reactive-scopes.expect.md @@ -33,8 +33,8 @@ bb4: bb1: predecessor blocks: bb4 bb2 bb0 [8] Const mutate $13:TPrimitive = "div" - [9] Const mutate $15_@1 = JSX {freeze x$10_@0:TFunction} - [10] Return read $15_@1 + [9] Const mutate t4$15_@1 = JSX {freeze x$10_@0:TFunction} + [10] Return read t4$15_@1 ``` ## Reactive Scopes @@ -67,14 +67,38 @@ function f( ```javascript function f$0(a$8, b$9) { - const x$10 = []; - bb1: if (a$8.length === 1) { - if (b$9) { - x$10.push(b$9); + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$8.length; + const c_1 = $[1] !== b$9; + let x$10; + if (c_0 || c_1) { + x$10 = []; + + bb1: if (a$8.length === 1) { + if (b$9) { + x$10.push(b$9); + } } + + $[0] = a$8.length; + $[1] = b$9; + $[2] = x$10; + } else { + x$10 = $[2]; } - return
{x$10}
; + const c_3 = $[3] !== x$10; + let t4$15; + + if (c_3) { + t4$15 =
{x$10}
; + $[3] = x$10; + $[4] = t4$15; + } else { + t4$15 = $[4]; + } + + return t4$15; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md index 733cc82335..456b86ca40 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md @@ -35,8 +35,8 @@ bb1: predecessor blocks: bb2 bb0 [7] Const mutate _$12_@1 = JSX [8] Call read y$8.push(read props$6.p2) - [9] Const mutate $15_@2 = JSX - [10] Return read $15_@2 + [9] Const mutate t6$15_@2 = JSX + [10] Return read t6$15_@2 ``` ## Reactive Scopes @@ -69,17 +69,50 @@ function Component( ```javascript function Component$0(props$6) { - let x$7 = []; - x$7.push(props$6.p0); - const y$8 = x$7; - bb1: if (props$6.p1) { + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$6.p0; + const c_1 = $[1] !== props$6.p1; + let x$7; + if (c_0 || c_1) { x$7 = []; + x$7.push(props$6.p0); + const y$8 = x$7; + + bb1: if (props$6.p1) { + x$7 = []; + } + + $[0] = props$6.p0; + $[1] = props$6.p1; + $[2] = x$7; + } else { + x$7 = $[2]; } - const _$12 = ; + const c_3 = $[3] !== x$7; + + if (c_3) { + const _$12 = ; + + $[3] = x$7; + } else { + } y$8.push(props$6.p2); - return ; + const c_4 = $[4] !== x$7; + const c_5 = $[5] !== y$8; + let t6$15; + + if (c_4 || c_5) { + t6$15 = ; + $[4] = x$7; + $[5] = y$8; + $[6] = t6$15; + } else { + t6$15 = $[6]; + } + + return t6$15; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md index 46b377fb8a..7be4b3dc1e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-separate-scopes.expect.md @@ -66,8 +66,8 @@ bb3: [16] Const mutate $26 = "\n " [17] Const mutate $27 = "\n " [18] Const mutate $28 = "\n " - [19] Const mutate $31_@3 = JSX {read $26}{read y$19_@1}{read $27}{freeze x$22_@2:TFunction}{read $28} - [20] Return read $31_@3 + [19] Const mutate t9$31_@3 = JSX {read $26}{read y$19_@1}{read $27}{freeze x$22_@2:TFunction}{read $28} + [20] Return read t9$31_@3 ``` ## Reactive Scopes @@ -119,33 +119,79 @@ function foo( ```javascript function foo$0(a$13, b$14, c$15) { - const x$16 = []; - bb1: if (a$13) { - x$16.push(a$13); - } + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$13; + let x$16; + if (c_0) { + x$16 = []; - const y$19 =
{x$16}
; - let x$22 = undefined; - - bb3: switch (b$14) { - case 0: { - x$22 = []; - x$22.push(b$14); - break bb3; + bb1: if (a$13) { + x$16.push(a$13); } - default: { - x$22 = []; - x$22.push(c$15); - } + $[0] = a$13; + $[1] = x$16; + } else { + x$16 = $[1]; } - return ( -
- {y$19} - {x$22} -
- ); + const c_2 = $[2] !== x$16; + let y$19; + + if (c_2) { + y$19 =
{x$16}
; + $[2] = x$16; + $[3] = y$19; + } else { + y$19 = $[3]; + } + + const c_4 = $[4] !== b$14; + const c_5 = $[5] !== c$15; + let x$22; + + if (c_4 || c_5) { + x$22 = undefined; + + bb3: switch (b$14) { + case 0: { + x$22 = []; + x$22.push(b$14); + break bb3; + } + + default: { + x$22 = []; + x$22.push(c$15); + } + } + + $[4] = b$14; + $[5] = c$15; + $[6] = x$22; + } else { + x$22 = $[6]; + } + + const c_7 = $[7] !== y$19; + const c_8 = $[8] !== x$22; + let t9$31; + + if (c_7 || c_8) { + t9$31 = ( +
+ {y$19} + {x$22} +
+ ); + $[7] = y$19; + $[8] = x$22; + $[9] = t9$31; + } else { + t9$31 = $[9]; + } + + return t9$31; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md index 638f61f065..61875c7917 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md @@ -27,8 +27,8 @@ bb0: [4] Const mutate x$9_@1 = Array [] [5] Const mutate _$10_@2 = JSX [6] Call mutate y$8_@0.push(read props$6.p1) - [7] Const mutate $11_@3 = JSX - [8] Return read $11_@3 + [7] Const mutate t7$11_@3 = JSX + [8] Return read t7$11_@3 ``` ## Reactive Scopes @@ -61,14 +61,54 @@ function Component( ```javascript function Component$0(props$6) { - const x$7 = []; - x$7.push(props$6.p0); - const y$8 = x$7; - const x$9 = []; - const _$10 = ; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$6.p0; + const c_1 = $[1] !== props$6.p1; + let y$8; + if (c_0 || c_1) { + const x$7 = []; + x$7.push(props$6.p0); + y$8 = x$7; + let x$9; - y$8.push(props$6.p1); - return ; + if (true) { + x$9 = []; + $[3] = x$9; + } else { + x$9 = $[3]; + } + + const c_4 = $[4] !== x$9; + + if (c_4) { + const _$10 = ; + + $[4] = x$9; + } else { + } + + y$8.push(props$6.p1); + $[0] = props$6.p0; + $[1] = props$6.p1; + $[2] = y$8; + } else { + y$8 = $[2]; + } + + const c_5 = $[5] !== x$9; + const c_6 = $[6] !== y$8; + let t7$11; + + if (c_5 || c_6) { + t7$11 = ; + $[5] = x$9; + $[6] = y$8; + $[7] = t7$11; + } else { + t7$11 = $[7]; + } + + return t7$11; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md index 080b6c0728..6e9bf037c5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md @@ -125,33 +125,58 @@ function Component( ```javascript function Component$0(props$6) { + const $ = React.useMemoCache(); const x$7 = undefined; - let x$11 = undefined; - bb1: if (props$6.cond) { - switch (props$6.test) { - case 0: { - x$11 = props$6.v0; - break bb1; - } + const c_0 = $[0] !== props$6.cond; + const c_1 = $[1] !== props$6.test; + const c_2 = $[2] !== props$6.v0; + const c_3 = $[3] !== props$6.v1; + const c_4 = $[4] !== props$6.v2; + const c_5 = $[5] !== props$6.cond2; + const c_6 = $[6] !== props$6.b; + const c_7 = $[7] !== props$6.c; + let x$11; + if (c_0 || c_1 || c_2 || c_3 || c_4 || c_5 || c_6 || c_7) { + x$11 = undefined; - case 1: { - x$11 = props$6.v1; - break bb1; - } + bb1: if (props$6.cond) { + switch (props$6.test) { + case 0: { + x$11 = props$6.v0; + break bb1; + } - case 2: { - } + case 1: { + x$11 = props$6.v1; + break bb1; + } - default: { - x$11 = props$6.v2; + case 2: { + } + + default: { + x$11 = props$6.v2; + } } - } - } else { - if (props$6.cond2) { - x$11 = props$6.b; } else { - x$11 = props$6.c; + if (props$6.cond2) { + x$11 = props$6.b; + } else { + x$11 = props$6.c; + } } + + $[0] = props$6.cond; + $[1] = props$6.test; + $[2] = props$6.v0; + $[3] = props$6.v1; + $[4] = props$6.v2; + $[5] = props$6.cond2; + $[6] = props$6.b; + $[7] = props$6.c; + $[8] = x$11; + } else { + x$11 = $[8]; } x$11; diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md index 4790a4beb4..29c4e6cc4f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md @@ -78,13 +78,26 @@ function foo( ```javascript function foo$0() { - const a$5 = {}; - const b$6 = {}; - const c$7 = {}; - const a$8 = b$6; - const b$9 = c$7; - const c$10 = a$8; - mutate$4(a$8, b$9); + const $ = React.useMemoCache(); + if (true) { + const a$5 = {}; + } else { + } + + let c$10; + + if (true) { + const b$6 = {}; + const c$7 = {}; + const a$8 = b$6; + const b$9 = c$7; + c$10 = a$8; + mutate$4(a$8, b$9); + $[0] = c$10; + } else { + c$10 = $[0]; + } + return c$10; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md index cddee91f0c..571db14c1d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md @@ -19,14 +19,14 @@ bb0: bb2: predecessor blocks: bb0 [2] Const mutate $10:TPrimitive = false - [3] Const mutate $11_@0 = Call read foo$0:TFunction(read $10:TPrimitive, read y$9:TPrimitive) - [4] Return freeze $11_@0 + [3] Const mutate t1$11_@0 = Call read foo$0:TFunction(read $10:TPrimitive, read y$9:TPrimitive) + [4] Return freeze t1$11_@0 bb1: predecessor blocks: bb0 [5] Const mutate $12:TPrimitive = 10 [6] Const mutate $13:TPrimitive = Binary read y$9:TPrimitive * read $12:TPrimitive - [7] Const mutate $14_@1 = Array [read $13:TPrimitive] - [8] Return freeze $14_@1 + [7] Const mutate t2$14_@1 = Array [read $13:TPrimitive] + [8] Return freeze t2$14_@1 ``` ## Reactive Scopes @@ -57,10 +57,32 @@ function foo( ```javascript function foo$0(x$8, y$9) { + const $ = React.useMemoCache(); bb1: if (x$8) { - return foo$0(false, y$9); + const c_0 = $[0] !== y$9; + let t1$11; + + if (c_0) { + t1$11 = foo$0(false, y$9); + $[0] = y$9; + $[1] = t1$11; + } else { + t1$11 = $[1]; + } + + return t1$11; } - return [y$9 * 10]; + + let t2$14; + + if (true) { + t2$14 = [y$9 * 10]; + $[2] = t2$14; + } else { + t2$14 = $[2]; + } + + return t2$14; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md index 6ee6295de8..2087fab9df 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md @@ -41,9 +41,17 @@ function Component( ```javascript function Component$0(props$5) { + const $ = React.useMemoCache(); const a$6 = 1; const b$7 = 2; - const x$8 = [a$6, b$7]; + let x$8; + if (true) { + x$8 = [a$6, b$7]; + $[0] = x$8; + } else { + x$8 = $[0]; + } + return x$8; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md index 12a480eb2f..b48a0ca24b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md @@ -59,8 +59,8 @@ bb1: predecessor blocks: bb2 bb0 [9] Call mutate foo$4:TFunction(read a$11_@0, mutate b$12_@0:TObject) [10] Const mutate $19:TPrimitive = "div" - [11] Const mutate $20_@3 = JSX - [12] Return read $20_@3 + [11] Const mutate t5$20_@3 = JSX + [12] Return read t5$20_@3 ``` ## Reactive Scopes @@ -97,15 +97,51 @@ function Component( ```javascript function Component$0(props$10) { - const a$11 = []; - const b$12 = {}; - foo$4(a$11, b$12); - bb1: if (foo$4()) { - const _$15 =
; + const $ = React.useMemoCache(); + let a$11; + let b$12; + if (true) { + a$11 = []; + b$12 = {}; + foo$4(a$11, b$12); + + if (true) { + } else { + } + + bb1: if (foo$4()) { + const c_2 = $[2] !== a$11; + + if (c_2) { + const _$15 =
; + + $[2] = a$11; + } else { + } + } + + foo$4(a$11, b$12); + $[0] = a$11; + $[1] = b$12; + } else { + a$11 = $[0]; + b$12 = $[1]; } - foo$4(a$11, b$12); - return
; + const c_3 = $[3] !== a$11; + const c_4 = $[4] !== b$12; + let t5$20; + + if (c_3 || c_4) { + t5$20 =
; + $[3] = a$11; + $[4] = b$12; + $[5] = t5$20; + } else { + t5$20 = $[5]; + } + + return t5$20; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md index 670dc299a7..ecaa45017c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md @@ -49,8 +49,8 @@ bb0: [5] Const mutate _$13_@1 = JSX [6] Call mutate foo$4:TFunction(read a$10_@0, mutate b$11_@0:TObject) [7] Const mutate $14:TPrimitive = "div" - [8] Const mutate $15_@2 = JSX - [9] Return read $15_@2 + [8] Const mutate t5$15_@2 = JSX + [9] Return read t5$15_@2 ``` ## Reactive Scopes @@ -82,13 +82,44 @@ function Component( ```javascript function Component$0(props$9) { - const a$10 = []; - const b$11 = {}; - foo$4(a$10, b$11); - const _$13 =
; + const $ = React.useMemoCache(); + let a$10; + let b$11; + if (true) { + a$10 = []; + b$11 = {}; + foo$4(a$10, b$11); + const c_2 = $[2] !== a$10; - foo$4(a$10, b$11); - return
; + if (c_2) { + const _$13 =
; + + $[2] = a$10; + } else { + } + + foo$4(a$10, b$11); + $[0] = a$10; + $[1] = b$11; + } else { + a$10 = $[0]; + b$11 = $[1]; + } + + const c_3 = $[3] !== a$10; + const c_4 = $[4] !== b$11; + let t5$15; + + if (c_3 || c_4) { + t5$15 =
; + $[3] = a$10; + $[4] = b$11; + $[5] = t5$15; + } else { + t5$15 = $[5]; + } + + return t5$15; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md index 8e490e8a20..251a865728 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md @@ -74,14 +74,23 @@ function foo( ```javascript function foo$0() { - let x$7 = 1; - const y$8 = 2; - bb1: if (y$8 === 2) { - x$7 = 3; - } + const $ = React.useMemoCache(); + let x$7; + if (true) { + x$7 = 1; + const y$8 = 2; - bb3: if (y$8 === 3) { - x$7 = 5; + bb1: if (y$8 === 2) { + x$7 = 3; + } + + bb3: if (y$8 === 3) { + x$7 = 5; + } + + $[0] = x$7; + } else { + x$7 = $[0]; } const y$18 = x$7; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md index 6fc92490c7..e9abf6f090 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md @@ -57,10 +57,19 @@ function foo( ```javascript function foo$0() { - let x$5 = 1; - const y$6 = 2; - bb1: if (y$6 === 2) { - x$5 = 3; + const $ = React.useMemoCache(); + let x$5; + if (true) { + x$5 = 1; + const y$6 = 2; + + bb1: if (y$6 === 2) { + x$5 = 3; + } + + $[0] = x$5; + } else { + x$5 = $[0]; } const y$11 = x$5; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md index 9ebe193557..723714b463 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md @@ -57,7 +57,10 @@ function foo( ```javascript function foo$0(cond$4) { - const items$5 = []; + if (true) { + const items$5 = []; + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-for-trivial-update.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-for-trivial-update.expect.md index 7e80e19369..0ea3c97a07 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-for-trivial-update.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-for-trivial-update.expect.md @@ -70,9 +70,18 @@ function foo( ```javascript function foo$0() { - let x$6 = 1; - bb2: for (const i$7 = 0; i$7 < 10; i$7) { - x$6 = x$6 + 1; + const $ = React.useMemoCache(); + let x$6; + if (true) { + x$6 = 1; + + bb2: for (const i$7 = 0; i$7 < 10; i$7) { + x$6 = x$6 + 1; + } + + $[0] = x$6; + } else { + x$6 = $[0]; } return x$6; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md index bf6858811b..ad2dd961f9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md @@ -74,9 +74,18 @@ function foo( ```javascript function foo$0() { - let x$7 = 1; - bb2: for (let i$8 = 0; i$8 < 10; i$8 = i$8 + 1, i$8) { - x$7 = x$7 + 1; + const $ = React.useMemoCache(); + let x$7; + if (true) { + x$7 = 1; + + bb2: for (let i$8 = 0; i$8 < 10; i$8 = i$8 + 1, i$8) { + x$7 = x$7 + 1; + } + + $[0] = x$7; + } else { + x$7 = $[0]; } return x$7; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-multiple-phis.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-multiple-phis.expect.md index b17369081e..337c975d75 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-multiple-phis.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-multiple-phis.expect.md @@ -109,24 +109,41 @@ function foo( ```javascript function foo$0(a$9, b$10, c$11, d$12) { + const $ = React.useMemoCache(); const x$13 = 0; - let x$18 = undefined; - bb1: if (true) { - bb3: if (true) { - x$18 = a$9; + const c_0 = $[0] !== a$9; + const c_1 = $[1] !== b$10; + const c_2 = $[2] !== c$11; + const c_3 = $[3] !== d$12; + let x$18; + if (c_0 || c_1 || c_2 || c_3) { + x$18 = undefined; + + bb1: if (true) { + bb3: if (true) { + x$18 = a$9; + } else { + x$18 = b$10; + } + + x$18; } else { - x$18 = b$10; + bb7: if (true) { + x$18 = c$11; + } else { + x$18 = d$12; + } + + x$18; } - x$18; + $[0] = a$9; + $[1] = b$10; + $[2] = c$11; + $[3] = d$12; + $[4] = x$18; } else { - bb7: if (true) { - x$18 = c$11; - } else { - x$18 = d$12; - } - - x$18; + x$18 = $[4]; } return x$18; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-phi.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-phi.expect.md index a2d212e8b7..9569ead3ab 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-phi.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-phi.expect.md @@ -62,13 +62,25 @@ function foo( ```javascript function foo$0(a$5, b$6, c$7) { - const x$8 = a$5; - bb1: if (b$6) { - bb3: if (c$7) { - x$8 = c$7; + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$5; + const c_1 = $[1] !== b$6; + const c_2 = $[2] !== c$7; + if (c_0 || c_1 || c_2) { + const x$8 = a$5; + + bb1: if (b$6) { + bb3: if (c$7) { + x$8 = c$7; + } + + x$8; } - x$8; + $[0] = a$5; + $[1] = b$6; + $[2] = c$7; + } else { } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-reassignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-reassignment.expect.md index af337a1707..b4d860c119 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-reassignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-partial-reassignment.expect.md @@ -67,13 +67,30 @@ function foo( ```javascript function foo$0(a$7, b$8, c$9, d$10, e$11) { - let x$12 = null; - bb1: if (a$7) { - x$12 = b$8; - } else { - if (c$9) { - x$12 = d$10; + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$7; + const c_1 = $[1] !== b$8; + const c_2 = $[2] !== c$9; + const c_3 = $[3] !== d$10; + let x$12; + if (c_0 || c_1 || c_2 || c_3) { + x$12 = null; + + bb1: if (a$7) { + x$12 = b$8; + } else { + if (c$9) { + x$12 = d$10; + } } + + $[0] = a$7; + $[1] = b$8; + $[2] = c$9; + $[3] = d$10; + $[4] = x$12; + } else { + x$12 = $[4]; } return x$12; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md index baa3ddecf5..6d86df9188 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md @@ -66,9 +66,17 @@ function Component( ```javascript function Component$0(props$6) { - const a$7 = []; - const b$8 = {}; - const c$9 = new Foo$5(a$7, b$8); + const $ = React.useMemoCache(); + let c$9; + if (true) { + const a$7 = []; + const b$8 = {}; + c$9 = new Foo$5(a$7, b$8); + $[0] = c$9; + } else { + c$9 = $[0]; + } + return c$9; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md index c6146b19a8..889383e0e9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md @@ -69,18 +69,39 @@ function foo( ```javascript function foo$0() { - let x$6 = 1; - let y$7 = 2; - bb1: if (x$6 > 1) { - x$6 = 2; + const $ = React.useMemoCache(); + let x$6; + if (true) { + x$6 = 1; + let y$7 = 2; + + bb1: if (x$6 > 1) { + x$6 = 2; + } else { + y$7 = 3; + } + + $[0] = x$6; } else { - y$7 = 3; + x$6 = $[0]; + } + + const c_1 = $[1] !== x$6; + const c_2 = $[2] !== y$7; + let t$14; + + if (c_1 || c_2) { + t$14 = { + x: x$6, + y: y$7, + }; + $[1] = x$6; + $[2] = y$7; + $[3] = t$14; + } else { + t$14 = $[3]; } - const t$14 = { - x: x$6, - y: y$7, - }; return t$14; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md index b1fc18ebf6..6a8a976f3a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md @@ -41,12 +41,20 @@ function Component( ```javascript function Component$0(props$5) { + const $ = React.useMemoCache(); const a$6 = 1; const b$7 = 2; - const x$8 = { - a: a$6, - b: b$7, - }; + let x$8; + if (true) { + x$8 = { + a: a$6, + b: b$7, + }; + $[0] = x$8; + } else { + x$8 = $[0]; + } + return x$8; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-alias-mutate-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-alias-mutate-if.expect.md index a4b6554caa..3f9eaa92ab 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-alias-mutate-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-alias-mutate-if.expect.md @@ -68,17 +68,28 @@ function foo( ```javascript function foo$0(a$7) { - const b$8 = {}; - const x$9 = b$8; - bb1: if (a$7) { - const y$10 = {}; - x$9.y = y$10; + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$7; + let x$9; + if (c_0) { + const b$8 = {}; + x$9 = b$8; + + bb1: if (a$7) { + const y$10 = {}; + x$9.y = y$10; + } else { + const z$11 = {}; + x$9.z = z$11; + } + + mutate$6(b$8); + $[0] = a$7; + $[1] = x$9; } else { - const z$11 = {}; - x$9.z = z$11; + x$9 = $[1]; } - mutate$6(b$8); return x$9; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md index 5c11e145b4..d96b7ecf9a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-if.expect.md @@ -66,13 +66,32 @@ function foo( ```javascript function foo$0(a$5) { - const x$6 = {}; - bb1: if (a$5) { - const y$7 = {}; - x$6.y = y$7; + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$5; + let x$6; + if (c_0) { + x$6 = {}; + + bb1: if (a$5) { + if (true) { + const y$7 = {}; + } else { + } + + x$6.y = y$7; + } else { + if (true) { + const z$8 = {}; + } else { + } + + x$6.z = z$8; + } + + $[0] = a$5; + $[1] = x$6; } else { - const z$8 = {}; - x$6.z = z$8; + x$6 = $[1]; } return x$6; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-if.expect.md index 3599dd2d39..b7c8647f0f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-if.expect.md @@ -65,16 +65,27 @@ function foo( ```javascript function foo$0(a$6) { - const x$7 = {}; - bb1: if (a$6) { - const y$8 = {}; - x$7.y = y$8; + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$6; + let x$7; + if (c_0) { + x$7 = {}; + + bb1: if (a$6) { + const y$8 = {}; + x$7.y = y$8; + } else { + const z$9 = {}; + x$7.z = z$9; + } + + mutate$5(x$7); + $[0] = a$6; + $[1] = x$7; } else { - const z$9 = {}; - x$7.z = z$9; + x$7 = $[1]; } - mutate$5(x$7); return x$7; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md index 51c0c3b5b8..eb7b304610 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate-inside-if.expect.md @@ -67,14 +67,29 @@ function foo( ```javascript function foo$0(a$6) { - const x$7 = {}; - bb1: if (a$6) { - const y$8 = {}; - x$7.y = y$8; - mutate$4(y$8); + const $ = React.useMemoCache(); + const c_0 = $[0] !== a$6; + let x$7; + if (c_0) { + x$7 = {}; + + bb1: if (a$6) { + const y$8 = {}; + x$7.y = y$8; + mutate$4(y$8); + } else { + if (true) { + const z$9 = {}; + } else { + } + + x$7.z = z$9; + } + + $[0] = a$6; + $[1] = x$7; } else { - const z$9 = {}; - x$7.z = z$9; + x$7 = $[1]; } return x$7; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate.expect.md index 393c19982e..ee9d1062e3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-alias-mutate.expect.md @@ -48,11 +48,19 @@ function foo( ```javascript function foo$0() { - const a$5 = {}; - const x$6 = a$5; - const y$7 = {}; - y$7.x = x$6; - mutate$4(a$5); + const $ = React.useMemoCache(); + let y$7; + if (true) { + const a$5 = {}; + const x$6 = a$5; + y$7 = {}; + y$7.x = x$6; + mutate$4(a$5); + $[0] = y$7; + } else { + y$7 = $[0]; + } + return y$7; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md index beba35c319..c735c95d29 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md @@ -44,11 +44,29 @@ function foo( ```javascript function foo$0() { - const x$4 = []; - const y$5 = { - x: x$4, - }; - y$5.x.push([]); + const $ = React.useMemoCache(); + let x$4; + if (true) { + x$4 = []; + $[0] = x$4; + } else { + x$4 = $[0]; + } + + const c_1 = $[1] !== x$4; + let y$5; + + if (c_1) { + y$5 = { + x: x$4, + }; + y$5.x.push([]); + $[1] = x$4; + $[2] = y$5; + } else { + y$5 = $[2]; + } + return y$5; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-2.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-2.expect.md index e820a41477..a3076dc2c2 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-2.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-2.expect.md @@ -43,10 +43,18 @@ function foo( ```javascript function foo$0() { - const x$4 = []; - const y$5 = {}; - y$5.x = x$4; - mutate$3(x$4); + const $ = React.useMemoCache(); + let y$5; + if (true) { + const x$4 = []; + y$5 = {}; + y$5.x = x$4; + mutate$3(x$4); + $[0] = y$5; + } else { + y$5 = $[0]; + } + return y$5; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-alias.expect.md index 8db27fee58..ae2b61e49a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-alias.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate-alias.expect.md @@ -48,11 +48,19 @@ function foo( ```javascript function foo$0() { - const a$5 = {}; - const y$6 = a$5; - const x$7 = []; - y$6.x = x$7; - mutate$4(a$5); + const $ = React.useMemoCache(); + let y$6; + if (true) { + const a$5 = {}; + y$6 = a$5; + const x$7 = []; + y$6.x = x$7; + mutate$4(a$5); + $[0] = y$6; + } else { + y$6 = $[0]; + } + return y$6; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate.expect.md index cd3ff5119c..43c242a1bf 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-mutate.expect.md @@ -43,10 +43,18 @@ function foo( ```javascript function foo$0() { - const x$4 = []; - const y$5 = {}; - y$5.x = x$4; - mutate$3(y$5); + const $ = React.useMemoCache(); + let y$5; + if (true) { + const x$4 = []; + y$5 = {}; + y$5.x = x$4; + mutate$3(y$5); + $[0] = y$5; + } else { + y$5 = $[0]; + } + return y$5; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md index d19d9b1978..f3c7564413 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md @@ -42,9 +42,27 @@ function foo( ```javascript function foo$0() { - const x$3 = []; - const y$4 = {}; - y$4.x = x$3; + const $ = React.useMemoCache(); + let x$3; + if (true) { + x$3 = []; + $[0] = x$3; + } else { + x$3 = $[0]; + } + + const c_1 = $[1] !== x$3; + let y$4; + + if (c_1) { + y$4 = {}; + y$4.x = x$3; + $[1] = x$3; + $[2] = y$4; + } else { + y$4 = $[2]; + } + return y$4; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md index a0d3d5f796..3e8133c3ef 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md @@ -52,9 +52,18 @@ function foo( ```javascript function foo$0() { - let x$4 = 1; - bb1: if (x$4 === 1) { - x$4 = 2; + const $ = React.useMemoCache(); + let x$4; + if (true) { + x$4 = 1; + + bb1: if (x$4 === 1) { + x$4 = 2; + } + + $[0] = x$4; + } else { + x$4 = $[0]; } return x$4; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md index 64ab1a4b1f..a408a6f2a8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md @@ -86,12 +86,23 @@ function Foo( ```javascript function Foo$0(cond$5) { - let str$6 = ""; - bb1: if (cond$5) { - const str$7 = "other test"; - log$4(str$7); + const $ = React.useMemoCache(); + const c_0 = $[0] !== cond$5; + let str$6; + if (c_0) { + str$6 = ""; + + bb1: if (cond$5) { + const str$7 = "other test"; + log$4(str$7); + } else { + str$6 = "fallthrough test"; + } + + $[0] = cond$5; + $[1] = str$6; } else { - str$6 = "fallthrough test"; + str$6 = $[1]; } log$4(str$6); diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-sibling-phis.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-sibling-phis.expect.md index c5f7613760..64c1323ae7 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-sibling-phis.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-sibling-phis.expect.md @@ -113,24 +113,49 @@ function foo( ```javascript function foo$0(a$9, b$10, c$11, d$12) { + const $ = React.useMemoCache(); const x$13 = 0; bb1: if (true) { - let x$16 = undefined; + const c_0 = $[0] !== a$9; + const c_1 = $[1] !== b$10; + let x$16; - bb3: if (true) { - x$16 = a$9; + if (c_0 || c_1) { + x$16 = undefined; + + bb3: if (true) { + x$16 = a$9; + } else { + x$16 = b$10; + } + + $[0] = a$9; + $[1] = b$10; + $[2] = x$16; } else { - x$16 = b$10; + x$16 = $[2]; } x$16; } else { - let x$20 = undefined; + const c_3 = $[3] !== c$11; + const c_4 = $[4] !== d$12; + let x$20; - bb7: if (true) { - x$20 = c$11; + if (c_3 || c_4) { + x$20 = undefined; + + bb7: if (true) { + x$20 = c$11; + } else { + x$20 = d$12; + } + + $[3] = c$11; + $[4] = d$12; + $[5] = x$20; } else { - x$20 = d$12; + x$20 = $[5]; } x$20; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md index cb2f21e3a2..89d4df4fba 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md @@ -65,12 +65,21 @@ function foo( ```javascript function foo$0() { + const $ = React.useMemoCache(); const y$5 = 2; - let y$8 = undefined; - bb1: if (y$5 > 1) { - y$8 = 1; + let y$8; + if (true) { + y$8 = undefined; + + bb1: if (y$5 > 1) { + y$8 = 1; + } else { + y$8 = 2; + } + + $[0] = y$8; } else { - y$8 = 2; + y$8 = $[0]; } const x$11 = y$8; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md index c5199a5ca3..e7fbc0e184 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md @@ -99,22 +99,31 @@ function foo( ```javascript function foo$0() { + const $ = React.useMemoCache(); const x$10 = 1; - let x$16 = undefined; - bb1: switch (x$10) { - case x$10 === 1: { - x$16 = x$10 + 1; - break bb1; + let x$16; + if (true) { + x$16 = undefined; + + bb1: switch (x$10) { + case x$10 === 1: { + x$16 = x$10 + 1; + break bb1; + } + + case x$10 === 2: { + x$16 = x$10 + 2; + break bb1; + } + + default: { + x$16 = x$10 + 3; + } } - case x$10 === 2: { - x$16 = x$10 + 2; - break bb1; - } - - default: { - x$16 = x$10 + 3; - } + $[0] = x$16; + } else { + x$16 = $[0]; } const y$22 = x$16; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md index f79cd4a9b3..a8ea84eaf4 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md @@ -51,9 +51,18 @@ function foo( ```javascript function foo$0() { - let x$4 = 1; - bb1: if (x$4 === 1) { - x$4 = 2; + const $ = React.useMemoCache(); + let x$4; + if (true) { + x$4 = 1; + + bb1: if (x$4 === 1) { + x$4 = 2; + } + + $[0] = x$4; + } else { + x$4 = $[0]; } throw x$4; diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md index 4bb10d26a1..5d95ec44a5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md @@ -59,9 +59,18 @@ function foo( ```javascript function foo$0() { - let x$5 = 1; - bb2: while (x$5 < 10) { - x$5 = x$5 + 1; + const $ = React.useMemoCache(); + let x$5; + if (true) { + x$5 = 1; + + bb2: while (x$5 < 10) { + x$5 = x$5 + 1; + } + + $[0] = x$5; + } else { + x$5 = $[0]; } return x$5; diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md index beb08d9a58..54fd534406 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md @@ -56,8 +56,8 @@ bb1: predecessor blocks: bb0 bb6 bb2 [12] Const mutate child$19_@2 = JSX [13] Call read y$11_@1.push(read props$9.p4) - [14] Const mutate $22_@3 = JSX {read child$19_@2} - [15] Return read $22_@3 + [14] Const mutate t7$22_@3 = JSX {read child$19_@2} + [15] Return read t7$22_@3 ``` ## Reactive Scopes @@ -105,31 +105,67 @@ function Component( ```javascript function Component$0(props$9) { - const x$10 = []; - let y$11 = undefined; - bb1: switch (props$9.p0) { - case 1: { - break bb1; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$9.p0; + const c_1 = $[1] !== props$9.p2; + let x$10; + if (c_0 || c_1) { + x$10 = []; + let y$11 = undefined; + + bb1: switch (props$9.p0) { + case 1: { + break bb1; + } + + case true: { + x$10.push(props$9.p2); + y$11 = []; + break bb1; + } + + default: { + break bb1; + } + + case false: { + y$11 = x$10; + } } - case true: { - x$10.push(props$9.p2); - y$11 = []; - break bb1; - } + $[0] = props$9.p0; + $[1] = props$9.p2; + $[2] = x$10; + } else { + x$10 = $[2]; + } - default: { - break bb1; - } + const c_3 = $[3] !== x$10; + let child$19; - case false: { - y$11 = x$10; - } + if (c_3) { + child$19 = ; + $[3] = x$10; + $[4] = child$19; + } else { + child$19 = $[4]; } - const child$19 = ; y$11.push(props$9.p4); - return {child$19}; + const c_5 = $[5] !== y$11; + const c_6 = $[6] !== child$19; + let t7$22; + + if (c_5 || c_6) { + t7$22 = {child$19}; + $[5] = y$11; + $[6] = child$19; + $[7] = t7$22; + } else { + t7$22 = $[7]; + } + + return t7$22; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md index f0f5e26938..e6caad23d1 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md @@ -50,8 +50,8 @@ bb1: predecessor blocks: bb2 bb0 [12] Const mutate child$19_@3 = JSX [13] Call read y$10_@1.push(read props$8.p4) - [14] Const mutate $23_@4 = JSX {read child$19_@3} - [15] Return read $23_@4 + [14] Const mutate t8$23_@4 = JSX {read child$19_@3} + [15] Return read t8$23_@4 ``` ## Reactive Scopes @@ -94,23 +94,65 @@ function Component( ```javascript function Component$0(props$8) { - const x$9 = []; - let y$10 = undefined; - bb1: switch (props$8.p0) { - case true: { - x$9.push(props$8.p2); - x$9.push(props$8.p3); - const y$13 = []; + const $ = React.useMemoCache(); + const c_0 = $[0] !== props$8.p0; + const c_1 = $[1] !== props$8.p2; + const c_2 = $[2] !== props$8.p3; + let x$9; + if (c_0 || c_1 || c_2) { + x$9 = []; + let y$10 = undefined; + + bb1: switch (props$8.p0) { + case true: { + x$9.push(props$8.p2); + x$9.push(props$8.p3); + + if (true) { + const y$13 = []; + } else { + } + } + + case false: { + y$10 = x$9; + } } - case false: { - y$10 = x$9; - } + $[0] = props$8.p0; + $[1] = props$8.p2; + $[2] = props$8.p3; + $[3] = x$9; + } else { + x$9 = $[3]; + } + + const c_4 = $[4] !== x$9; + let child$19; + + if (c_4) { + child$19 = ; + $[4] = x$9; + $[5] = child$19; + } else { + child$19 = $[5]; } - const child$19 = ; y$10.push(props$8.p4); - return {child$19}; + const c_6 = $[6] !== y$10; + const c_7 = $[7] !== child$19; + let t8$23; + + if (c_6 || c_7) { + t8$23 = {child$19}; + $[6] = y$10; + $[7] = child$19; + $[8] = t8$23; + } else { + t8$23 = $[8]; + } + + return t8$23; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/transitive-alias-fields.expect.md b/compiler/forget/src/__tests__/fixtures/hir/transitive-alias-fields.expect.md index 9b1dfc7620..0778a152a9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/transitive-alias-fields.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/transitive-alias-fields.expect.md @@ -56,14 +56,17 @@ function component( ```javascript function component$0() { - const x$6 = {}; - const p$7 = {}; - const q$8 = {}; - const y$9 = {}; - x$6.y = y$9; - p$7.y = x$6.y; - q$8.y = p$7.y; - mutate$5(q$8); + if (true) { + const x$6 = {}; + const p$7 = {}; + const q$8 = {}; + const y$9 = {}; + x$6.y = y$9; + p$7.y = x$6.y; + q$8.y = p$7.y; + mutate$5(q$8); + } else { + } } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-args-test-binary-operator.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-args-test-binary-operator.expect.md index af1b1172e2..a8d5db67d8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-args-test-binary-operator.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-args-test-binary-operator.expect.md @@ -48,7 +48,10 @@ function component( ```javascript function component$0(a$5, b$6) { bb1: if (a$5 > b$6) { - const m$8 = {}; + if (true) { + const m$8 = {}; + } else { + } } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md index f2962b76b3..753ec5987a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-binary-operator.expect.md @@ -55,10 +55,29 @@ function component( ```javascript function component$0() { - const a$7 = some$2(); - const b$8 = someOther$4(); + const $ = React.useMemoCache(); + let a$7; + if (true) { + a$7 = some$2(); + $[0] = a$7; + } else { + a$7 = $[0]; + } + + let b$8; + + if (true) { + b$8 = someOther$4(); + $[1] = b$8; + } else { + b$8 = $[1]; + } + bb1: if (a$7 > b$8) { - const m$10 = {}; + if (true) { + const m$10 = {}; + } else { + } } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md index 78e3814330..297abfb7f5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-field-load.expect.md @@ -38,9 +38,17 @@ function component( ```javascript function component$0() { - const x$5 = { - t: 1, - }; + const $ = React.useMemoCache(); + let x$5; + if (true) { + x$5 = { + t: 1, + }; + $[0] = x$5; + } else { + x$5 = $[0]; + } + const p$6 = x$5.t; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md index 63a90619ea..7c330b5dc8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-load-binary-op.expect.md @@ -19,9 +19,9 @@ function component() { ``` bb0: - [1] Const mutate $10_@0:TPrimitive = Call mutate makeSomePrimitive$2:TFunction() - [2] Const mutate $11_@1:TPrimitive = Call mutate makeSomePrimitive$2:TFunction() - [3] Const mutate x$12_@2:TObject = Object { u: read $10_@0:TPrimitive, v: read $11_@1:TPrimitive } + [1] Const mutate t0$10_@0:TPrimitive = Call mutate makeSomePrimitive$2:TFunction() + [2] Const mutate t1$11_@1:TPrimitive = Call mutate makeSomePrimitive$2:TFunction() + [3] Const mutate x$12_@2:TObject = Object { u: read t0$10_@0:TPrimitive, v: read t1$11_@1:TPrimitive } [4] Const mutate u$13:TPrimitive = read x$12_@2.u [5] Const mutate v$14:TPrimitive = read x$12_@2.v [6] Const mutate $15:TPrimitive = Binary read u$13:TPrimitive > read v$14:TPrimitive @@ -63,12 +63,43 @@ function component( ```javascript function component$0() { - const x$12 = { - u: makeSomePrimitive$2(), - v: makeSomePrimitive$2(), - }; + const $ = React.useMemoCache(); + let t0$10; + if (true) { + t0$10 = makeSomePrimitive$2(); + $[0] = t0$10; + } else { + t0$10 = $[0]; + } + + let t1$11; + + if (true) { + t1$11 = makeSomePrimitive$2(); + $[1] = t1$11; + } else { + t1$11 = $[1]; + } + + const c_2 = $[2] !== t0$10; + const c_3 = $[3] !== t1$11; + let x$12; + + if (c_2 || c_3) { + x$12 = { + u: t0$10, + v: t1$11, + }; + $[2] = t0$10; + $[3] = t1$11; + $[4] = x$12; + } else { + x$12 = $[4]; + } + const u$13 = x$12.u; const v$14 = x$12.v; + bb1: if (u$13 > v$14) { } diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md index c8b147bc87..50ce73d71a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-field-store.expect.md @@ -44,9 +44,22 @@ function component( ```javascript function component$0() { - const x$4 = {}; - const q$5 = {}; - x$4.t = q$5; + const $ = React.useMemoCache(); + let x$4; + if (true) { + x$4 = {}; + + if (true) { + const q$5 = {}; + } else { + } + + x$4.t = q$5; + $[0] = x$4; + } else { + x$4 = $[0]; + } + const z$6 = x$4.t; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md index 584cd5b977..0a3718cd4d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-polymorphic.expect.md @@ -61,13 +61,41 @@ function component( ```javascript function component$0() { - const p$7 = makePrimitive$2(); + const $ = React.useMemoCache(); + let p$7; + if (true) { + p$7 = makePrimitive$2(); + $[0] = p$7; + } else { + p$7 = $[0]; + } + p$7 + p$7; - const o$8 = {}; - const x$9 = {}; - x$9.t = p$7; - const z$10 = x$9.t; - x$9.t = o$8; + let o$8; + + if (true) { + o$8 = {}; + $[1] = o$8; + } else { + o$8 = $[1]; + } + + const c_2 = $[2] !== p$7; + const c_3 = $[3] !== o$8; + let x$9; + + if (c_2 || c_3) { + x$9 = {}; + x$9.t = p$7; + const z$10 = x$9.t; + x$9.t = o$8; + $[2] = p$7; + $[3] = o$8; + $[4] = x$9; + } else { + x$9 = $[4]; + } + const y$11 = x$9.t; } diff --git a/compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md b/compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md index 9face07b07..de4c0edc16 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/type-test-return-type-inference.expect.md @@ -61,13 +61,35 @@ function component( ```javascript function component$0() { - const x$7 = foo$2(); - const y$8 = foo$2(); - bb1: if (x$7 > y$8) { - const z$10 = {}; + const $ = React.useMemoCache(); + let x$7; + if (true) { + x$7 = foo$2(); + $[0] = x$7; + } else { + x$7 = $[0]; } - const z$12 = foo$2(); + let y$8; + + if (true) { + y$8 = foo$2(); + $[1] = y$8; + } else { + y$8 = $[1]; + } + + bb1: if (x$7 > y$8) { + if (true) { + const z$10 = {}; + } else { + } + } + + if (true) { + const z$12 = foo$2(); + } else { + } } ```