diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts b/compiler/forget/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts index 0cffa408c7..2d91fd5ad1 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts +++ b/compiler/forget/packages/babel-plugin-react-forget/src/SSA/EliminateRedundantPhi.ts @@ -46,7 +46,6 @@ export function eliminateRedundantPhi( // compare to see if any new rewrites were added in that iteration. let size = rewrites.size; do { - const isFirstIteration = !hasBackEdge; size = rewrites.size; for (const [blockId, block] of ir.blocks) { // On the first iteration of the loop check for any back-edges. @@ -116,10 +115,10 @@ export function eliminateRedundantPhi( rewritePlace(place, rewrites); } - // visit function expressions on first iteration of each block - if (isFirstIteration) { - eliminateRedundantPhi(instr.value.loweredFunc, rewrites); - } + // recursive call to: + // - eliminate phi nodes in child node + // - propagate rewrites, which may have changed between iterations + eliminateRedundantPhi(instr.value.loweredFunc, rewrites); } } diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/e2e/constant-prop.e2e.js b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/e2e/constant-prop.e2e.js index 3446030107..dfb68b2ce5 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/e2e/constant-prop.e2e.js +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/e2e/constant-prop.e2e.js @@ -96,6 +96,11 @@ test("lambda-constant-propagation-of-phi-node", () => { if (constantValue) { noopCallback(); } + for (let i = 0; i < 5; i++) { + if (!constantValue) { + noopCallback(); + } + } const getDiv = () =>
{x}
; return getDiv(); } diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rewrite-phis-in-lambda-capture-context.expect.md b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rewrite-phis-in-lambda-capture-context.expect.md index fbf001317a..a94b4e7c94 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rewrite-phis-in-lambda-capture-context.expect.md +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rewrite-phis-in-lambda-capture-context.expect.md @@ -2,13 +2,19 @@ ## Input ```javascript -function ConstantPropagationBug() { - const x = CONSTANT1; - const createPhiNode = CONSTANT2 || 5; +function Component() { + const x = 4; - const getFoo = () => ; + const get4 = () => { + while (bar()) { + if (baz) { + bar(); + } + } + return () => x; + }; - return getFoo(); + return get4; } ``` @@ -17,26 +23,24 @@ function ConstantPropagationBug() { ```javascript import { unstable_useMemoCache as useMemoCache } from "react"; -function ConstantPropagationBug() { - const $ = useMemoCache(2); - - const createPhiNode = CONSTANT2 || 5; +function Component() { + const $ = useMemoCache(1); let t0; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { - t0 = () => ; + t0 = () => { + while (bar()) { + if (baz) { + bar(); + } + } + return () => 4; + }; $[0] = t0; } else { t0 = $[0]; } - const getFoo = t0; - let t1; - if ($[1] === Symbol.for("react.memo_cache_sentinel")) { - t1 = getFoo(); - $[1] = t1; - } else { - t1 = $[1]; - } - return t1; + const get4 = t0; + return get4; } ``` diff --git a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rewrite-phis-in-lambda-capture-context.js b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rewrite-phis-in-lambda-capture-context.js index 8ed131ece9..9d6fec2f61 100644 --- a/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rewrite-phis-in-lambda-capture-context.js +++ b/compiler/forget/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/rewrite-phis-in-lambda-capture-context.js @@ -1,8 +1,14 @@ -function ConstantPropagationBug() { - const x = CONSTANT1; - const createPhiNode = CONSTANT2 || 5; +function Component() { + const x = 4; - const getFoo = () => ; + const get4 = () => { + while (bar()) { + if (baz) { + bar(); + } + } + return () => x; + }; - return getFoo(); + return get4; }