Add and use eachTerminalSuccessor()

This commit is contained in:
Joe Savona
2022-11-08 14:45:56 -08:00
parent e665f6b877
commit 2a049044bb
25 changed files with 101 additions and 109 deletions
+7 -17
View File
@@ -2,7 +2,6 @@ import { assertExhaustive } from "../Common/utils";
import { invariant } from "../CompilerError";
import {
BasicBlock,
BlockId,
HIRFunction,
Identifier,
Instruction,
@@ -11,6 +10,7 @@ import {
} from "./HIR";
import { Environment } from "./HIRBuilder";
import { printIdentifier } from "./PrintHIR";
import { eachTerminalSuccessor } from "./visitors";
type IncompletePhi = {
oldId: Identifier;
@@ -186,7 +186,7 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
}
for (const instr of block.instructions) {
rewriteUses(instr, builder);
rewriteInstructionUses(instr, builder);
if (instr.lvalue != null) {
const oldPlace = instr.lvalue.place;
@@ -200,9 +200,9 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
}
}
const outputs = rewriteUsesAndCollectOutputs(block, builder);
const outputBlocks = outputs.map((id) => func.body.blocks.get(id)!);
for (const output of outputBlocks) {
rewriteTerminalOperands(block, builder);
for (const outputId of eachTerminalSuccessor(block.terminal)) {
const output = func.body.blocks.get(outputId)!;
let count;
if (builder.unsealedPreds.has(output)) {
count = builder.unsealedPreds.get(output)! - 1;
@@ -218,11 +218,7 @@ export default function enterSSA(func: HIRFunction, env: Environment) {
}
}
function rewriteUsesAndCollectOutputs(
block: BasicBlock,
builder: SSABuilder
): Array<BlockId> {
const outputs: Array<BlockId> = [];
function rewriteTerminalOperands(block: BasicBlock, builder: SSABuilder): void {
const { terminal } = block;
switch (terminal.kind) {
case "return":
@@ -233,14 +229,11 @@ function rewriteUsesAndCollectOutputs(
break;
}
case "goto": {
outputs.push(terminal.block);
break;
}
case "if": {
const { consequent, alternate } = terminal;
terminal.test = builder.getPlace(terminal.test);
outputs.push(alternate);
outputs.push(consequent);
break;
}
case "switch": {
@@ -250,7 +243,6 @@ function rewriteUsesAndCollectOutputs(
if (case_.test) {
case_.test = builder.getPlace(case_.test);
}
outputs.push(case_.block);
}
break;
}
@@ -261,11 +253,9 @@ function rewriteUsesAndCollectOutputs(
);
}
}
return outputs;
}
function rewriteUses(instr: Instruction, builder: SSABuilder) {
function rewriteInstructionUses(instr: Instruction, builder: SSABuilder) {
const instrValue = instr.value;
switch (instrValue.kind) {
+3 -29
View File
@@ -19,7 +19,7 @@ import {
Terminal,
} from "./HIR";
import { printInstruction } from "./PrintHIR";
import { mapTerminalSuccessors } from "./visitors";
import { eachTerminalSuccessor, mapTerminalSuccessors } from "./visitors";
// *******************************************************************************************
// *******************************************************************************************
@@ -512,34 +512,8 @@ function markPredecessors(func: HIR) {
const { terminal } = block;
switch (terminal.kind) {
case "return":
case "throw": {
break;
}
case "goto": {
visit(terminal.block, block);
break;
}
case "if": {
const { consequent, alternate } = terminal;
visit(alternate, block);
visit(consequent, block);
break;
}
case "switch": {
const { cases } = terminal;
for (const case_ of [...cases]) {
visit(case_.block, block);
}
break;
}
default: {
assertExhaustive(
terminal,
`Unexpected terminal kind '${(terminal as any).kind}'`
);
}
for (const successor of eachTerminalSuccessor(terminal)) {
visit(successor, block);
}
}
visit(func.entry, null);
@@ -16,15 +16,14 @@ import {
InstructionValue,
Phi,
Place,
Terminal,
ValueKind,
} from "./HIR";
import { printMixedHIR, printPlace, printSourceLocation } from "./PrintHIR";
import {
eachInstructionOperand,
eachTerminalOperand,
mapTerminalSuccessors,
eachTerminalSuccessor,
} from "./visitors";
import { printMixedHIR, printPlace, printSourceLocation } from "./PrintHIR";
/**
* For every usage of a value in the given function, infers the effect or action
@@ -137,17 +136,9 @@ export default function inferReferenceEffects(fn: HIRFunction) {
const environment = incomingEnvironment.clone();
inferBlock(environment, block);
// TODO: add a `forEachTerminalSuccessor` helper, we don't actually want the result
// here
const _ = mapTerminalSuccessors(
block.terminal,
(nextBlockId, isFallthrough) => {
if (!isFallthrough) {
queue(nextBlockId, environment);
}
return nextBlockId;
}
);
for (const nextBlockId of eachTerminalSuccessor(block.terminal)) {
queue(nextBlockId, environment);
}
}
}
}
+37
View File
@@ -129,6 +129,43 @@ export function mapTerminalSuccessors(
}
}
/**
* Iterates over the successor block ids of the provided terminal. The function is called
* specifically for the successors that define the standard control flow, and not
* pseduo-successors such as fallthroughs.
*/
export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
switch (terminal.kind) {
case "goto": {
yield terminal.block;
break;
}
case "if": {
yield terminal.consequent;
yield terminal.alternate;
break;
}
case "switch": {
for (const case_ of terminal.cases) {
yield case_.block;
}
break;
}
case "return": {
break;
}
case "throw": {
break;
}
default: {
assertExhaustive(
terminal,
`Unexpected terminal kind '${(terminal as any as Terminal).kind}'`
);
}
}
}
export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
switch (terminal.kind) {
case "if": {
@@ -43,7 +43,7 @@ bb0:
[6] Const mutate max$32 = Call mutate Math$8.max(read $31, read maxItems$28)
Goto bb1
bb1:
predecessor blocks: bb0 bb4 bb7
predecessor blocks: bb0 bb7 bb4
If (read items$27) then:bb3 else:bb2
bb3:
predecessor blocks: bb1
@@ -59,8 +59,8 @@ bb9:
[10] Const mutate $39 = Call mutate seen$30.has(mutate item$10)
Goto bb7
bb7:
predecessor blocks: bb9 bb8
$40: phi(bb9: $39, bb8: $37)
predecessor blocks: bb8 bb9
$40: phi(bb8: $37, bb9: $39)
If (read $40) then:bb1 else:bb4
bb4:
predecessor blocks: bb7
@@ -71,7 +71,7 @@ bb4:
[15] Const mutate $49 = Binary read renderedItems$29.length >= read max$32
If (read $49) then:bb2 else:bb1
bb2:
predecessor blocks: bb1 bb4
predecessor blocks: bb4 bb1
[16] Const mutate count$52 = read renderedItems$29.length
[17] Const mutate $53 = "div"
[18] Const mutate $54 = "\n "
@@ -118,7 +118,7 @@ bb2:
[3] Call mutate a$4.push(read props$3.c)
Goto bb1
bb1:
predecessor blocks: bb0 bb2
predecessor blocks: bb2 bb0
[4] Call mutate a$4.push(read props$3.d)
Return freeze a$4
```
@@ -218,7 +218,7 @@ bb2:
[3] Call mutate a$4.push(read props$3.c)
Goto bb1
bb1:
predecessor blocks: bb2 bb0
predecessor blocks: bb0 bb2
[4] Call mutate a$4.push(read props$3.d)
Return freeze a$4
```
@@ -75,14 +75,14 @@ bb2:
[3] Call mutate a$7.push(read props$6.p0)
Goto bb1
bb1:
predecessor blocks: bb0 bb2
predecessor blocks: bb2 bb0
If (read props$6.p1) then:bb4 else:bb3
bb4:
predecessor blocks: bb1
[4] Call mutate b$8.push(read props$6.p2)
Goto bb3
bb3:
predecessor blocks: bb1 bb4
predecessor blocks: bb4 bb1
[5] Const mutate $16 = JSX <read Foo$4 a={freeze a$7} b={freeze b$8} ></read Foo$4>
Return read $16
```
@@ -120,14 +120,14 @@ bb2:
[4] Call mutate a$9.push(read props$8.p0)
Goto bb1
bb1:
predecessor blocks: bb0 bb2
predecessor blocks: bb2 bb0
If (read props$8.p1) then:bb4 else:bb3
bb4:
predecessor blocks: bb1
[5] Call mutate b$10.push(read props$8.p2)
Goto bb3
bb3:
predecessor blocks: bb1 bb4
predecessor blocks: bb4 bb1
[6] Const mutate $19 = JSX <read Foo$6 a={freeze a$9} b={freeze b$10} ></read Foo$6>
Return read $19
```
@@ -39,8 +39,8 @@ bb3:
[5] Reassign mutate a$12 = Array []
Goto bb1
bb1:
predecessor blocks: bb3 bb2
a$14: phi(bb3: a$12, bb2: a$11)
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)
@@ -106,7 +106,7 @@ bb2:
[4] Call mutate mutate$5(mutate b$10)
Goto bb1
bb1:
predecessor blocks: bb0 bb2
predecessor blocks: bb2 bb0
[5] Const mutate $14 = JSX <read Foo$6 a={freeze a$9} b={freeze b$10} ></read Foo$6>
Return read $14
```
@@ -84,7 +84,7 @@ bb2:
[3] Call mutate foo$5(mutate a$9, mutate b$10)
Goto bb1
bb1:
predecessor blocks: bb0 bb2
predecessor blocks: bb2 bb0
[4] Const mutate $14 = JSX <read Foo$6 a={freeze a$9} b={freeze b$10} ></read Foo$6>
Return read $14
```
@@ -34,8 +34,8 @@ bb3:
[3] Const mutate $7 = read $5
Goto bb1
bb1:
predecessor blocks: bb3 bb2
$8: phi(bb3: $7, bb2: $6)
predecessor blocks: bb2 bb3
$8: phi(bb2: $6, bb3: $7)
Return freeze $8
```
@@ -67,8 +67,8 @@ bb3:
[3] Const mutate $7 = Call mutate g$4()
Goto bb1
bb1:
predecessor blocks: bb3 bb2
$8: phi(bb3: $7, bb2: $6)
predecessor blocks: bb2 bb3
$8: phi(bb2: $6, bb3: $7)
Return freeze $8
```
@@ -102,8 +102,8 @@ bb3:
[5] Const mutate $13 = Call mutate g$7()
Goto bb1
bb1:
predecessor blocks: bb3 bb2
$14: phi(bb3: $13, bb2: $12)
predecessor blocks: bb2 bb3
$14: phi(bb2: $12, bb3: $13)
Return freeze $14
```
@@ -97,11 +97,11 @@ bb3:
[12] Const mutate $29 = Call mutate cond$8(mutate a$21)
If (read $29) then:bb2 else:bb1
bb2:
predecessor blocks: bb1 bb3
a$30: phi(bb1: a$18, bb3: a$21)
b$31: phi(bb1: b$20, bb3: b$23)
c$32: phi(bb1: c$22, bb3: c$25)
d$33[-1:14]: phi(bb1: d$24, bb3: d$26)
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
bb7:
predecessor blocks: bb2
@@ -83,7 +83,7 @@ bb3:
[7] Const mutate $21 = Call mutate cond$7(mutate a$12)
If (read $21) then:bb2 else:bb1
bb2:
predecessor blocks: bb1 bb3
predecessor blocks: bb3 bb1
If (read a$12) then:bb7 else:bb7
bb7:
predecessor blocks: bb2
@@ -32,8 +32,8 @@ bb2:
[4] Reassign mutate x$9 = Array []
Goto bb1
bb1:
predecessor blocks: bb0 bb2
x$11: phi(bb0: x$7, bb2: x$9)
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>
[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>
@@ -72,8 +72,8 @@ bb13:
[9] Reassign mutate x$15 = read props$6.c
Goto bb1
bb1:
predecessor blocks: bb13 bb12 bb8 bb6 bb4
x$16: phi(bb13: x$15, bb12: x$14, bb8: x$11, bb6: x$12, bb4: x$13)
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
Return
```
@@ -48,7 +48,7 @@ bb2:
[6] Let mutate _$15 = JSX <read $14 a={freeze a$11} ></read $14>
Goto bb1
bb1:
predecessor blocks: bb0 bb2
predecessor blocks: bb2 bb0
[7] Call mutate foo$4(read a$11, mutate b$12)
[8] Const mutate $19 = "div"
[9] Const mutate $20 = JSX <read $19 a={freeze a$11} b={freeze b$12} ></read $19>
@@ -31,8 +31,8 @@ bb2:
[5] Reassign mutate x$11 = 3
Goto bb1
bb1:
predecessor blocks: bb0 bb2
x$17: phi(bb0: x$7, bb2: x$11)
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
@@ -41,8 +41,8 @@ bb4:
[8] Reassign mutate x$15 = 5
Goto bb3
bb3:
predecessor blocks: bb1 bb4
x$16: phi(bb1: x$17, bb4: x$15)
predecessor blocks: bb4 bb1
x$16: phi(bb4: x$15, bb1: x$17)
[9] Reassign mutate y$18 = read x$16
Return
```
@@ -28,8 +28,8 @@ bb2:
[5] Reassign mutate x$9 = 3
Goto bb1
bb1:
predecessor blocks: bb0 bb2
x$10: phi(bb0: x$5, bb2: x$9)
predecessor blocks: bb2 bb0
x$10: phi(bb2: x$9, bb0: x$5)
[6] Reassign mutate y$11 = read x$10
Return
```
@@ -22,7 +22,7 @@ bb0:
[1] Let mutate items$5 = Array []
Goto bb1
bb1:
predecessor blocks: bb0 bb3 bb5
predecessor blocks: bb0 bb5 bb3
If (read items$5) then:bb3 else:bb2
bb3:
predecessor blocks: bb1
@@ -31,7 +31,7 @@ bb3:
[4] Let mutate z$8 = read x$5
Goto bb1
bb1:
predecessor blocks: bb3 bb2
predecessor blocks: bb2 bb3
Return
```
@@ -36,9 +36,9 @@ bb3:
[6] Reassign mutate y$11 = 3
Goto bb1
bb1:
predecessor blocks: bb3 bb2
x$12: phi(bb3: x$6, bb2: x$10)
y$13: phi(bb3: y$11, bb2: y$7)
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 }
Return freeze t$14
```
@@ -26,8 +26,8 @@ bb2:
[4] Reassign mutate x$7 = 2
Goto bb1
bb1:
predecessor blocks: bb0 bb2
x$8: phi(bb0: x$4, bb2: x$7)
predecessor blocks: bb2 bb0
x$8: phi(bb2: x$7, bb0: x$4)
Return read x$8
```
@@ -33,8 +33,8 @@ bb3:
[5] Reassign mutate y$9 = 2
Goto bb1
bb1:
predecessor blocks: bb3 bb2
y$10: phi(bb3: y$9, bb2: y$8)
predecessor blocks: bb2 bb3
y$10: phi(bb2: y$8, bb3: y$9)
[6] Let mutate x$11 = read y$10
Return
```
@@ -25,7 +25,7 @@ bb2:
[3] Let mutate z$6 = Binary read x$4 + read y$5
Goto bb1
bb1:
predecessor blocks: bb0 bb2
predecessor blocks: bb2 bb0
Return
```
@@ -25,8 +25,8 @@ bb2:
[4] Reassign mutate x$7 = 2
Goto bb1
bb1:
predecessor blocks: bb0 bb2
x$8: phi(bb0: x$4, bb2: x$7)
predecessor blocks: bb2 bb0
x$8: phi(bb2: x$7, bb0: x$4)
Throw read x$8
```