diff --git a/compiler/forget/src/HIR/HIR.ts b/compiler/forget/src/HIR/HIR.ts index f489890e04..334f2dfa69 100644 --- a/compiler/forget/src/HIR/HIR.ts +++ b/compiler/forget/src/HIR/HIR.ts @@ -214,6 +214,7 @@ export type Terminal = | ReturnTerminal | GotoTerminal | IfTerminal + | BranchTerminal | SwitchTerminal | ForTerminal | WhileTerminal @@ -256,6 +257,14 @@ export type IfTerminal = { id: InstructionId; }; +export type BranchTerminal = { + kind: "branch"; + test: Place; + consequent: BlockId; + alternate: BlockId; + id: InstructionId; +}; + export type SwitchTerminal = { kind: "switch"; test: Place; diff --git a/compiler/forget/src/HIR/HIRBuilder.ts b/compiler/forget/src/HIR/HIRBuilder.ts index f686e7c352..347dc61782 100644 --- a/compiler/forget/src/HIR/HIRBuilder.ts +++ b/compiler/forget/src/HIR/HIRBuilder.ts @@ -553,6 +553,12 @@ export function reversePostorderBlocks(func: HIR): void { visit(consequent); break; } + case "branch": { + const { consequent, alternate } = terminal; + visit(alternate); + visit(consequent); + break; + } case "switch": { // can ignore fallthrough, if its reachable it will be reached through // a case diff --git a/compiler/forget/src/HIR/PrintHIR.ts b/compiler/forget/src/HIR/PrintHIR.ts index 00211d97f6..436d51a767 100644 --- a/compiler/forget/src/HIR/PrintHIR.ts +++ b/compiler/forget/src/HIR/PrintHIR.ts @@ -75,6 +75,7 @@ export function printMixedHIR( return printInstruction(value); } switch (value.kind) { + case "branch": case "if": case "logical": case "return": @@ -134,6 +135,12 @@ export function printTerminal(terminal: Terminal): Array | string { }`; break; } + case "branch": { + value = `[${terminal.id}] Branch (${printPlace(terminal.test)}) then:bb${ + terminal.consequent + } else:bb${terminal.alternate}`; + break; + } case "logical": { value = `[${terminal.id}] Logical ${terminal.operator} test:bb${terminal.test} fallthrough=bb${terminal.fallthrough}`; break; diff --git a/compiler/forget/src/HIR/visitors.ts b/compiler/forget/src/HIR/visitors.ts index 889ffbf2e7..be7300e2a2 100644 --- a/compiler/forget/src/HIR/visitors.ts +++ b/compiler/forget/src/HIR/visitors.ts @@ -253,6 +253,17 @@ export function mapTerminalSuccessors( id: makeInstructionId(0), }; } + case "branch": { + const consequent = fn(terminal.consequent); + const alternate = fn(terminal.alternate); + return { + kind: "branch", + test: terminal.test, + consequent, + alternate, + id: makeInstructionId(0), + }; + } case "switch": { const cases = terminal.cases.map((case_) => { const target = fn(case_.block); @@ -350,6 +361,11 @@ export function* eachTerminalSuccessor(terminal: Terminal): Iterable { yield terminal.alternate; break; } + case "branch": { + yield terminal.consequent; + yield terminal.alternate; + break; + } case "switch": { for (const case_ of terminal.cases) { yield case_.block; @@ -394,6 +410,10 @@ export function mapTerminalOperands( terminal.test = fn(terminal.test); break; } + case "branch": { + terminal.test = fn(terminal.test); + break; + } case "switch": { terminal.test = fn(terminal.test); for (const case_ of terminal.cases) { @@ -434,6 +454,10 @@ export function* eachTerminalOperand(terminal: Terminal): Iterable { yield terminal.test; break; } + case "branch": { + yield terminal.test; + break; + } case "switch": { yield terminal.test; for (const case_ of terminal.cases) { diff --git a/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts b/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts index 0c37e80a38..f3741fc73f 100644 --- a/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts +++ b/compiler/forget/src/ReactiveScopes/BuildReactiveFunction.ts @@ -360,6 +360,9 @@ class Driver { } break; } + case "branch": { + todo("Implement tree visitor for branch terminal"); + } case "logical": { todo("Implement tree visitor for logical terminal"); } diff --git a/compiler/forget/src/Utils/VisualizeHIRMermaid.ts b/compiler/forget/src/Utils/VisualizeHIRMermaid.ts index 94d82ba52b..6d55dccfe9 100644 --- a/compiler/forget/src/Utils/VisualizeHIRMermaid.ts +++ b/compiler/forget/src/Utils/VisualizeHIRMermaid.ts @@ -77,6 +77,10 @@ function printTerminalLabel(terminal: Terminal): string { buffer.push(`If (${printPlace(terminal.test)})`); break; } + case "branch": { + buffer.push(`Branch (${printPlace(terminal.test)})`); + break; + } case "goto": { buffer.push("Goto"); break; @@ -130,6 +134,11 @@ function printTerminalArrows(blockId: BlockId, terminal: Terminal): string { } break; } + case "branch": { + buffer.push(printJumpArrow(blockId, terminal.consequent, "then")); + buffer.push(printJumpArrow(blockId, terminal.alternate, "else")); + break; + } case "logical": { buffer.push(printJumpArrow(blockId, terminal.test, "test")); buffer.push(printJumpArrow(blockId, terminal.fallthrough, "fallthrough"));