From 584eff2d38670dcfb98d947b3db39dfb06f6cabb Mon Sep 17 00:00:00 2001 From: Sathya Gunasekaran Date: Mon, 21 Nov 2022 18:35:14 +0000 Subject: [PATCH] [hir] Handle simple aliases when inferring mutable lifetimes (#794) --- .../forget/src/HIR/InferMutableLifetimes.ts | 60 ++++++- .../fixtures/hir/alias-while.expect.md | 148 ++++++++++++++++++ .../src/__tests__/fixtures/hir/alias-while.js | 18 +++ .../hir/mutable-lifetime-loops.expect.md | 40 ++--- .../hir/reassignment-conditional.expect.md | 20 +-- .../fixtures/hir/reassignment.expect.md | 28 ++-- .../fixtures/hir/simple-alias.expect.md | 98 ++++++++++++ .../__tests__/fixtures/hir/simple-alias.js | 11 ++ .../hir/ssa-complex-multiple-if.expect.md | 16 +- .../hir/ssa-complex-single-if.expect.md | 12 +- .../fixtures/hir/ssa-simple-phi.expect.md | 12 +- .../fixtures/hir/ssa-switch.expect.md | 16 +- .../hir/switch-non-final-default.expect.md | 56 +++---- .../__tests__/fixtures/hir/switch.expect.md | 48 +++--- 14 files changed, 458 insertions(+), 125 deletions(-) create mode 100644 compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/hir/alias-while.js create mode 100644 compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md create mode 100644 compiler/forget/src/__tests__/fixtures/hir/simple-alias.js diff --git a/compiler/forget/src/HIR/InferMutableLifetimes.ts b/compiler/forget/src/HIR/InferMutableLifetimes.ts index 9a188b0bb8..d2c08f0e78 100644 --- a/compiler/forget/src/HIR/InferMutableLifetimes.ts +++ b/compiler/forget/src/HIR/InferMutableLifetimes.ts @@ -7,7 +7,8 @@ import invariant from "invariant"; import { assertExhaustive } from "../Common/utils"; -import { Effect, HIRFunction, Instruction, Place } from "./HIR"; +import DisjointSet from "./DisjointSet"; +import { Effect, HIRFunction, Identifier, Instruction, Place } from "./HIR"; import { printInstruction, printPlace } from "./PrintHIR"; import { eachInstructionOperand } from "./visitors"; @@ -76,6 +77,8 @@ function inferPlace(place: Place, instr: Instruction) { } export function inferMutableRanges(func: HIRFunction) { + const aliases = new DisjointSet(); + for (const [_, block] of func.body.blocks) { for (const phi of block.phis) { let start = Number.MAX_SAFE_INTEGER; @@ -100,6 +103,20 @@ export function inferMutableRanges(func: HIRFunction) { } if (instr.lvalue !== null) { + if (instr.value.kind === "Identifier") { + // TODO(gsn): Handle complex aliasing. + if ( + instr.value.memberPath === null && + instr.lvalue.place.memberPath === null + ) { + // direct aliasing: `a = b`; + aliases.union([ + instr.lvalue.place.identifier, + instr.value.identifier, + ]); + } + } + if (instr.lvalue.place.memberPath === null) { const lvalueId = instr.lvalue.place.identifier; @@ -116,4 +133,45 @@ export function inferMutableRanges(func: HIRFunction) { } } } + + const aliasIds: Map = new Map(); + // Store the mutable range and set of identifiers for each scope + const aliasIndentifiers: Map< + number, + { end: number; identifiers: Set } + > = new Map(); + + aliases.forEach((identifier, groupIdentifier) => { + let aliasId = aliasIds.get(groupIdentifier); + if (aliasId == null) { + aliasId = aliasIds.size; + aliasIds.set(groupIdentifier, aliasId); + } + + let alias = aliasIndentifiers.get(aliasId); + if (alias === undefined) { + alias = { + end: identifier.mutableRange.end, + identifiers: new Set(), + }; + aliasIndentifiers.set(aliasId, alias); + } else { + alias.end = Math.max(alias.end, identifier.mutableRange.end); + } + alias.identifiers.add(identifier); + }); + + for (const [_, alias] of aliasIndentifiers) { + // Update mutableRange.end only if the identifiers have actually been + // mutated. + const haveIdentifiersBeenMutated = [...alias.identifiers].some( + (id) => id.mutableRange.end > id.mutableRange.start + ); + + if (haveIdentifiersBeenMutated) { + for (const identifier of alias.identifiers) { + identifier.mutableRange.end = alias.end; + } + } + } } diff --git a/compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md b/compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md new file mode 100644 index 0000000000..6afc2a3c6c --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/alias-while.expect.md @@ -0,0 +1,148 @@ + +## Input + +```javascript +function foo(cond) { + let a = {}; + let b = {}; + let c = {}; + while (cond) { + let z = a; + a = b; + b = c; + c = z; + mutate(a, b); + } + a; + b; + c; + return a; +} + +function mutate(x, y) {} + +``` + +## HIR + +``` +bb0: + [1] Let mutate a$2_@0[0:8] = Object { } + [2] Let mutate b$3_@0[0:8] = Object { } + [3] Let mutate c$4_@0[0:8] = Object { } + While test=bb1 loop=bb3 fallthrough=bb2 +bb1: + predecessor blocks: bb0 bb3 + If (read cond$1) then:bb3 else:bb2 +bb3: + predecessor blocks: bb1 + [4] Let mutate z$5_@0[0:8] = read a$2_@0 + [5] Reassign mutate a$2_@0[0:8] = read b$3_@0 + [6] Reassign mutate b$3_@0[0:8] = read c$4_@0 + [7] Reassign mutate c$4_@0[0:8] = read z$5_@0 + [8] Call mutate mutate$6_@0(mutate a$2_@0, mutate b$3_@0) + Goto(Continue) bb1 +bb2: + predecessor blocks: bb1 + [9] read a$2_@0 + [10] read b$3_@0 + [11] read c$4_@0 + Return freeze a$2_@0 +``` + +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate a$2_@0[0:8] = Object { } + [2] Let mutate b$3_@0[0:8] = Object { } + [3] Let mutate c$4_@0[0:8] = Object { } + "] + bb0_instrs --> bb0_terminal(["While"]) + end + subgraph bb1 + bb1_terminal(["If (read cond$1)"]) + end + subgraph bb3 + bb3_instrs[" + [4] Let mutate z$5_@0[0:8] = read a$2_@0 + [5] Reassign mutate a$2_@0[0:8] = read b$3_@0 + [6] Reassign mutate b$3_@0[0:8] = read c$4_@0 + [7] Reassign mutate c$4_@0[0:8] = read z$5_@0 + [8] Call mutate mutate$6_@0(mutate a$2_@0, mutate b$3_@0) + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + subgraph bb2 + bb2_instrs[" + [9] read a$2_@0 + [10] read b$3_@0 + [11] read c$4_@0 + "] + bb2_instrs --> bb2_terminal(["Return freeze a$2_@0"]) + end + + %% Jumps + bb0_terminal -- "test" --> bb1 + bb0_terminal -- "loop" --> bb3 + bb0_terminal -- "fallthrough" --> bb2 + bb1_terminal -- "then" --> bb3 + bb1_terminal -- "else" --> bb2 + bb3_terminal --> bb1 + +``` + +## Code + +```javascript +function foo$0(cond$1) { + let a$2 = {}; + let b$3 = {}; + let c$4 = {}; + bb2: while (cond$1) { + let z$5 = a$2; + a$2 = b$3; + b$3 = c$4; + c$4 = z$5; + mutate$6(a$2, b$3); + } + + a$2; + b$3; + c$4; + return a$2; +} + +``` +## HIR + +``` +bb0: + Return +``` + +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + %% Jumps + %% empty +``` + +## Code + +```javascript +function mutate$0(x$1, y$2) { + return; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/alias-while.js b/compiler/forget/src/__tests__/fixtures/hir/alias-while.js new file mode 100644 index 0000000000..34aa4c93aa --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/alias-while.js @@ -0,0 +1,18 @@ +function foo(cond) { + let a = {}; + let b = {}; + let c = {}; + while (cond) { + let z = a; + a = b; + b = c; + c = z; + mutate(a, b); + } + a; + b; + c; + return a; +} + +function mutate(x, y) {} 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 0906af08b6..5e113a89ce 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 @@ -101,20 +101,20 @@ function cond$0(x$1) { bb0: [1] Let mutate a$2_@0[0:14] = Object { } [2] Let mutate b$3_@0[0:14] = Object { } - [3] Let mutate c$4_@1[0:9] = Object { } + [3] Let mutate c$4_@0[0:14] = Object { } [4] Let mutate d$5_@0[0:14] = Object { } While test=bb1 loop=bb3 fallthrough=bb2 bb1: predecessor blocks: bb0 bb4 - [5] Const mutate $10_@2 = true - If (read $10_@2) then:bb3 else:bb2 + [5] Const mutate $10_@1 = true + If (read $10_@1) then:bb3 else:bb2 bb3: predecessor blocks: bb1 - [6] Let mutate z$6_@3 = read a$2_@0 + [6] Let mutate z$6_@0[0:14] = read a$2_@0 [7] Reassign mutate a$2_@0[0:14] = read b$3_@0 - [8] Reassign mutate b$3_@0[0:14] = read c$4_@1 - [9] Reassign mutate c$4_@1[0:9] = read d$5_@0 - [10] Reassign mutate d$5_@0[0:14] = read z$6_@3 + [8] Reassign mutate b$3_@0[0:14] = read c$4_@0 + [9] Reassign mutate c$4_@0[0:14] = read d$5_@0 + [10] Reassign mutate d$5_@0[0:14] = read z$6_@0 [11] Call mutate mutate$7_@0(mutate a$2_@0, mutate b$3_@0) [12] Const mutate $9_@0[0:14] = Call mutate cond$8_@0(mutate a$2_@0) If (read $9_@0) then:bb2 else:bb4 @@ -129,14 +129,14 @@ bb7: If (read b$3_@0) then:bb9 else:bb9 bb9: predecessor blocks: bb7 - If (read c$4_@1) then:bb11 else:bb11 + If (read c$4_@0) then:bb11 else:bb11 bb11: predecessor blocks: bb9 If (read d$5_@0) then:bb13 else:bb13 bb13: predecessor blocks: bb11 - [13] Const mutate $11_@4 = null - [14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@4) + [13] Const mutate $11_@2 = null + [14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@2) Return ``` @@ -149,24 +149,24 @@ flowchart TB bb0_instrs[" [1] Let mutate a$2_@0[0:14] = Object { } [2] Let mutate b$3_@0[0:14] = Object { } - [3] Let mutate c$4_@1[0:9] = Object { } + [3] Let mutate c$4_@0[0:14] = Object { } [4] Let mutate d$5_@0[0:14] = Object { } "] bb0_instrs --> bb0_terminal(["While"]) end subgraph bb1 bb1_instrs[" - [5] Const mutate $10_@2 = true + [5] Const mutate $10_@1 = true "] - bb1_instrs --> bb1_terminal(["If (read $10_@2)"]) + bb1_instrs --> bb1_terminal(["If (read $10_@1)"]) end subgraph bb3 bb3_instrs[" - [6] Let mutate z$6_@3 = read a$2_@0 + [6] Let mutate z$6_@0[0:14] = read a$2_@0 [7] Reassign mutate a$2_@0[0:14] = read b$3_@0 - [8] Reassign mutate b$3_@0[0:14] = read c$4_@1 - [9] Reassign mutate c$4_@1[0:9] = read d$5_@0 - [10] Reassign mutate d$5_@0[0:14] = read z$6_@3 + [8] Reassign mutate b$3_@0[0:14] = read c$4_@0 + [9] Reassign mutate c$4_@0[0:14] = read d$5_@0 + [10] Reassign mutate d$5_@0[0:14] = read z$6_@0 [11] Call mutate mutate$7_@0(mutate a$2_@0, mutate b$3_@0) [12] Const mutate $9_@0[0:14] = Call mutate cond$8_@0(mutate a$2_@0) "] @@ -182,15 +182,15 @@ flowchart TB bb7_terminal(["If (read b$3_@0)"]) end subgraph bb9 - bb9_terminal(["If (read c$4_@1)"]) + bb9_terminal(["If (read c$4_@0)"]) end subgraph bb11 bb11_terminal(["If (read d$5_@0)"]) end subgraph bb13 bb13_instrs[" - [13] Const mutate $11_@4 = null - [14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@4) + [13] Const mutate $11_@2 = null + [14] Call mutate mutate$7_@0(mutate d$5_@0, read $11_@2) "] bb13_instrs --> bb13_terminal(["Return"]) end 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 870d6299c2..7d96a850c1 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md @@ -25,7 +25,7 @@ function Component(props) { bb0: [1] Let mutate x$2_@0[1:4] = Array [] [2] Call mutate x$2_@0.push(read props$1.p0) - [3] Let mutate y$3_@1 = read x$2_@0 + [3] Let mutate y$3_@0[1:4] = read x$2_@0 If (read props$1.p1) then:bb2 else:bb1 bb2: predecessor blocks: bb0 @@ -33,10 +33,10 @@ bb2: Goto bb1 bb1: predecessor blocks: bb2 bb0 - [5] Let mutate _$4_@2 = JSX - [6] Call read y$3_@1.push(read props$1.p2) - [7] Const mutate $5_@3 = JSX - Return read $5_@3 + [5] Let mutate _$4_@1 = JSX + [6] Call read y$3_@0.push(read props$1.p2) + [7] Const mutate $5_@2 = JSX + Return read $5_@2 ``` ### CFG @@ -48,7 +48,7 @@ flowchart TB bb0_instrs[" [1] Let mutate x$2_@0[1:4] = Array [] [2] Call mutate x$2_@0.push(read props$1.p0) - [3] Let mutate y$3_@1 = read x$2_@0 + [3] Let mutate y$3_@0[1:4] = read x$2_@0 "] bb0_instrs --> bb0_terminal(["If (read props$1.p1)"]) end @@ -60,11 +60,11 @@ flowchart TB end subgraph bb1 bb1_instrs[" - [5] Let mutate _$4_@2 = JSX - [6] Call read y$3_@1.push(read props$1.p2) - [7] Const mutate $5_@3 = JSX + [5] Let mutate _$4_@1 = JSX + [6] Call read y$3_@0.push(read props$1.p2) + [7] Const mutate $5_@2 = JSX "] - bb1_instrs --> bb1_terminal(["Return read $5_@3"]) + bb1_instrs --> bb1_terminal(["Return read $5_@2"]) end %% Jumps diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md index abcea79bc7..b79ce4f74b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md @@ -21,14 +21,14 @@ function Component(props) { ``` bb0: - [1] Let mutate x$2_@0[1:2] = Array [] + [1] Let mutate x$2_@0[1:6] = Array [] [2] Call mutate x$2_@0.push(read props$1.p0) - [3] Let mutate y$3_@1[3:6] = read x$2_@0 - [4] Reassign mutate x$2_@2 = Array [] - [5] Let mutate _$4_@3 = JSX - [6] Call mutate y$3_@1.push(read props$1.p1) - [7] Const mutate $5_@4 = JSX - Return read $5_@4 + [3] Let mutate y$3_@0[1:6] = read x$2_@0 + [4] Reassign mutate x$2_@1 = Array [] + [5] Let mutate _$4_@2 = JSX + [6] Call mutate y$3_@0.push(read props$1.p1) + [7] Const mutate $5_@3 = JSX + Return read $5_@3 ``` ### CFG @@ -38,15 +38,15 @@ flowchart TB %% Basic Blocks subgraph bb0 bb0_instrs[" - [1] Let mutate x$2_@0[1:2] = Array [] + [1] Let mutate x$2_@0[1:6] = Array [] [2] Call mutate x$2_@0.push(read props$1.p0) - [3] Let mutate y$3_@1[3:6] = read x$2_@0 - [4] Reassign mutate x$2_@2 = Array [] - [5] Let mutate _$4_@3 = JSX - [6] Call mutate y$3_@1.push(read props$1.p1) - [7] Const mutate $5_@4 = JSX + [3] Let mutate y$3_@0[1:6] = read x$2_@0 + [4] Reassign mutate x$2_@1 = Array [] + [5] Let mutate _$4_@2 = JSX + [6] Call mutate y$3_@0.push(read props$1.p1) + [7] Const mutate $5_@3 = JSX "] - bb0_instrs --> bb0_terminal(["Return read $5_@4"]) + bb0_instrs --> bb0_terminal(["Return read $5_@3"]) end %% Jumps diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md new file mode 100644 index 0000000000..e937473a7b --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/simple-alias.expect.md @@ -0,0 +1,98 @@ + +## Input + +```javascript +function mutate() {} +function foo() { + let a = {}; + let b = {}; + let c = {}; + a = b; + b = c; + c = a; + mutate(a, b); + return c; +} + +``` + +## HIR + +``` +bb0: + Return +``` + +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + %% Jumps + %% empty +``` + +## Code + +```javascript +function mutate$0() { + return; +} + +``` +## HIR + +``` +bb0: + [1] Let mutate a$1_@0 = Object { } + [2] Let mutate b$2_@1[0:7] = Object { } + [3] Let mutate c$3_@1[0:7] = Object { } + [4] Reassign mutate a$1_@1[0:7] = read b$2_@1 + [5] Reassign mutate b$2_@1[0:7] = read c$3_@1 + [6] Reassign mutate c$3_@1[0:7] = read a$1_@1 + [7] Call mutate mutate$4_@1(mutate a$1_@1, mutate b$2_@1) + Return freeze c$3_@1 +``` + +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate a$1_@0 = Object { } + [2] Let mutate b$2_@1[0:7] = Object { } + [3] Let mutate c$3_@1[0:7] = Object { } + [4] Reassign mutate a$1_@1[0:7] = read b$2_@1 + [5] Reassign mutate b$2_@1[0:7] = read c$3_@1 + [6] Reassign mutate c$3_@1[0:7] = read a$1_@1 + [7] Call mutate mutate$4_@1(mutate a$1_@1, mutate b$2_@1) + "] + bb0_instrs --> bb0_terminal(["Return freeze c$3_@1"]) + end + + %% Jumps + %% empty +``` + +## Code + +```javascript +function foo$0() { + let a$1 = {}; + let b$2 = {}; + let c$3 = {}; + a$1 = b$2; + b$2 = c$3; + c$3 = a$1; + mutate$4(a$1, b$2); + return c$3; +} + +``` + \ No newline at end of file diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple-alias.js b/compiler/forget/src/__tests__/fixtures/hir/simple-alias.js new file mode 100644 index 0000000000..f57584af69 --- /dev/null +++ b/compiler/forget/src/__tests__/fixtures/hir/simple-alias.js @@ -0,0 +1,11 @@ +function mutate() {} +function foo() { + let a = {}; + let b = {}; + let c = {}; + a = b; + b = c; + c = a; + mutate(a, b); + return c; +} 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 d8a758a76a..7ad778d40d 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,14 +21,14 @@ function foo() { ``` bb0: - [1] Let mutate x$1_@0[1:8] = 1 + [1] Let mutate x$1_@0[1:9] = 1 [2] Let mutate y$2_@1 = 2 [3] Const mutate $3_@2 = 2 [4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2 If (read $4_@3) then:bb2 else:bb1 bb2: predecessor blocks: bb0 - [5] Reassign mutate x$1_@0[1:8] = 3 + [5] Reassign mutate x$1_@0[1:9] = 3 Goto bb1 bb1: predecessor blocks: bb2 bb0 @@ -37,11 +37,11 @@ bb1: If (read $6_@5) then:bb4 else:bb3 bb4: predecessor blocks: bb1 - [8] Reassign mutate x$1_@0[1:8] = 5 + [8] Reassign mutate x$1_@0[1:9] = 5 Goto bb3 bb3: predecessor blocks: bb4 bb1 - [9] Reassign mutate y$2_@6 = read x$1_@0 + [9] Reassign mutate y$2_@0[1:9] = read x$1_@0 Return ``` @@ -52,7 +52,7 @@ flowchart TB %% Basic Blocks subgraph bb0 bb0_instrs[" - [1] Let mutate x$1_@0[1:8] = 1 + [1] Let mutate x$1_@0[1:9] = 1 [2] Let mutate y$2_@1 = 2 [3] Const mutate $3_@2 = 2 [4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2 @@ -61,7 +61,7 @@ flowchart TB end subgraph bb2 bb2_instrs[" - [5] Reassign mutate x$1_@0[1:8] = 3 + [5] Reassign mutate x$1_@0[1:9] = 3 "] bb2_instrs --> bb2_terminal(["Goto"]) end @@ -74,13 +74,13 @@ flowchart TB end subgraph bb4 bb4_instrs[" - [8] Reassign mutate x$1_@0[1:8] = 5 + [8] Reassign mutate x$1_@0[1:9] = 5 "] bb4_instrs --> bb4_terminal(["Goto"]) end subgraph bb3 bb3_instrs[" - [9] Reassign mutate y$2_@6 = read x$1_@0 + [9] Reassign mutate y$2_@0[1:9] = read x$1_@0 "] bb3_instrs --> bb3_terminal(["Return"]) end 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 9217f2f6b7..7204e90191 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,18 +18,18 @@ function foo() { ``` bb0: - [1] Let mutate x$1_@0[1:5] = 1 + [1] Let mutate x$1_@0[1:6] = 1 [2] Let mutate y$2_@1 = 2 [3] Const mutate $3_@2 = 2 [4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2 If (read $4_@3) then:bb2 else:bb1 bb2: predecessor blocks: bb0 - [5] Reassign mutate x$1_@0[1:5] = 3 + [5] Reassign mutate x$1_@0[1:6] = 3 Goto bb1 bb1: predecessor blocks: bb2 bb0 - [6] Reassign mutate y$2_@4 = read x$1_@0 + [6] Reassign mutate y$2_@0[1:6] = read x$1_@0 Return ``` @@ -40,7 +40,7 @@ flowchart TB %% Basic Blocks subgraph bb0 bb0_instrs[" - [1] Let mutate x$1_@0[1:5] = 1 + [1] Let mutate x$1_@0[1:6] = 1 [2] Let mutate y$2_@1 = 2 [3] Const mutate $3_@2 = 2 [4] Const mutate $4_@3 = Binary read y$2_@1 === read $3_@2 @@ -49,13 +49,13 @@ flowchart TB end subgraph bb2 bb2_instrs[" - [5] Reassign mutate x$1_@0[1:5] = 3 + [5] Reassign mutate x$1_@0[1:6] = 3 "] bb2_instrs --> bb2_terminal(["Goto"]) end subgraph bb1 bb1_instrs[" - [6] Reassign mutate y$2_@4 = read x$1_@0 + [6] Reassign mutate y$2_@0[1:6] = read x$1_@0 "] bb1_instrs --> bb1_terminal(["Return"]) end 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 c12b5146d5..8229101d05 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,15 +26,15 @@ bb0: If (read $3_@2) then:bb2 else:bb3 bb2: predecessor blocks: bb0 - [4] Reassign mutate y$1_@3[4:5] = 1 + [4] Reassign mutate y$1_@3[4:6] = 1 Goto bb1 bb3: predecessor blocks: bb0 - [5] Reassign mutate y$1_@3[4:5] = 2 + [5] Reassign mutate y$1_@3[4:6] = 2 Goto bb1 bb1: predecessor blocks: bb2 bb3 - [6] Let mutate x$4_@4 = read y$1_@3 + [6] Let mutate x$4_@3[4:6] = read y$1_@3 Return ``` @@ -53,19 +53,19 @@ flowchart TB end subgraph bb2 bb2_instrs[" - [4] Reassign mutate y$1_@3[4:5] = 1 + [4] Reassign mutate y$1_@3[4:6] = 1 "] bb2_instrs --> bb2_terminal(["Goto"]) end subgraph bb3 bb3_instrs[" - [5] Reassign mutate y$1_@3[4:5] = 2 + [5] Reassign mutate y$1_@3[4:6] = 2 "] bb3_instrs --> bb3_terminal(["Goto"]) end subgraph bb1 bb1_instrs[" - [6] Let mutate x$4_@4 = read y$1_@3 + [6] Let mutate x$4_@3[4:6] = read y$1_@3 "] bb1_instrs --> bb1_terminal(["Return"]) end 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 b76bd23106..97d2ebe4e4 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md @@ -40,21 +40,21 @@ bb0: bb5: predecessor blocks: bb0 [6] Const mutate $6_@5 = 1 - [7] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $6_@5 + [7] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $6_@5 Goto bb1 bb3: predecessor blocks: bb0 [8] Const mutate $3_@7 = 2 - [9] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $3_@7 + [9] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $3_@7 Goto bb1 bb2: predecessor blocks: bb0 [10] Const mutate $2_@8 = 3 - [11] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $2_@8 + [11] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $2_@8 Goto bb1 bb1: predecessor blocks: bb5 bb3 bb2 - [12] Let mutate y$9_@9 = read x$1_@6 + [12] Let mutate y$9_@6[7:12] = read x$1_@6 Return ``` @@ -76,27 +76,27 @@ flowchart TB subgraph bb5 bb5_instrs[" [6] Const mutate $6_@5 = 1 - [7] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $6_@5 + [7] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $6_@5 "] bb5_instrs --> bb5_terminal(["Goto"]) end subgraph bb3 bb3_instrs[" [8] Const mutate $3_@7 = 2 - [9] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $3_@7 + [9] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $3_@7 "] bb3_instrs --> bb3_terminal(["Goto"]) end subgraph bb2 bb2_instrs[" [10] Const mutate $2_@8 = 3 - [11] Reassign mutate x$1_@6[7:11] = Binary read x$1_@0 + read $2_@8 + [11] Reassign mutate x$1_@6[7:12] = Binary read x$1_@0 + read $2_@8 "] bb2_instrs --> bb2_terminal(["Goto"]) end subgraph bb1 bb1_instrs[" - [12] Let mutate y$9_@9 = read x$1_@6 + [12] Let mutate y$9_@6[7:12] = read x$1_@6 "] bb1_instrs --> bb1_terminal(["Return"]) end 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 0056448aa4..e4a9e413dc 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 @@ -32,31 +32,31 @@ function Component(props) { ``` bb0: - [1] Let mutate x$2_@0[1:6] = Array [] - [2] Let mutate y$3_@1[2:8] = undefined - [3] Const mutate $4_@2 = false - [4] Const mutate $5_@3 = true - [5] Const mutate $6_@4 = 1 + [1] Let mutate x$2_@0[1:8] = Array [] + [2] Let mutate y$3_@0[1:8] = undefined + [3] Const mutate $4_@1 = false + [4] Const mutate $5_@2 = true + [5] Const mutate $6_@3 = 1 Switch (read props$1.p0) - Case read $6_@4: bb1 - Case read $5_@3: bb6 + Case read $6_@3: bb1 + Case read $5_@2: bb6 Default: bb1 - Case read $4_@2: bb2 + Case read $4_@1: bb2 bb6: predecessor blocks: bb0 [6] Call mutate x$2_@0.push(read props$1.p2) - [7] Reassign mutate y$3_@1[2:8] = Array [] + [7] Reassign mutate y$3_@0[1:8] = Array [] Goto bb1 bb2: predecessor blocks: bb0 - [8] Reassign mutate y$3_@1[2:8] = read x$2_@0 + [8] Reassign mutate y$3_@0[1:8] = read x$2_@0 Goto bb1 bb1: predecessor blocks: bb0 bb6 bb2 - [9] Const mutate child$7_@5 = JSX - [10] Call read y$3_@1.push(read props$1.p4) - [11] Const mutate $8_@6 = JSX {read child$7_@5} - Return read $8_@6 + [9] Const mutate child$7_@4 = JSX + [10] Call read y$3_@0.push(read props$1.p4) + [11] Const mutate $8_@5 = JSX {read child$7_@4} + Return read $8_@5 ``` ### CFG @@ -66,41 +66,41 @@ flowchart TB %% Basic Blocks subgraph bb0 bb0_instrs[" - [1] Let mutate x$2_@0[1:6] = Array [] - [2] Let mutate y$3_@1[2:8] = undefined - [3] Const mutate $4_@2 = false - [4] Const mutate $5_@3 = true - [5] Const mutate $6_@4 = 1 + [1] Let mutate x$2_@0[1:8] = Array [] + [2] Let mutate y$3_@0[1:8] = undefined + [3] Const mutate $4_@1 = false + [4] Const mutate $5_@2 = true + [5] Const mutate $6_@3 = 1 "] bb0_instrs --> bb0_terminal(["Switch (read props$1.p0)"]) end subgraph bb6 bb6_instrs[" [6] Call mutate x$2_@0.push(read props$1.p2) - [7] Reassign mutate y$3_@1[2:8] = Array [] + [7] Reassign mutate y$3_@0[1:8] = Array [] "] bb6_instrs --> bb6_terminal(["Goto"]) end subgraph bb2 bb2_instrs[" - [8] Reassign mutate y$3_@1[2:8] = read x$2_@0 + [8] Reassign mutate y$3_@0[1:8] = read x$2_@0 "] bb2_instrs --> bb2_terminal(["Goto"]) end subgraph bb1 bb1_instrs[" - [9] Const mutate child$7_@5 = JSX - [10] Call read y$3_@1.push(read props$1.p4) - [11] Const mutate $8_@6 = JSX {read child$7_@5} + [9] Const mutate child$7_@4 = JSX + [10] Call read y$3_@0.push(read props$1.p4) + [11] Const mutate $8_@5 = JSX {read child$7_@4} "] - bb1_instrs --> bb1_terminal(["Return read $8_@6"]) + bb1_instrs --> bb1_terminal(["Return read $8_@5"]) end %% Jumps - bb0_terminal -- "read $6_@4" --> bb1 - bb0_terminal -- "read $5_@3" --> bb6 + bb0_terminal -- "read $6_@3" --> bb1 + bb0_terminal -- "read $5_@2" --> bb6 bb0_terminal -- "default" --> bb1 - bb0_terminal -- "read $4_@2" --> bb2 + bb0_terminal -- "read $4_@1" --> bb2 bb0_terminal -- "fallthrough" --> bb1 bb6_terminal --> bb1 bb2_terminal --> bb1 diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md index 3a7075357b..e45f168b89 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md @@ -28,30 +28,30 @@ function Component(props) { ``` bb0: - [1] Let mutate x$2_@0[1:6] = Array [] - [2] Let mutate y$3_@1[2:8] = undefined - [3] Const mutate $4_@2 = false - [4] Const mutate $5_@3 = true + [1] Let mutate x$2_@0[1:8] = Array [] + [2] Let mutate y$3_@0[1:8] = undefined + [3] Const mutate $4_@1 = false + [4] Const mutate $5_@2 = true Switch (read props$1.p0) - Case read $5_@3: bb4 - Case read $4_@2: bb2 + Case read $5_@2: bb4 + Case read $4_@1: bb2 Default: bb1 bb4: predecessor blocks: bb0 [5] Call mutate x$2_@0.push(read props$1.p2) [6] Call mutate x$2_@0.push(read props$1.p3) - [7] Reassign mutate y$3_@4 = Array [] + [7] Reassign mutate y$3_@3 = Array [] Goto bb2 bb2: predecessor blocks: bb4 bb0 - [8] Reassign mutate y$3_@1[2:8] = read x$2_@0 + [8] Reassign mutate y$3_@0[1:8] = read x$2_@0 Goto bb1 bb1: predecessor blocks: bb2 bb0 - [9] Const mutate child$6_@5 = JSX - [10] Call read y$3_@1.push(read props$1.p4) - [11] Const mutate $7_@6 = JSX {read child$6_@5} - Return read $7_@6 + [9] Const mutate child$6_@4 = JSX + [10] Call read y$3_@0.push(read props$1.p4) + [11] Const mutate $7_@5 = JSX {read child$6_@4} + Return read $7_@5 ``` ### CFG @@ -61,10 +61,10 @@ flowchart TB %% Basic Blocks subgraph bb0 bb0_instrs[" - [1] Let mutate x$2_@0[1:6] = Array [] - [2] Let mutate y$3_@1[2:8] = undefined - [3] Const mutate $4_@2 = false - [4] Const mutate $5_@3 = true + [1] Let mutate x$2_@0[1:8] = Array [] + [2] Let mutate y$3_@0[1:8] = undefined + [3] Const mutate $4_@1 = false + [4] Const mutate $5_@2 = true "] bb0_instrs --> bb0_terminal(["Switch (read props$1.p0)"]) end @@ -72,28 +72,28 @@ flowchart TB bb4_instrs[" [5] Call mutate x$2_@0.push(read props$1.p2) [6] Call mutate x$2_@0.push(read props$1.p3) - [7] Reassign mutate y$3_@4 = Array [] + [7] Reassign mutate y$3_@3 = Array [] "] bb4_instrs --> bb4_terminal(["Goto"]) end subgraph bb2 bb2_instrs[" - [8] Reassign mutate y$3_@1[2:8] = read x$2_@0 + [8] Reassign mutate y$3_@0[1:8] = read x$2_@0 "] bb2_instrs --> bb2_terminal(["Goto"]) end subgraph bb1 bb1_instrs[" - [9] Const mutate child$6_@5 = JSX - [10] Call read y$3_@1.push(read props$1.p4) - [11] Const mutate $7_@6 = JSX {read child$6_@5} + [9] Const mutate child$6_@4 = JSX + [10] Call read y$3_@0.push(read props$1.p4) + [11] Const mutate $7_@5 = JSX {read child$6_@4} "] - bb1_instrs --> bb1_terminal(["Return read $7_@6"]) + bb1_instrs --> bb1_terminal(["Return read $7_@5"]) end %% Jumps - bb0_terminal -- "read $5_@3" --> bb4 - bb0_terminal -- "read $4_@2" --> bb2 + bb0_terminal -- "read $5_@2" --> bb4 + bb0_terminal -- "read $4_@1" --> bb2 bb0_terminal -- "default" --> bb1 bb0_terminal -- "fallthrough" --> bb1 bb4_terminal --> bb2