mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
"ValueBlock" for while test node
The instructions of a while test node cannot just be pushed to the previous block. This creates a new block for the test node and then during code gen converts the statements pushed to the "value block" into expressions.
This commit is contained in:
@@ -100,6 +100,10 @@ class CodegenVisitor
|
||||
this.depth++;
|
||||
return [];
|
||||
}
|
||||
enterValueBlock(): t.Statement[] {
|
||||
this.depth++;
|
||||
return [];
|
||||
}
|
||||
visitValue(value: InstructionValue): t.Expression {
|
||||
return codegenInstructionValue(this.temp, value);
|
||||
}
|
||||
@@ -237,6 +241,25 @@ class CodegenVisitor
|
||||
this.depth--;
|
||||
return t.blockStatement(block);
|
||||
}
|
||||
leaveValueBlock(block: t.Statement[], place: t.Expression): t.Expression {
|
||||
this.depth--;
|
||||
if (block.length === 0) {
|
||||
return place;
|
||||
}
|
||||
const expressions = block.map((stmt) => {
|
||||
switch (stmt.type) {
|
||||
case "ExpressionStatement":
|
||||
return stmt.expression;
|
||||
default:
|
||||
todoInvariant(
|
||||
false,
|
||||
`Handle conversion of ${stmt.type} to expression`
|
||||
);
|
||||
}
|
||||
});
|
||||
expressions.push(place);
|
||||
return t.sequenceExpression(expressions);
|
||||
}
|
||||
}
|
||||
|
||||
function codegenLabel(id: BlockId): string {
|
||||
|
||||
@@ -239,15 +239,20 @@ class Driver<TBlock, TValue, TItem, TCase> {
|
||||
testTerminal.kind === "if",
|
||||
"Expected while loop test block to end in an if"
|
||||
);
|
||||
// const bodyLength = blockValue.length;
|
||||
const testValueBlock = this.visitor.enterValueBlock();
|
||||
for (const instr of testBlock.instructions) {
|
||||
this.visitInstr(instr, blockValue);
|
||||
const value = this.visitor.visitValue(instr.value, instr.id);
|
||||
const item = this.visitor.visitInstruction(instr, value);
|
||||
this.visitor.appendBlock(testValueBlock, item);
|
||||
}
|
||||
// invariant(
|
||||
// body.length === bodyLength,
|
||||
// "Expected test to produce only temporaries"
|
||||
// );
|
||||
const testValue = this.visitPlace(testTerminal.test, terminal.id);
|
||||
const testValueLast = this.visitor.visitValue(
|
||||
testTerminal.test,
|
||||
testTerminal.id
|
||||
);
|
||||
const testValue = this.visitor.leaveValueBlock(
|
||||
testValueBlock,
|
||||
testValueLast
|
||||
);
|
||||
const fallthroughId =
|
||||
terminal.fallthrough !== null &&
|
||||
!this.cx.isScheduled(terminal.fallthrough)
|
||||
@@ -644,6 +649,10 @@ export interface Visitor<TBlock, TValue, TItem, TCase> {
|
||||
*/
|
||||
enterBlock(): TBlock;
|
||||
|
||||
enterValueBlock(): TBlock;
|
||||
|
||||
leaveValueBlock(block: TBlock, value: TValue): TValue;
|
||||
|
||||
/**
|
||||
* Convert an InstructionValue into the visitor's own representation
|
||||
* of a value.
|
||||
|
||||
@@ -189,8 +189,12 @@ class ScopeDependenciesVisitor
|
||||
}
|
||||
|
||||
enterBlock(): void {}
|
||||
enterValueBlock(): void {}
|
||||
visitImplicitTerminal(): void | null {}
|
||||
visitCase(test: InstructionValue, block: void): void {}
|
||||
appendBlock(block: void, item: void, label?: BlockId | undefined): void {}
|
||||
leaveBlock(block: void): void {}
|
||||
leaveValueBlock(block: void, value: InstructionValue): InstructionValue {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,6 +254,12 @@ class MergeOverlappingReactiveScopesVisitor
|
||||
enterBlock(): void {
|
||||
this.scopes.push(new BlockScope());
|
||||
}
|
||||
enterValueBlock(): void {
|
||||
this.enterBlock();
|
||||
}
|
||||
leaveValueBlock(block: void, value: void): void {
|
||||
this.leaveBlock();
|
||||
}
|
||||
visitValue(value: InstructionValue, id: InstructionId): void {
|
||||
this.visitId(id);
|
||||
for (const operand of eachInstructionValueOperand(value)) {
|
||||
@@ -355,6 +361,14 @@ class AlignReactiveScopesToBlockScopeRangeVisitor
|
||||
}
|
||||
}
|
||||
|
||||
enterValueBlock(): void {
|
||||
this.enterBlock();
|
||||
}
|
||||
|
||||
leaveValueBlock(block: void, value: void): void {
|
||||
this.leaveBlock();
|
||||
}
|
||||
|
||||
visitInstruction(instruction: Instruction, value: void): void {
|
||||
const scope = getInstructionScope(instruction);
|
||||
if (scope !== null) {
|
||||
|
||||
@@ -32,6 +32,12 @@ class PrintVisitor implements Visitor<Array<string>, string, string, string> {
|
||||
this.depth++;
|
||||
return [];
|
||||
}
|
||||
enterValueBlock(): string[] {
|
||||
return this.enterBlock();
|
||||
}
|
||||
leaveValueBlock(block: string[], value: string): string {
|
||||
return this.leaveBlock(block);
|
||||
}
|
||||
visitValue(value: InstructionValue): string {
|
||||
return printMixedHIR(value);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ bb1:
|
||||
sum$21_@3[0:14]: phi(bb0: sum$16_@3, bb3: sum$22_@3)
|
||||
[8] Reassign mutate value$18_@3[0:14] = Call mutate queue$14_@3.pop()
|
||||
[9] Const mutate $19_@6 = null
|
||||
[10] Const mutate $20_@7[10:14] = Binary read value$18_@3 != read $19_@6
|
||||
[10] Const mutate $20_@7[10:12] = Binary read value$18_@3 != read $19_@6
|
||||
[11] If (read $20_@7) then:bb3 else:bb2
|
||||
bb3:
|
||||
predecessor blocks: bb1
|
||||
@@ -40,7 +40,7 @@ bb3:
|
||||
bb2:
|
||||
predecessor blocks: bb1
|
||||
[14] Return read sum$21_@3
|
||||
scope7 [10:14]:
|
||||
scope7 [10:12]:
|
||||
- read $19_@6
|
||||
```
|
||||
|
||||
@@ -64,7 +64,7 @@ flowchart TB
|
||||
bb1_instrs["
|
||||
[8] Reassign mutate value$18_@3[0:14] = Call mutate queue$14_@3.pop()
|
||||
[9] Const mutate $19_@6 = null
|
||||
[10] Const mutate $20_@7[10:14] = Binary read value$18_@3 != read $19_@6
|
||||
[10] Const mutate $20_@7[10:12] = Binary read value$18_@3 != read $19_@6
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["If (read $20_@7)"])
|
||||
end
|
||||
@@ -95,8 +95,7 @@ function f$0(reader$1) {
|
||||
const queue$2 = [1, 2, 3];
|
||||
let value$6 = 0;
|
||||
let sum$7 = 0;
|
||||
value$6 = queue$2.pop();
|
||||
bb2: while (value$6 != null) {
|
||||
bb2: while (((value$6 = queue$2.pop()), value$6 != null)) {
|
||||
sum$7 = sum$7 + value$6;
|
||||
}
|
||||
|
||||
|
||||
@@ -108,7 +108,7 @@ bb1:
|
||||
b$20_@0[0:23]: phi(bb0: b$14_@0, bb4: b$23_@0)
|
||||
c$22_@0[0:23]: phi(bb0: c$15_@0, bb4: c$25_@0)
|
||||
d$24_@0[0:23]: phi(bb0: d$16_@0, bb4: d$26_@0)
|
||||
[6] Const mutate $17_@1[6:17] = true
|
||||
[6] Const mutate $17_@1[6:8] = true
|
||||
[7] If (read $17_@1) then:bb3 else:bb2
|
||||
bb3:
|
||||
predecessor blocks: bb1
|
||||
@@ -163,7 +163,7 @@ flowchart TB
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[6] Const mutate $17_@1[6:17] = true
|
||||
[6] Const mutate $17_@1[6:8] = true
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["If (read $17_@1)"])
|
||||
end
|
||||
|
||||
@@ -99,7 +99,7 @@ bb0:
|
||||
[5] While test=bb1 loop=bb3 fallthrough=bb2
|
||||
bb1:
|
||||
predecessor blocks: bb0 bb4
|
||||
[6] Const mutate $16_@2[6:12] = true
|
||||
[6] Const mutate $16_@2[6:8] = true
|
||||
[7] If (read $16_@2) then:bb3 else:bb2
|
||||
bb3:
|
||||
predecessor blocks: bb1
|
||||
@@ -145,7 +145,7 @@ flowchart TB
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[6] Const mutate $16_@2[6:12] = true
|
||||
[6] Const mutate $16_@2[6:8] = true
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["If (read $16_@2)"])
|
||||
end
|
||||
|
||||
@@ -17,12 +17,12 @@ function foo() {
|
||||
|
||||
```
|
||||
bb0:
|
||||
[1] Let mutate x$5_@0[1:3] = 1
|
||||
[1] Let mutate x$5_@0 = 1
|
||||
[2] While test=bb1 loop=bb3 fallthrough=bb2
|
||||
bb1:
|
||||
predecessor blocks: bb0 bb3
|
||||
[3] Const mutate $6_@1 = 10
|
||||
[4] Const mutate $8_@2[4:9] = Binary read x$5_@0 < read $6_@1
|
||||
[4] Const mutate $8_@2[4:6] = Binary read x$5_@0 < read $6_@1
|
||||
[5] If (read $8_@2) then:bb3 else:bb2
|
||||
bb3:
|
||||
predecessor blocks: bb1
|
||||
@@ -32,7 +32,7 @@ bb3:
|
||||
bb2:
|
||||
predecessor blocks: bb1
|
||||
[9] Return read x$5_@0
|
||||
scope2 [4:9]:
|
||||
scope2 [4:6]:
|
||||
- read x$5_@0
|
||||
- read $6_@1
|
||||
scope3 [6:7]:
|
||||
@@ -46,14 +46,14 @@ flowchart TB
|
||||
%% Basic Blocks
|
||||
subgraph bb0
|
||||
bb0_instrs["
|
||||
[1] Let mutate x$5_@0[1:3] = 1
|
||||
[1] Let mutate x$5_@0 = 1
|
||||
"]
|
||||
bb0_instrs --> bb0_terminal(["While"])
|
||||
end
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[3] Const mutate $6_@1 = 10
|
||||
[4] Const mutate $8_@2[4:9] = Binary read x$5_@0 < read $6_@1
|
||||
[4] Const mutate $8_@2[4:6] = Binary read x$5_@0 < read $6_@1
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["If (read $8_@2)"])
|
||||
end
|
||||
|
||||
@@ -23,7 +23,7 @@ bb1:
|
||||
predecessor blocks: bb0 bb3
|
||||
x$7_@0[0:9]: phi(bb0: x$5_@0, bb3: x$10_@0)
|
||||
[3] Const mutate $6_@1 = 10
|
||||
[4] Const mutate $8_@2[4:9] = Binary read x$7_@0 < read $6_@1
|
||||
[4] Const mutate $8_@2[4:6] = Binary read x$7_@0 < read $6_@1
|
||||
[5] If (read $8_@2) then:bb3 else:bb2
|
||||
bb3:
|
||||
predecessor blocks: bb1
|
||||
@@ -33,7 +33,7 @@ bb3:
|
||||
bb2:
|
||||
predecessor blocks: bb1
|
||||
[9] Return read x$7_@0
|
||||
scope2 [4:9]:
|
||||
scope2 [4:6]:
|
||||
- read $6_@1
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ flowchart TB
|
||||
subgraph bb1
|
||||
bb1_instrs["
|
||||
[3] Const mutate $6_@1 = 10
|
||||
[4] Const mutate $8_@2[4:9] = Binary read x$7_@0 < read $6_@1
|
||||
[4] Const mutate $8_@2[4:6] = Binary read x$7_@0 < read $6_@1
|
||||
"]
|
||||
bb1_instrs --> bb1_terminal(["If (read $8_@2)"])
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user