[valueblocks] Scaffolding for branch terminal
Scaffolding for a new 'branch' terminal, which is the lower-level form of 'if' meant for use in value blocks. See design at https://fb.quip.com/b7N6AjkDcl2a#temp:C:bAO904b0cf06f154de4a7287af6d
Joe Savona committed
Jan 25, 2023 at 17:05 UTC
f88fa006e716a4a39cbf0608165956afb2b21fcb
6 files changed
+58
compiler/forget/src/HIR/HIR.ts
+9
@@ -214,6 +214,7 @@ export type Terminal =
214
| ReturnTerminal
215
| GotoTerminal
216
| IfTerminal
217
+ | BranchTerminal
218
| SwitchTerminal
219
| ForTerminal
220
| WhileTerminal
@@ -256,6 +257,14 @@ export type IfTerminal = {
257
id: InstructionId;
258
};
259
260
+export type BranchTerminal = {
261
+ kind: "branch";
262
+ test: Place;
263
+ consequent: BlockId;
264
+ alternate: BlockId;
265
+ id: InstructionId;
266
+};
267
+
268
export type SwitchTerminal = {
269
kind: "switch";
270
test: Place;
compiler/forget/src/HIR/HIRBuilder.ts
+6
@@ -553,6 +553,12 @@ export function reversePostorderBlocks(func: HIR): void {
553
visit(consequent);
554
break;
555
}
556
+ case "branch": {
557
+ const { consequent, alternate } = terminal;
558
+ visit(alternate);
559
+ visit(consequent);
560
+ break;
561
+ }
562
case "switch": {
563
// can ignore fallthrough, if its reachable it will be reached through
564
// a case
compiler/forget/src/HIR/PrintHIR.ts
+7
@@ -75,6 +75,7 @@ export function printMixedHIR(
75
return printInstruction(value);
76
}
77
switch (value.kind) {
78
+ case "branch":
79
case "if":
80
case "logical":
81
case "return":
@@ -134,6 +135,12 @@ export function printTerminal(terminal: Terminal): Array<string> | string {
135
}`;
136
break;
137
}
138
+ case "branch": {
139
+ value = `[${terminal.id}] Branch (${printPlace(terminal.test)}) then:bb${
140
+ terminal.consequent
141
+ } else:bb${terminal.alternate}`;
142
+ break;
143
+ }
144
case "logical": {
145
value = `[${terminal.id}] Logical ${terminal.operator} test:bb${terminal.test} fallthrough=bb${terminal.fallthrough}`;
146
break;
compiler/forget/src/HIR/visitors.ts
+24
@@ -253,6 +253,17 @@ export function mapTerminalSuccessors(
253
id: makeInstructionId(0),
254
};
255
}
256
+ case "branch": {
257
+ const consequent = fn(terminal.consequent);
258
+ const alternate = fn(terminal.alternate);
259
+ return {
260
+ kind: "branch",
261
+ test: terminal.test,
262
+ consequent,
263
+ alternate,
264
+ id: makeInstructionId(0),
265
+ };
266
+ }
267
case "switch": {
268
const cases = terminal.cases.map((case_) => {
269
const target = fn(case_.block);
@@ -350,6 +361,11 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable<BlockId> {
361
yield terminal.alternate;
362
break;
363
}
364
+ case "branch": {
365
+ yield terminal.consequent;
366
+ yield terminal.alternate;
367
+ break;
368
+ }
369
case "switch": {
370
for (const case_ of terminal.cases) {
371
yield case_.block;
@@ -394,6 +410,10 @@ export function mapTerminalOperands(
410
terminal.test = fn(terminal.test);
411
break;
412
}
413
+ case "branch": {
414
+ terminal.test = fn(terminal.test);
415
+ break;
416
+ }
417
case "switch": {
418
terminal.test = fn(terminal.test);
419
for (const case_ of terminal.cases) {
@@ -434,6 +454,10 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable<Place> {
454
yield terminal.test;
455
break;
456
}
457
+ case "branch": {
458
+ yield terminal.test;
459
+ break;
460
+ }
461
case "switch": {
462
yield terminal.test;
463
for (const case_ of terminal.cases) {
compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts
+3
@@ -360,6 +360,9 @@ class Driver {
360
}
361
break;
362
}
363
+ case "branch": {
364
+ todo("Implement tree visitor for branch terminal");
365
+ }
366
case "logical": {
367
todo("Implement tree visitor for logical terminal");
368
}
compiler/forget/src/Utils/VisualizeHIRMermaid.ts
+9
@@ -77,6 +77,10 @@ function printTerminalLabel(terminal: Terminal): string {
77
buffer.push(`If (${printPlace(terminal.test)})`);
78
break;
79
}
80
+ case "branch": {
81
+ buffer.push(`Branch (${printPlace(terminal.test)})`);
82
+ break;
83
+ }
84
case "goto": {
85
buffer.push("Goto");
86
break;
@@ -130,6 +134,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string {
134
}
135
break;
136
}
137
+ case "branch": {
138
+ buffer.push(printJumpArrow(blockId, terminal.consequent, "then"));
139
+ buffer.push(printJumpArrow(blockId, terminal.alternate, "else"));
140
+ break;
141
+ }
142
case "logical": {
143
buffer.push(printJumpArrow(blockId, terminal.test, "test"));
144
buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));