From 74e6ffc4a2e0a99bd6e2cdbc9a05c4d481c58dd0 Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Wed, 9 Nov 2022 15:12:04 -0500 Subject: [PATCH] Leave SSA form Alternative approach to #750. We now store the original identifier on the Phi node, then rewrite every BasicBlock's identifiers to reference the original id instead of the SSA'd id. This solves the shadowing problem and also lets us omit adding copies of instructions. --- compiler/forget/src/HIR/EnterSSA.ts | 1 + compiler/forget/src/HIR/HIR.ts | 1 + compiler/forget/src/HIR/LeaveSSA.ts | 50 +++++++++++++ .../fixtures/hir/component.expect.md | 7 +- ...reeze-possibly-mutable-arguments.expect.md | 25 +++---- .../fixtures/hir/logical-expression.expect.md | 27 +++---- .../hir/mutable-lifetime-loops.expect.md | 48 +++++------- .../hir/reassignment-conditional.expect.md | 25 +++---- .../fixtures/hir/reverse-postorder.expect.md | 25 +++---- .../hir/ssa-complex-multiple-if.expect.md | 18 ++--- .../hir/ssa-complex-single-if.expect.md | 13 ++-- .../__tests__/fixtures/hir/ssa-for.expect.md | 11 ++- .../hir/ssa-objectexpression-phi.expect.md | 28 ++++--- .../fixtures/hir/ssa-return.expect.md | 17 ++--- .../fixtures/hir/ssa-shadowing.expect.md | 73 +++++++++++++++++++ .../__tests__/fixtures/hir/ssa-shadowing.js | 12 +++ .../fixtures/hir/ssa-simple-phi.expect.md | 13 ++-- .../fixtures/hir/ssa-switch.expect.md | 17 ++--- .../fixtures/hir/ssa-throw.expect.md | 17 ++--- .../fixtures/hir/ssa-while.expect.md | 11 ++- .../hir/switch-non-final-default.expect.md | 21 +++--- .../__tests__/fixtures/hir/switch.expect.md | 17 ++--- compiler/forget/src/__tests__/hir-test.ts | 2 + 23 files changed, 295 insertions(+), 184 deletions(-) create mode 100644 compiler/forget/src/HIR/LeaveSSA.ts create mode 100644 compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.js 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);