diff --git a/compiler/forget/src/HIR/EnterSSA.ts b/compiler/forget/src/HIR/EnterSSA.ts index 6cf31edec6..4d6c835620 100644 --- a/compiler/forget/src/HIR/EnterSSA.ts +++ b/compiler/forget/src/HIR/EnterSSA.ts @@ -121,6 +121,7 @@ class SSABuilder { const phi: Phi = { kind: "Phi", id: newId, + oldId, operands: predDefs, }; diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index 4bb1c6c363..315de05ea6 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -193,6 +193,7 @@ export type InstructionValue = export type Phi = { kind: "Phi"; id: Identifier; + oldId: Identifier; operands: Map; }; diff --git a/compiler/forget/src/HIR/LeaveSSA.ts b/compiler/forget/src/HIR/LeaveSSA.ts new file mode 100644 index 0000000000..ae1684483a --- /dev/null +++ b/compiler/forget/src/HIR/LeaveSSA.ts @@ -0,0 +1,50 @@ +import { invariant } from "../CompilerError"; +import { HIRFunction, Identifier, Place } from "./HIR"; +import { eachInstructionOperand, eachTerminalOperand } from "./visitors"; + +export default function leaveSSA(fn: HIRFunction) { + const ir = fn.body; + const entryBlock = ir.blocks.get(ir.entry); + invariant(entryBlock, "expected to find the entry basic block"); + const originalIdMap = new Map< + /* SSA'd id */ Identifier, + /* original id*/ Identifier + >(); + + for (const [, block] of ir.blocks) { + for (const phi of block.phis) { + originalIdMap.set(phi.id, phi.oldId); + for (const [, ssaId] of phi.operands) { + originalIdMap.set(ssaId, phi.oldId); + } + } + block.phis.clear(); + } + + if (originalIdMap.size === 0) { + return; + } + + function tryRewrite(place: Place) { + const originalId = originalIdMap.get(place.identifier); + if (originalId != null) { + place.identifier = originalId; + } + } + + for (const [, block] of ir.blocks) { + for (const instr of block.instructions) { + // LValues also need to be rewritten as they might be declaring or reassigning an identifier + // that was previously SSA'd. + if (instr.lvalue != null) { + tryRewrite(instr.lvalue.place); + } + for (const place of eachInstructionOperand(instr)) { + tryRewrite(place); + } + } + for (const place of eachTerminalOperand(block.terminal)) { + tryRewrite(place); + } + } +} diff --git a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md index fb91041897..ce590067ce 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md @@ -52,16 +52,15 @@ bb3: If (read $36) then:bb8 else:bb9 bb8: predecessor blocks: bb3 - [9] Const mutate $37 = read $36 + [9] Const mutate $13 = read $36 Goto bb7 bb9: predecessor blocks: bb3 - [10] Const mutate $39 = Call mutate seen$30.has(mutate item$10) + [10] Const mutate $13 = Call mutate seen$30.has(mutate item$10) Goto bb7 bb7: predecessor blocks: bb8 bb9 - $40: phi(bb8: $37, bb9: $39) - If (read $40) then:bb1 else:bb4 + If (read $13) then:bb1 else:bb4 bb4: predecessor blocks: bb7 [11] Call mutate seen$30.add(mutate item$10) 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 cedbeacbf1..5a350ddf60 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 @@ -32,19 +32,18 @@ bb0: If (read cond$8) then:bb2 else:bb3 bb2: predecessor blocks: bb0 - [4] Reassign mutate a$11 = read x$9 + [4] Reassign mutate a$4 = read x$9 Goto bb1 bb3: predecessor blocks: bb0 - [5] Reassign mutate a$12 = Array [] + [5] Reassign mutate a$4 = Array [] Goto bb1 bb1: predecessor blocks: bb2 bb3 - a$14: phi(bb2: a$11, bb3: a$12) - [6] Call read useFreeze$5(freeze a$14) - [7] Call read useFreeze$5(read a$14) - [8] Call mutate call$6(read a$14) - Return read a$14 + [6] Call read useFreeze$5(freeze a$4) + [7] Call read useFreeze$5(read a$4) + [8] Call mutate call$6(read a$4) + Return read a$4 ``` ## Code @@ -55,15 +54,15 @@ function Component$0(props$7) { const x$9 = props$7.x; let a$10 = undefined; bb1: if (cond$8) { - a$11 = x$9; + a$4 = x$9; } else { - a$12 = []; + a$4 = []; } - useFreeze$5(a$14); - useFreeze$5(a$14); - call$6(a$14); - return a$14; + useFreeze$5(a$4); + useFreeze$5(a$4); + call$6(a$4); + return a$4; } ``` 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 074ea39abd..21669b28f6 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md @@ -27,16 +27,15 @@ bb0: If (read $5) then:bb2 else:bb3 bb2: predecessor blocks: bb0 - [2] Const mutate $6 = Call mutate g$4() + [2] Const mutate $3 = Call mutate g$4() Goto bb1 bb3: predecessor blocks: bb0 - [3] Const mutate $7 = read $5 + [3] Const mutate $3 = read $5 Goto bb1 bb1: predecessor blocks: bb2 bb3 - $8: phi(bb2: $6, bb3: $7) - Return freeze $8 + Return freeze $3 ``` ## Code @@ -46,7 +45,7 @@ function And$0() { bb1: if (f$1()) { } else { } - return t8; + return f$1(); } ``` @@ -58,16 +57,15 @@ bb0: If (read $5) then:bb2 else:bb3 bb2: predecessor blocks: bb0 - [2] Const mutate $6 = read $5 + [2] Const mutate $3 = read $5 Goto bb1 bb3: predecessor blocks: bb0 - [3] Const mutate $7 = Call mutate g$4() + [3] Const mutate $3 = Call mutate g$4() Goto bb1 bb1: predecessor blocks: bb2 bb3 - $8: phi(bb2: $6, bb3: $7) - Return freeze $8 + Return freeze $3 ``` ## Code @@ -77,7 +75,7 @@ function Or$0() { bb1: if (f$1()) { } else { } - return t8; + return g$4(); } ``` @@ -91,16 +89,15 @@ bb0: If (read $11) then:bb2 else:bb3 bb2: predecessor blocks: bb0 - [4] Const mutate $12 = read $9 + [4] Const mutate $6 = read $9 Goto bb1 bb3: predecessor blocks: bb0 - [5] Const mutate $13 = Call mutate g$7() + [5] Const mutate $6 = Call mutate g$7() Goto bb1 bb1: predecessor blocks: bb2 bb3 - $14: phi(bb2: $12, bb3: $13) - Return freeze $14 + Return freeze $6 ``` ## Code @@ -110,7 +107,7 @@ function QuestionQuestion$0(props$8) { bb1: if (f$2() != null) { } else { } - return t14; + return g$7(); } ``` 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 3ebca18d96..8b0c352270 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 @@ -73,49 +73,41 @@ function cond$0(x$2) { ``` bb0: - [1] Let mutate a$13 = Object { } - [2] Let mutate b$14 = Object { } - [3] Let mutate c$15 = Object { } - [4] Let mutate d$16 = Object { } + [1] Let mutate a$2 = Object { } + [2] Let mutate b$3 = Object { } + [3] Let mutate c$4 = Object { } + [4] Let mutate d$5 = Object { } Goto bb1 bb1: predecessor blocks: bb0 bb3 - a$18: phi(bb0: a$13, bb3: a$21) - b$20: phi(bb0: b$14, bb3: b$23) - c$22: phi(bb0: c$15, bb3: c$25) - d$24: phi(bb0: d$16, bb3: d$26) [5] Const mutate $17 = true If (read $17) then:bb3 else:bb2 bb3: predecessor blocks: bb1 - [6] Let mutate z$19 = read a$18 - [7] Reassign mutate a$21[7:12] = read b$20 - [8] Reassign mutate b$23[8:11] = read c$22 - [9] Reassign mutate c$25 = read d$24 - [10] Reassign mutate d$26 = read z$19 - [11] Call mutate mutate$7(mutate a$21, mutate b$23) - [12] Const mutate $29 = Call mutate cond$8(mutate a$21) + [6] Let mutate z$19 = read a$2 + [7] Reassign mutate a$2 = read b$3 + [8] Reassign mutate b$3 = read c$4 + [9] Reassign mutate c$4 = read d$5 + [10] Reassign mutate d$5 = read z$19 + [11] Call mutate mutate$7(mutate a$2, mutate b$3) + [12] Const mutate $29 = Call mutate cond$8(mutate a$2) If (read $29) then:bb2 else:bb1 bb2: predecessor blocks: bb3 bb1 - a$30: phi(bb3: a$21, bb1: a$18) - b$31: phi(bb3: b$23, bb1: b$20) - c$32: phi(bb3: c$25, bb1: c$22) - d$33[-1:14]: phi(bb3: d$26, bb1: d$24) - If (read a$30) then:bb7 else:bb7 + If (read a$2) then:bb7 else:bb7 bb7: predecessor blocks: bb2 - If (read b$31) then:bb9 else:bb9 + If (read b$3) then:bb9 else:bb9 bb9: predecessor blocks: bb7 - If (read c$32) then:bb11 else:bb11 + If (read c$4) then:bb11 else:bb11 bb11: predecessor blocks: bb9 - If (read d$33) then:bb13 else:bb13 + If (read d$5) then:bb13 else:bb13 bb13: predecessor blocks: bb11 [13] Const mutate $34 = null - [14] Call mutate mutate$7(mutate d$33, read $34) + [14] Call mutate mutate$7(mutate d$5, read $34) Return ``` @@ -123,10 +115,10 @@ bb13: ```javascript function Component$0(props$12) { - let a$13 = {}; - let b$14 = {}; - let c$15 = {}; - let d$16 = {}; + let a$2 = {}; + let b$3 = {}; + let c$4 = {}; + let d$5 = {}; } ``` 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 527df2ecd4..7ae0a7c8ab 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md @@ -23,20 +23,19 @@ function Component(props) { ``` bb0: - [1] Let mutate x$7[1:2] = Array [] - [2] Call mutate x$7.push(read props$6.p0) - [3] Let mutate y$8 = read x$7 + [1] Let mutate x$2 = Array [] + [2] Call mutate x$2.push(read props$6.p0) + [3] Let mutate y$8 = read x$2 If (read props$6.p1) then:bb2 else:bb1 bb2: predecessor blocks: bb0 - [4] Reassign mutate x$9 = Array [] + [4] Reassign mutate x$2 = Array [] Goto bb1 bb1: predecessor blocks: bb2 bb0 - x$11: phi(bb2: x$9, bb0: x$7) - [5] Let mutate _$12 = JSX + [5] Let mutate _$12 = JSX [6] Call read y$8.push(read props$6.p2) - [7] Const mutate $15 = JSX + [7] Const mutate $15 = JSX Return read $15 ``` @@ -44,17 +43,17 @@ bb1: ```javascript function Component$0(props$6) { - let x$7 = []; - x$7.push(props$6.p0); - let y$8 = x$7; + let x$2 = []; + x$2.push(props$6.p0); + let y$8 = x$2; bb1: if (props$6.p1) { - x$9 = []; + x$2 = []; } - let _$12 = ; + let _$12 = ; y$8.push(props$6.p2); - return ; + return ; } ``` 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 8ba7c8b9ce..79b996bb94 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md @@ -50,31 +50,30 @@ bb2: Default: bb4 bb8: predecessor blocks: bb2 - [5] Reassign mutate x$11 = read props$6.v0 + [5] Reassign mutate x$2 = read props$6.v0 Goto bb1 bb6: predecessor blocks: bb2 - [6] Reassign mutate x$12 = read props$6.v1 + [6] Reassign mutate x$2 = read props$6.v1 Goto bb1 bb4: predecessor blocks: bb2 - [7] Reassign mutate x$13 = read props$6.v2 + [7] Reassign mutate x$2 = read props$6.v2 Goto bb1 bb10: predecessor blocks: bb0 If (read props$6.cond2) then:bb12 else:bb13 bb12: predecessor blocks: bb10 - [8] Reassign mutate x$14 = read props$6.b + [8] Reassign mutate x$2 = read props$6.b Goto bb1 bb13: predecessor blocks: bb10 - [9] Reassign mutate x$15 = read props$6.c + [9] Reassign mutate x$2 = read props$6.c Goto bb1 bb1: predecessor blocks: bb8 bb6 bb4 bb12 bb13 - x$16: phi(bb8: x$11, bb6: x$12, bb4: x$13, bb12: x$14, bb13: x$15) - [10] read x$16 + [10] read x$2 Return ``` @@ -86,12 +85,12 @@ function Component$0(props$6) { bb1: if (props$6.cond) { switch (props$6.test) { case 0: { - x$11 = props$6.v0; + x$2 = props$6.v0; break bb1; } case 1: { - x$12 = props$6.v1; + x$2 = props$6.v1; break bb1; } @@ -99,18 +98,18 @@ function Component$0(props$6) { } default: { - x$13 = props$6.v2; + x$2 = props$6.v2; } } } else { if (props$6.cond2) { - x$14 = props$6.b; + x$2 = props$6.b; } else { - x$15 = props$6.c; + x$2 = props$6.c; } } - x$16; + x$2; return; } 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 7e66da4401..a57cbf2203 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 @@ -21,29 +21,27 @@ function foo() { ``` bb0: - [1] Let mutate x$7 = 1 + [1] Let mutate x$1 = 1 [2] Let mutate y$8 = 2 [3] Const mutate $9 = 2 [4] Const mutate $10 = Binary read y$8 === read $9 If (read $10) then:bb2 else:bb1 bb2: predecessor blocks: bb0 - [5] Reassign mutate x$11 = 3 + [5] Reassign mutate x$1 = 3 Goto bb1 bb1: predecessor blocks: bb2 bb0 - x$17: phi(bb2: x$11, bb0: x$7) [6] Const mutate $12 = 3 [7] Const mutate $14 = Binary read y$8 === read $12 If (read $14) then:bb4 else:bb3 bb4: predecessor blocks: bb1 - [8] Reassign mutate x$15 = 5 + [8] Reassign mutate x$1 = 5 Goto bb3 bb3: predecessor blocks: bb4 bb1 - x$16: phi(bb4: x$15, bb1: x$17) - [9] Reassign mutate y$18 = read x$16 + [9] Reassign mutate y$18 = read x$1 Return ``` @@ -51,17 +49,17 @@ bb3: ```javascript function foo$0() { - let x$7 = 1; + let x$1 = 1; let y$8 = 2; bb1: if (y$8 === 2) { - x$11 = 3; + x$1 = 3; } bb3: if (y$8 === 3) { - x$15 = 5; + x$1 = 5; } - y$18 = x$16; + y$18 = x$1; return; } 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 ad136317dd..79dedcc9c2 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 @@ -18,19 +18,18 @@ function foo() { ``` bb0: - [1] Let mutate x$5 = 1 + [1] Let mutate x$1 = 1 [2] Let mutate y$6 = 2 [3] Const mutate $7 = 2 [4] Const mutate $8 = Binary read y$6 === read $7 If (read $8) then:bb2 else:bb1 bb2: predecessor blocks: bb0 - [5] Reassign mutate x$9 = 3 + [5] Reassign mutate x$1 = 3 Goto bb1 bb1: predecessor blocks: bb2 bb0 - x$10: phi(bb2: x$9, bb0: x$5) - [6] Reassign mutate y$11 = read x$10 + [6] Reassign mutate y$11 = read x$1 Return ``` @@ -38,13 +37,13 @@ bb1: ```javascript function foo$0() { - let x$5 = 1; + let x$1 = 1; let y$6 = 2; bb1: if (y$6 === 2) { - x$9 = 3; + x$1 = 3; } - y$11 = x$10; + y$11 = x$1; return; } 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 dfe24fe2df..d3c9fc45f6 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md @@ -16,29 +16,28 @@ function foo() { ``` bb0: - [1] Let mutate x$5 = 0 + [1] Let mutate x$1 = 0 Goto bb1 bb1: predecessor blocks: bb0 bb4 - x$7: phi(bb0: x$5, bb4: x$10) [2] Const mutate $6 = 10 - [3] Const mutate $8 = Binary read x$7 < read $6 + [3] Const mutate $8 = Binary read x$1 < read $6 If (read $8) then:bb4 else:bb2 bb4: predecessor blocks: bb1 [4] Const mutate $9 = 1 - [5] Reassign mutate x$10 = Binary read x$7 + read $9 + [5] Reassign mutate x$1 = Binary read x$1 + read $9 Goto bb1 bb2: predecessor blocks: bb1 - Return read x$7 + Return read x$1 ``` ## Code ```javascript function foo$0() { - let x$5 = 0; + let x$1 = 0; } ``` 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 8729e4112b..05faad4bfc 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 @@ -22,24 +22,22 @@ function foo() { ``` bb0: - [1] Let mutate x$6 = 1 - [2] Let mutate y$7 = 2 + [1] Let mutate x$1 = 1 + [2] Let mutate y$2 = 2 [3] Const mutate $8 = 1 - [4] Const mutate $9 = Binary read x$6 > read $8 + [4] Const mutate $9 = Binary read x$1 > read $8 If (read $9) then:bb2 else:bb3 bb2: predecessor blocks: bb0 - [5] Reassign mutate x$10 = 2 + [5] Reassign mutate x$1 = 2 Goto bb1 bb3: predecessor blocks: bb0 - [6] Reassign mutate y$11 = 3 + [6] Reassign mutate y$2 = 3 Goto bb1 bb1: predecessor blocks: bb2 bb3 - x$12: phi(bb2: x$10, bb3: x$6) - y$13: phi(bb2: y$7, bb3: y$11) - [7] Let mutate t$14 = Object { x: read x$12, y: read y$13 } + [7] Let mutate t$14 = Object { x: read x$1, y: read y$2 } Return freeze t$14 ``` @@ -47,17 +45,17 @@ bb1: ```javascript function foo$0() { - let x$6 = 1; - let y$7 = 2; - bb1: if (x$6 > 1) { - x$10 = 2; + let x$1 = 1; + let y$2 = 2; + bb1: if (x$1 > 1) { + x$1 = 2; } else { - y$11 = 3; + y$2 = 3; } let t$14 = { - x: x$12, - y: y$13, + x: x$1, + y: y$2, }; return t$14; } 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 d291e97cef..09cc1158a0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md @@ -17,30 +17,29 @@ function foo() { ``` bb0: - [1] Let mutate x$4 = 1 + [1] Let mutate x$1 = 1 [2] Const mutate $5 = 1 - [3] Const mutate $6 = Binary read x$4 === read $5 + [3] Const mutate $6 = Binary read x$1 === read $5 If (read $6) then:bb2 else:bb1 bb2: predecessor blocks: bb0 - [4] Reassign mutate x$7 = 2 + [4] Reassign mutate x$1 = 2 Goto bb1 bb1: predecessor blocks: bb2 bb0 - x$8: phi(bb2: x$7, bb0: x$4) - Return read x$8 + Return read x$1 ``` ## Code ```javascript function foo$0() { - let x$4 = 1; - bb1: if (x$4 === 1) { - x$7 = 2; + let x$1 = 1; + bb1: if (x$1 === 1) { + x$1 = 2; } - return x$8; + return x$1; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md new file mode 100644 index 0000000000..f210b0f70b --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md @@ -0,0 +1,73 @@ + +## Input + +```javascript +function log() {} + +function Foo(cond) { + let str = ""; + if (cond) { + let str = "other test"; + log(str); + } else { + str = "fallthrough test"; + } + log(str); +} + +``` + +## HIR + +``` +bb0: + Return +``` + +## Code + +```javascript +function log$0() { + return; +} + +``` +## HIR + +``` +bb0: + [1] Let mutate str$2 = "" + If (read cond$5) then:bb2 else:bb3 +bb2: + predecessor blocks: bb0 + [2] Let mutate str$7 = "other test" + [3] Call mutate log$4(read str$7) + Goto bb1 +bb3: + predecessor blocks: bb0 + [4] Reassign mutate str$2 = "fallthrough test" + Goto bb1 +bb1: + predecessor blocks: bb2 bb3 + [5] Call mutate log$4(read str$2) + Return +``` + +## Code + +```javascript +function Foo$0(cond$5) { + let str$2 = ""; + bb1: if (cond$5) { + let str$7 = "other test"; + log$4(str$7); + } else { + str$2 = "fallthrough test"; + } + + log$4(str$2); + return; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.js b/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.js new file mode 100644 index 0000000000..5fd9bb75d2 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.js @@ -0,0 +1,12 @@ +function log() {} + +function Foo(cond) { + let str = ""; + if (cond) { + let str = "other test"; + log(str); + } else { + str = "fallthrough test"; + } + log(str); +} 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 c60ef6bdb5..a4e9a1d1b8 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 @@ -26,16 +26,15 @@ bb0: If (read $7) then:bb2 else:bb3 bb2: predecessor blocks: bb0 - [4] Reassign mutate y$8 = 1 + [4] Reassign mutate y$1 = 1 Goto bb1 bb3: predecessor blocks: bb0 - [5] Reassign mutate y$9 = 2 + [5] Reassign mutate y$1 = 2 Goto bb1 bb1: predecessor blocks: bb2 bb3 - y$10: phi(bb2: y$8, bb3: y$9) - [6] Let mutate x$11 = read y$10 + [6] Let mutate x$11 = read y$1 Return ``` @@ -45,12 +44,12 @@ bb1: function foo$0() { let y$5 = 2; bb1: if (y$5 > 1) { - y$8 = 1; + y$1 = 1; } else { - y$9 = 2; + y$1 = 2; } - let x$11 = y$10; + let x$11 = y$1; return; } 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 cf3506a2dd..34e0f1cf89 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md @@ -40,22 +40,21 @@ bb0: bb5: predecessor blocks: bb0 [6] Const mutate $15 = 1 - [7] Reassign mutate x$16 = Binary read x$10 + read $15 + [7] Reassign mutate x$1 = Binary read x$10 + read $15 Goto bb1 bb3: predecessor blocks: bb0 [8] Const mutate $17 = 2 - [9] Reassign mutate x$18 = Binary read x$10 + read $17 + [9] Reassign mutate x$1 = Binary read x$10 + read $17 Goto bb1 bb2: predecessor blocks: bb0 [10] Const mutate $19 = 3 - [11] Reassign mutate x$20 = Binary read x$10 + read $19 + [11] Reassign mutate x$1 = Binary read x$10 + read $19 Goto bb1 bb1: predecessor blocks: bb5 bb3 bb2 - x$21: phi(bb5: x$16, bb3: x$18, bb2: x$20) - [12] Let mutate y$22 = read x$21 + [12] Let mutate y$22 = read x$1 Return ``` @@ -66,21 +65,21 @@ function foo$0() { let x$10 = 1; bb1: switch (x$10) { case x$10 === 1: { - x$16 = x$10 + 1; + x$1 = x$10 + 1; break bb1; } case x$10 === 2: { - x$18 = x$10 + 2; + x$1 = x$10 + 2; break bb1; } default: { - x$20 = x$10 + 3; + x$1 = x$10 + 3; } } - let y$22 = x$21; + let y$22 = x$1; return; } 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 03269a912a..82958321a0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md @@ -16,30 +16,29 @@ function foo() { ``` bb0: - [1] Let mutate x$4 = 1 + [1] Let mutate x$1 = 1 [2] Const mutate $5 = 1 - [3] Const mutate $6 = Binary read x$4 === read $5 + [3] Const mutate $6 = Binary read x$1 === read $5 If (read $6) then:bb2 else:bb1 bb2: predecessor blocks: bb0 - [4] Reassign mutate x$7 = 2 + [4] Reassign mutate x$1 = 2 Goto bb1 bb1: predecessor blocks: bb2 bb0 - x$8: phi(bb2: x$7, bb0: x$4) - Throw read x$8 + Throw read x$1 ``` ## Code ```javascript function foo$0() { - let x$4 = 1; - bb1: if (x$4 === 1) { - x$7 = 2; + let x$1 = 1; + bb1: if (x$1 === 1) { + x$1 = 2; } - throw x$8; + throw x$1; } ``` 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 7c76dda790..1c723cef31 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md @@ -17,29 +17,28 @@ function foo() { ``` bb0: - [1] Let mutate x$5 = 1 + [1] Let mutate x$1 = 1 Goto bb1 bb1: predecessor blocks: bb0 bb3 - x$7: phi(bb0: x$5, bb3: x$10) [2] Const mutate $6 = 10 - [3] Const mutate $8 = Binary read x$7 < read $6 + [3] Const mutate $8 = Binary read x$1 < read $6 If (read $8) then:bb3 else:bb2 bb3: predecessor blocks: bb1 [4] Const mutate $9 = 1 - [5] Reassign mutate x$10 = Binary read x$7 + read $9 + [5] Reassign mutate x$1 = Binary read x$1 + read $9 Goto bb1 bb2: predecessor blocks: bb1 - Return read x$7 + Return read x$1 ``` ## Code ```javascript function foo$0() { - let x$5 = 1; + let x$1 = 1; } ``` 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 9e8546f4d6..ab7d946d2d 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 @@ -33,7 +33,7 @@ function Component(props) { ``` bb0: [1] Let mutate x$10[1:6] = Array [] - [2] Let mutate y$11 = undefined + [2] Let mutate y$3 = undefined [3] Const mutate $12 = false [4] Const mutate $13 = true [5] Const mutate $14 = 1 @@ -45,18 +45,17 @@ bb0: bb6: predecessor blocks: bb0 [6] Call mutate x$10.push(read props$9.p2) - [7] Reassign mutate y$15 = Array [] + [7] Reassign mutate y$3 = Array [] Goto bb1 bb2: predecessor blocks: bb0 - [8] Reassign mutate y$16 = read x$10 + [8] Reassign mutate y$3 = read x$10 Goto bb1 bb1: predecessor blocks: bb0 bb6 bb2 - y$20: phi(bb0: y$11, bb6: y$15, bb2: y$16) [9] Const mutate child$19 = JSX - [10] Call read y$20.push(read props$9.p4) - [11] Const mutate $22 = JSX {read child$19} + [10] Call read y$3.push(read props$9.p4) + [11] Const mutate $22 = JSX {read child$19} Return read $22 ``` @@ -65,7 +64,7 @@ bb1: ```javascript function Component$0(props$9) { let x$10 = []; - let y$11 = undefined; + let y$3 = undefined; bb1: switch (props$9.p0) { case 1: { break bb1; @@ -73,7 +72,7 @@ function Component$0(props$9) { case true: { x$10.push(props$9.p2); - y$15 = []; + y$3 = []; break bb1; } @@ -82,13 +81,13 @@ function Component$0(props$9) { } case false: { - y$16 = x$10; + y$3 = x$10; } } const child$19 = ; - y$20.push(props$9.p4); - return {child$19}; + y$3.push(props$9.p4); + return {child$19}; } ``` diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md index 385a690ad2..7ff960925a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md @@ -29,7 +29,7 @@ function Component(props) { ``` bb0: [1] Let mutate x$9[1:6] = Array [] - [2] Let mutate y$10 = undefined + [2] Let mutate y$3 = undefined [3] Const mutate $11 = false [4] Const mutate $12 = true Switch (read props$8.p0) @@ -44,14 +44,13 @@ bb4: Goto bb2 bb2: predecessor blocks: bb4 bb0 - [8] Reassign mutate y$15 = read x$9 + [8] Reassign mutate y$3 = read x$9 Goto bb1 bb1: predecessor blocks: bb2 bb0 - y$20: phi(bb2: y$15, bb0: y$10) [9] Const mutate child$19 = JSX - [10] Call read y$20.push(read props$8.p4) - [11] Const mutate $23 = JSX {read child$19} + [10] Call read y$3.push(read props$8.p4) + [11] Const mutate $23 = JSX {read child$19} Return read $23 ``` @@ -60,7 +59,7 @@ bb1: ```javascript function Component$0(props$8) { let x$9 = []; - let y$10 = undefined; + let y$3 = undefined; bb1: switch (props$8.p0) { case true: { x$9.push(props$8.p2); @@ -69,13 +68,13 @@ function Component$0(props$8) { } case false: { - y$15 = x$9; + y$3 = x$9; } } const child$19 = ; - y$20.push(props$8.p4); - return {child$19}; + y$3.push(props$8.p4); + return {child$19}; } ``` diff --git a/compiler/forget/src/__tests__/hir-test.ts b/compiler/forget/src/__tests__/hir-test.ts index 80b68a7c14..b9739c4572 100644 --- a/compiler/forget/src/__tests__/hir-test.ts +++ b/compiler/forget/src/__tests__/hir-test.ts @@ -22,6 +22,7 @@ import { HIRFunction } from "../HIR/HIR"; import { Environment } from "../HIR/HIRBuilder"; import { inferMutableRanges } from "../HIR/InferMutableLifetimes"; import inferReferenceEffects from "../HIR/InferReferenceEffects"; +import leaveSSA from "../HIR/LeaveSSA"; import printHIR from "../HIR/PrintHIR"; import generateTestsFromFixtures from "./test-utils/generateTestsFromFixtures"; @@ -68,6 +69,7 @@ describe("React Forget (HIR version)", () => { eliminateRedundantPhi(ir); inferReferenceEffects(ir); inferMutableRanges(ir); + leaveSSA(ir); // const lifetimeGraph = buildDefUseGraph(ir); const textHIR = printHIR(ir.body); // const textLifetimeGraph = printGraph(lifetimeGraph);