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.
This commit is contained in:
Lauren Tan
2022-11-09 15:12:04 -05:00
parent ea1a18ec16
commit 74e6ffc4a2
23 changed files with 295 additions and 184 deletions
+1
View File
@@ -121,6 +121,7 @@ class SSABuilder {
const phi: Phi = {
kind: "Phi",
id: newId,
oldId,
operands: predDefs,
};
+1
View File
@@ -193,6 +193,7 @@ export type InstructionValue =
export type Phi = {
kind: "Phi";
id: Identifier;
oldId: Identifier;
operands: Map<BasicBlock, Identifier>;
};
+50
View File
@@ -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);
}
}
}
@@ -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)
@@ -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;
}
```
@@ -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();
}
```
@@ -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 = {};
}
```
@@ -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 <read Component$0 x={freeze x$11} ></read Component$0>
[5] Let mutate _$12 = JSX <read Component$0 x={freeze x$2} ></read Component$0>
[6] Call read y$8.push(read props$6.p2)
[7] Const mutate $15 = JSX <read Component$0 x={read x$11} y={read y$8} ></read Component$0>
[7] Const mutate $15 = JSX <read Component$0 x={read x$2} y={read y$8} ></read Component$0>
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 = <Component$0 x={x$11}></Component$0>;
let _$12 = <Component$0 x={x$2}></Component$0>;
y$8.push(props$6.p2);
return <Component$0 x={x$11} y={y$8}></Component$0>;
return <Component$0 x={x$2} y={y$8}></Component$0>;
}
```
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
```
@@ -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;
}
@@ -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;
}
```
@@ -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;
}
```
@@ -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);
}
@@ -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;
}
@@ -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;
}
@@ -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;
}
```
@@ -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;
}
```
@@ -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 <read Component$0 data={freeze x$10} ></read Component$0>
[10] Call read y$20.push(read props$9.p4)
[11] Const mutate $22 = JSX <read Component$0 data={freeze y$20} >{read child$19}</read Component$0>
[10] Call read y$3.push(read props$9.p4)
[11] Const mutate $22 = JSX <read Component$0 data={freeze y$3} >{read child$19}</read Component$0>
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 = <Component$0 data={x$10}></Component$0>;
y$20.push(props$9.p4);
return <Component$0 data={y$20}>{child$19}</Component$0>;
y$3.push(props$9.p4);
return <Component$0 data={y$3}>{child$19}</Component$0>;
}
```
@@ -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 <read Component$0 data={freeze x$9} ></read Component$0>
[10] Call read y$20.push(read props$8.p4)
[11] Const mutate $23 = JSX <read Component$0 data={read y$20} >{read child$19}</read Component$0>
[10] Call read y$3.push(read props$8.p4)
[11] Const mutate $23 = JSX <read Component$0 data={read y$3} >{read child$19}</read Component$0>
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 = <Component$0 data={x$9}></Component$0>;
y$20.push(props$8.p4);
return <Component$0 data={y$20}>{child$19}</Component$0>;
y$3.push(props$8.p4);
return <Component$0 data={y$3}>{child$19}</Component$0>;
}
```
@@ -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);