mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
Add and use eachTerminalSuccessor()
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
```
|
||||
|
||||
+2
-2
@@ -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
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user