[ssa] Run SSA in RPO traversal

This prevents us from looking up state in blocks that have not been visited.
This commit is contained in:
Sathya Gunasekaran
2022-10-27 16:43:28 +01:00
parent 15104ab21b
commit fd6cb34843
9 changed files with 69 additions and 75 deletions
+6 -12
View File
@@ -165,11 +165,11 @@ class SSABuilder {
export default function buildSSA(func: HIRFunction, env: Environment) {
const builder = new SSABuilder(env);
function visit(blockId: BlockId) {
const block = func.body.blocks.get(blockId)!;
if (builder.visitedBlocks.has(block)) {
return;
}
for (const [blockId, block] of func.body.blocks) {
invariant(
!builder.visitedBlocks.has(block),
`found a cycle! visiting bb${block.id} again`
);
builder.visitedBlocks.add(block);
builder.startBlock(block);
@@ -208,13 +208,7 @@ export default function buildSSA(func: HIRFunction, env: Environment) {
builder.fixIncompletePhis(output);
}
}
for (const output of outputs) {
visit(output);
}
}
visit(func.body.entry);
}
function rewriteUsesAndCollectOutputs(
@@ -245,7 +239,7 @@ function rewriteUsesAndCollectOutputs(
case "switch": {
const { cases } = terminal;
terminal.test = builder.getPlace(terminal.test);
for (const case_ of [...cases].reverse()) {
for (const case_ of [...cases]) {
if (case_.test) {
case_.test = builder.getPlace(case_.test);
}
@@ -28,23 +28,23 @@ bb0:
If (read $10) then:bb2 else:bb1
bb2:
predecessor blocks: bb0
Reassign mutate x$18 = 3
Reassign mutate x$11 = 3
Goto bb1
bb1:
predecessor blocks: bb0 bb2
y$12: phi(bb0: y$8, bb2: y$8)
x$17: phi(bb0: x$7, bb2: x$18)
Const mutate $11 = 3
Const mutate $13 = Binary read y$12 === read $11
If (read $13) then:bb4 else:bb3
y$13: phi(bb0: y$8, bb2: y$8)
x$17: phi(bb0: x$7, bb2: x$11)
Const mutate $12 = 3
Const mutate $14 = Binary read y$13 === read $12
If (read $14) then:bb4 else:bb3
bb4:
predecessor blocks: bb1
Reassign mutate x$16 = 5
Reassign mutate x$15 = 5
Goto bb3
bb3:
predecessor blocks: bb1 bb4
x$14: phi(bb1: x$17, bb4: x$16)
Reassign mutate y$15 = read x$14
x$16: phi(bb1: x$17, bb4: x$15)
Reassign mutate y$18 = read x$16
Return
```
@@ -55,16 +55,16 @@ function foo$0() {
let x$7 = 1;
let y$8 = 2;
if (y$8 === 2) {
x$18 = 3;
x$11 = 3;
("<<TODO: handle complex control flow in codegen>>");
}
if (y$12 === 3) {
x$16 = 5;
if (y$13 === 3) {
x$15 = 5;
("<<TODO: handle complex control flow in codegen>>");
}
y$15 = x$14;
y$18 = x$16;
return;
}
@@ -25,12 +25,12 @@ bb0:
If (read $8) then:bb2 else:bb1
bb2:
predecessor blocks: bb0
Reassign mutate x$11 = 3
Reassign mutate x$9 = 3
Goto bb1
bb1:
predecessor blocks: bb0 bb2
x$9: phi(bb0: x$5, bb2: x$11)
Reassign mutate y$10 = read x$9
x$10: phi(bb0: x$5, bb2: x$9)
Reassign mutate y$11 = read x$10
Return
```
@@ -41,11 +41,11 @@ function foo$0() {
let x$5 = 1;
let y$6 = 2;
if (y$6 === 2) {
x$11 = 3;
x$9 = 3;
("<<TODO: handle complex control flow in codegen>>");
}
y$10 = x$9;
y$11 = x$10;
return;
}
@@ -24,11 +24,11 @@ bb0:
If (read y$6) then:bb2 else:bb3
bb2:
predecessor blocks: bb0
Let mutate z$8 = Binary read x$5 + read y$6
Let mutate z$7 = Binary read x$5 + read y$6
Goto bb1
bb3:
predecessor blocks: bb0
Let mutate z$7 = read x$5
Let mutate z$8 = read x$5
Goto bb1
bb1:
predecessor blocks: bb3 bb2
@@ -42,10 +42,10 @@ function foo$0() {
let x$5 = 1;
let y$6 = 2;
if (y$6) {
let z$8 = x$5 + y$6;
let z$7 = x$5 + y$6;
("<<TODO: handle complex control flow in codegen>>");
} else {
let z$7 = x$5;
let z$8 = x$5;
("<<TODO: handle complex control flow in codegen>>");
}
@@ -29,18 +29,18 @@ bb0:
If (read $9) then:bb2 else:bb3
bb2:
predecessor blocks: bb0
Reassign mutate x$14 = 2
Reassign mutate x$10 = 2
Goto bb1
bb3:
predecessor blocks: bb0
Reassign mutate y$10 = 3
Reassign mutate y$11 = 3
Goto bb1
bb1:
predecessor blocks: bb3 bb2
x$11: phi(bb3: x$6, bb2: x$14)
y$12: phi(bb3: y$10, bb2: y$7)
Let mutate t$13 = Object { x: read x$11, y: read y$12 }
Return freeze t$13
x$12: phi(bb3: x$6, bb2: x$10)
y$13: phi(bb3: y$11, bb2: y$7)
Let mutate t$14 = Object { x: read x$12, y: read y$13 }
Return freeze t$14
```
## Code
@@ -50,18 +50,18 @@ function foo$0() {
let x$6 = 1;
let y$7 = 2;
if (x$6 > 1) {
x$14 = 2;
x$10 = 2;
("<<TODO: handle complex control flow in codegen>>");
} else {
y$10 = 3;
y$11 = 3;
("<<TODO: handle complex control flow in codegen>>");
}
let t$13 = {
x: x$11,
y: y$12,
let t$14 = {
x: x$12,
y: y$13,
};
return t$13;
return t$14;
}
```
@@ -23,12 +23,12 @@ bb0:
If (read $6) then:bb2 else:bb1
bb2:
predecessor blocks: bb0
Reassign mutate x$8 = 2
Reassign mutate x$7 = 2
Goto bb1
bb1:
predecessor blocks: bb0 bb2
x$7: phi(bb0: x$4, bb2: x$8)
Return read x$7
x$8: phi(bb0: x$4, bb2: x$7)
Return read x$8
```
## Code
@@ -37,11 +37,11 @@ bb1:
function foo$0() {
let x$4 = 1;
if (x$4 === 1) {
x$8 = 2;
x$7 = 2;
("<<TODO: handle complex control flow in codegen>>");
}
return x$7;
return x$8;
}
```
@@ -26,16 +26,16 @@ bb0:
If (read $7) then:bb2 else:bb3
bb2:
predecessor blocks: bb0
Reassign mutate y$11 = 1
Reassign mutate y$8 = 1
Goto bb1
bb3:
predecessor blocks: bb0
Reassign mutate y$8 = 2
Reassign mutate y$9 = 2
Goto bb1
bb1:
predecessor blocks: bb3 bb2
y$9: phi(bb3: y$8, bb2: y$11)
Let mutate x$10 = read y$9
y$10: phi(bb3: y$9, bb2: y$8)
Let mutate x$11 = read y$10
Return
```
@@ -45,14 +45,14 @@ bb1:
function foo$0() {
let y$5 = 2;
if (y$5 > 1) {
y$11 = 1;
y$8 = 1;
("<<TODO: handle complex control flow in codegen>>");
} else {
y$8 = 2;
y$9 = 2;
("<<TODO: handle complex control flow in codegen>>");
}
let x$10 = y$9;
let x$11 = y$10;
return;
}
@@ -39,23 +39,23 @@ bb0:
Default: bb2
bb5:
predecessor blocks: bb0
Const mutate $21 = 1
Reassign mutate x$22 = Binary read x$10 + read $21
Const mutate $15 = 1
Reassign mutate x$16 = Binary read x$10 + read $15
Goto bb1
bb3:
predecessor blocks: bb0
Const mutate $19 = 2
Reassign mutate x$20 = Binary read x$10 + read $19
Const mutate $17 = 2
Reassign mutate x$18 = Binary read x$10 + read $17
Goto bb1
bb2:
predecessor blocks: bb0
Const mutate $15 = 3
Reassign mutate x$16 = Binary read x$10 + read $15
Const mutate $19 = 3
Reassign mutate x$20 = Binary read x$10 + read $19
Goto bb1
bb1:
predecessor blocks: bb5 bb3 bb2
x$17: phi(bb5: x$22, bb3: x$20, bb2: x$16)
Let mutate y$18 = read x$17
x$21: phi(bb5: x$16, bb3: x$18, bb2: x$20)
Let mutate y$22 = read x$21
Return
```
@@ -66,22 +66,22 @@ function foo$0() {
let x$10 = 1;
switch (x$10) {
case x$10 === 1: {
x$22 = x$10 + 1;
x$16 = x$10 + 1;
("<<TODO: handle complex control flow in codegen>>");
}
case x$10 === 2: {
x$20 = x$10 + 2;
x$18 = x$10 + 2;
("<<TODO: handle complex control flow in codegen>>");
}
default: {
x$16 = x$10 + 3;
x$20 = x$10 + 3;
("<<TODO: handle complex control flow in codegen>>");
}
}
let y$18 = x$17;
let y$22 = x$21;
return;
}
@@ -22,12 +22,12 @@ bb0:
If (read $6) then:bb2 else:bb1
bb2:
predecessor blocks: bb0
Reassign mutate x$8 = 2
Reassign mutate x$7 = 2
Goto bb1
bb1:
predecessor blocks: bb0 bb2
x$7: phi(bb0: x$4, bb2: x$8)
Throw read x$7
x$8: phi(bb0: x$4, bb2: x$7)
Throw read x$8
```
## Code
@@ -36,11 +36,11 @@ bb1:
function foo$0() {
let x$4 = 1;
if (x$4 === 1) {
x$8 = 2;
x$7 = 2;
("<<TODO: handle complex control flow in codegen>>");
}
throw x$7;
throw x$8;
}
```