diff --git a/compiler/forget/src/HIR/VisualizeHIRMermaid.ts b/compiler/forget/src/HIR/VisualizeHIRMermaid.ts new file mode 100644 index 0000000000..4acc79b5d0 --- /dev/null +++ b/compiler/forget/src/HIR/VisualizeHIRMermaid.ts @@ -0,0 +1,180 @@ +import { assertExhaustive } from "../Common/utils"; +import { BasicBlock, BlockId, HIRFunction, Terminal } from "./HIR"; +import { printInstruction, printPlace } from "./PrintHIR"; + +enum MermaidFlowchartDirection { + TopBottom = "TB", // top to bottom + TopDown = "TD", // top-down/ same as top to bottom + BottomTop = "BT", // bottom to top + RightLeft = "RL", // right to left + LeftRight = "LR", // left to right +} + +function indent(str: string, level: number = 1) { + const leadingSpaces = " ".repeat(level * 2); + return str + .split("\n") + .map((line) => `${leadingSpaces}${line}`) + .join("\n"); +} + +function printBlockId(id: BlockId): string { + return `bb${id}`; +} + +function printJump(from: BlockId, to: BlockId, label: string | null): string { + const fromId = printBlockId(from); + const toId = printBlockId(to); + if (label != null) { + return `${fromId}_terminal -- ${label} --> ${toId}\n`; + } + return `${fromId}_terminal --> ${toId}\n`; +} + +function visualizeInstructions({ id, instructions }: BasicBlock): string { + return ( + `${printBlockId(id)}_instrs["\n` + + indent( + instructions + .map((instr) => printInstruction(instr).replaceAll('"', "'")) + .join("\n"), + 2 + ) + + indent('\n"]') + ); +} + +function visualizeTerminal(terminal: Terminal) { + let buffer = ""; + switch (terminal.kind) { + case "if": { + buffer = buffer.concat(`If (${printPlace(terminal.test)})`); + break; + } + case "goto": { + buffer = buffer.concat("Goto"); + break; + } + case "return": { + if (terminal.value != null) { + buffer = buffer.concat(`Return ${printPlace(terminal.value)}`); + } else { + buffer = buffer.concat("Return"); + } + break; + } + case "switch": + buffer = buffer.concat(`Switch (${printPlace(terminal.test)})`); + break; + case "throw": + buffer = buffer.concat(`Throw ${printPlace(terminal.value)}`); + break; + case "while": + buffer = buffer.concat("While"); + break; + default: + assertExhaustive(terminal, `unhandled terminal ${terminal}`); + } + return buffer; +} + +function visualizeJump(blockId: BlockId, terminal: Terminal): string { + let buffer = ""; + switch (terminal.kind) { + case "if": { + buffer = buffer.concat(printJump(blockId, terminal.consequent, "then")); + buffer = buffer.concat(printJump(blockId, terminal.alternate, "else")); + if ( + terminal.fallthrough != null && + terminal.alternate !== terminal.fallthrough + ) { + buffer = buffer.concat( + printJump(blockId, terminal.fallthrough, "fallthrough") + ); + } + break; + } + case "goto": { + buffer = buffer.concat(printJump(blockId, terminal.block, null)); + break; + } + case "switch": { + terminal.cases.forEach((case_) => { + if (case_.test != null) { + buffer = buffer.concat( + printJump(blockId, case_.block, printPlace(case_.test)) + ); + } else { + buffer = buffer.concat(printJump(blockId, case_.block, "default")); + } + }); + if (terminal.fallthrough != null) { + buffer = buffer.concat( + printJump(blockId, terminal.fallthrough, "fallthrough") + ); + } + break; + } + case "while": { + buffer = buffer.concat(printJump(blockId, terminal.test, "test")); + buffer = buffer.concat(printJump(blockId, terminal.loop, "loop")); + buffer = buffer.concat( + printJump(blockId, terminal.fallthrough, "fallthrough") + ); + break; + } + case "throw": + case "return": { + break; + } + default: + assertExhaustive(terminal, `unhandled terminal ${terminal}`); + } + return buffer; +} + +/** + * Visualizes the HIR as a mermaid.js diagram. + */ +export default function visualizeHIRMermaid(fn: HIRFunction): string { + const ir = fn.body; + const subgraphs = []; + const jumps = []; + + for (const [blockId, block] of ir.blocks) { + let buffer; + const bbId = printBlockId(blockId); + buffer = indent(`subgraph ${bbId}\n`); + if (block.instructions.length > 0) { + buffer = buffer.concat(indent(visualizeInstructions(block))); + buffer = buffer.concat( + indent( + `\n${bbId}_instrs --> ${bbId}_terminal(["${visualizeTerminal( + block.terminal + )}"])`, + 2 + ) + ); + } else { + buffer = buffer.concat( + indent(`${bbId}_terminal(["${visualizeTerminal(block.terminal)}"])`) + ); + } + buffer = buffer.concat(indent("\nend\n")); + subgraphs.push(buffer); + } + + for (const [blockId, block] of ir.blocks) { + const jump = visualizeJump(blockId, block.terminal); + if (jump.length > 0) { + jumps.push(indent(jump)); + } + } + + return `flowchart ${MermaidFlowchartDirection.TopBottom} + %% Basic Blocks +${subgraphs.length ? subgraphs.join("\n") : " %% empty"} + + %% Jumps +${jumps.length ? jumps.join("\n") : " %% empty"}`; +} diff --git a/compiler/forget/src/__tests__/fixtures/hir/call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/call.expect.md index 266571ba79..f250eadb45 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/call.expect.md @@ -22,6 +22,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -45,6 +59,30 @@ bb0: Return read $15 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$10[1:3] = Array [] + [2] Const mutate b$11[2:6] = Object { } + [3] Call mutate foo$4(mutate a$10, mutate b$11) + [4] Const mutate $12 = 'div' + [5] Let mutate _$13 = JSX + [6] Call mutate foo$4(mutate b$11) + [7] Const mutate $14 = 'div' + [8] Const mutate $15 = JSX + "] + bb0_instrs --> bb0_terminal(["Return read $15"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/complex-while.expect.md b/compiler/forget/src/__tests__/fixtures/hir/complex-while.expect.md index d4a5a7a48e..b7bff457a3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/complex-while.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/complex-while.expect.md @@ -36,6 +36,54 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["If (read a$4)"]) + end + + subgraph bb3 + bb3_terminal(["While"]) + end + + subgraph bb4 + bb4_terminal(["If (read b$5)"]) + end + + subgraph bb6 + bb6_terminal(["If (read c$6)"]) + end + + subgraph bb7 + bb7_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb3 + bb0_terminal -- else --> bb1 + + bb3_terminal -- test --> bb4 + bb3_terminal -- loop --> bb6 + bb3_terminal -- fallthrough --> bb1 + + bb4_terminal -- then --> bb6 + bb4_terminal -- else --> bb1 + + bb6_terminal -- then --> bb1 + bb6_terminal -- else --> bb7 + + bb7_terminal --> bb4 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md index 91672e54db..b3a672d45d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/component.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/component.expect.md @@ -89,6 +89,114 @@ bb2: Return read $60 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate items$27 = read props$26.items + [2] Const mutate maxItems$28 = read props$26.maxItems + [3] Const mutate renderedItems$29[3:14] = Array [] + [4] Const mutate seen$30[4:11] = New mutate Set$6() + [5] Const mutate $31 = 0 + [6] Const mutate max$32 = Call mutate Math$8.max(read $31, read maxItems$28) + "] + bb0_instrs --> bb0_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["If (read items$27)"]) + end + + subgraph bb3 + bb3_instrs[" + [7] Const mutate $34 = null + [8] Const mutate $36 = Binary read item$10 == read $34 + "] + bb3_instrs --> bb3_terminal(["If (read $36)"]) + end + + subgraph bb8 + bb8_instrs[" + [9] Const mutate $13 = read $36 + "] + bb8_instrs --> bb8_terminal(["Goto"]) + end + + subgraph bb9 + bb9_instrs[" + [10] Const mutate $13 = Call mutate seen$30.has(mutate item$10) + "] + bb9_instrs --> bb9_terminal(["Goto"]) + end + + subgraph bb7 + bb7_terminal(["If (read $13)"]) + end + + subgraph bb5 + bb5_terminal(["Goto"]) + end + + subgraph bb4 + bb4_instrs[" + [11] Call mutate seen$30.add(mutate item$10) + [12] Const mutate $43 = 'div' + [13] Const mutate $44 = JSX {read item$10} + [14] Call mutate renderedItems$29.push(read $44) + [15] Const mutate $49 = Binary read renderedItems$29.length >= read max$32 + "] + bb4_instrs --> bb4_terminal(["If (read $49)"]) + end + + subgraph bb10 + bb10_terminal(["Goto"]) + end + + subgraph bb2 + bb2_instrs[" + [16] Const mutate count$52 = read renderedItems$29.length + [17] Const mutate $53 = 'div' + [18] Const mutate $54 = '\n ' + [19] Const mutate $55 = 'h1' + [20] Const mutate $56 = ' Items' + [21] Const mutate $57 = JSX {freeze count$52}{read $56} + [22] Const mutate $58 = '\n ' + [23] Const mutate $59 = '\n ' + [24] Const mutate $60 = JSX {read $54}{read $57}{read $58}{freeze renderedItems$29}{read $59} + "] + bb2_instrs --> bb2_terminal(["Return read $60"]) + end + + + %% Jumps + bb0_terminal --> bb1 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb2 + + bb3_terminal -- then --> bb8 + bb3_terminal -- else --> bb9 + bb3_terminal -- fallthrough --> bb7 + + bb8_terminal --> bb7 + + bb9_terminal --> bb7 + + bb7_terminal -- then --> bb5 + bb7_terminal -- else --> bb4 + + bb5_terminal --> bb1 + + bb4_terminal -- then --> bb2 + bb4_terminal -- else --> bb10 + + bb10_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md b/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md index b8bbf62288..03e206f78c 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/conditional-break.expect.md @@ -91,6 +91,40 @@ bb1: Return freeze a_DEBUG$5 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a_DEBUG$5[1:4] = Array [] + [2] Call mutate a_DEBUG$5.push(read props$4.a) + "] + bb0_instrs --> bb0_terminal(["If (read props$4.b)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Const mutate $6 = null + "] + bb2_instrs --> bb2_terminal(["Return read $6"]) + end + + subgraph bb1 + bb1_instrs[" + [4] Call mutate a_DEBUG$5.push(read props$4.d) + "] + bb1_instrs --> bb1_terminal(["Return freeze a_DEBUG$5"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + +``` + ## Code ```javascript @@ -123,6 +157,42 @@ bb1: Return freeze a$4 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$4[1:4] = Array [] + [2] Call mutate a$4.push(read props$3.a) + "] + bb0_instrs --> bb0_terminal(["If (read props$3.b)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Call mutate a$4.push(read props$3.c) + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [4] Call mutate a$4.push(read props$3.d) + "] + bb1_instrs --> bb1_terminal(["Return freeze a$4"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript @@ -156,6 +226,41 @@ bb1: Return freeze a$5 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$5[1:5] = Array [] + [2] Call mutate a$5.push(read props$4.a) + "] + bb0_instrs --> bb0_terminal(["If (read props$4.b)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Call mutate a$5.push(read props$4.c) + [4] Const mutate $6 = null + "] + bb2_instrs --> bb2_terminal(["Return read $6"]) + end + + subgraph bb1 + bb1_instrs[" + [5] Call mutate a$5.push(read props$4.d) + "] + bb1_instrs --> bb1_terminal(["Return freeze a$5"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + +``` + ## Code ```javascript @@ -189,6 +294,40 @@ bb1: Return freeze a$4 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$4[1:4] = Array [] + [2] Call mutate a$4.push(read props$3.a) + "] + bb0_instrs --> bb0_terminal(["If (read props$3.b)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Call mutate a$4.push(read props$3.c) + "] + bb2_instrs --> bb2_terminal(["Return freeze a$4"]) + end + + subgraph bb1 + bb1_instrs[" + [4] Call mutate a$4.push(read props$3.d) + "] + bb1_instrs --> bb1_terminal(["Return freeze a$4"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + +``` + ## Code ```javascript @@ -222,6 +361,42 @@ bb1: Return freeze a$4 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$4[1:4] = Array [] + [2] Call mutate a$4.push(read props$3.a) + "] + bb0_instrs --> bb0_terminal(["If (read props$3.b)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Call mutate a$4.push(read props$3.c) + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [4] Call mutate a$4.push(read props$3.d) + "] + bb1_instrs --> bb1_terminal(["Return freeze a$4"]) + end + + + %% Jumps + bb0_terminal -- then --> bb1 + bb0_terminal -- else --> bb2 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md b/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md index 102b79b8f7..ef548de759 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/conditional-on-mutable.expect.md @@ -87,6 +87,58 @@ bb3: Return read $16 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$7[1:3] = Array [] + [2] Const mutate b$8[2:4] = Array [] + "] + bb0_instrs --> bb0_terminal(["If (read b$8)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Call mutate a$7.push(read props$6.p0) + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["If (read props$6.p1)"]) + end + + subgraph bb4 + bb4_instrs[" + [4] Call mutate b$8.push(read props$6.p2) + "] + bb4_instrs --> bb4_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [5] Const mutate $16 = JSX + "] + bb3_instrs --> bb3_terminal(["Return read $16"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + + bb1_terminal -- then --> bb4 + bb1_terminal -- else --> bb3 + + bb4_terminal --> bb3 + +``` + ## Code ```javascript @@ -130,6 +182,59 @@ bb3: Return read $19 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$9[1:4] = Array [] + [2] Const mutate b$10[2:5] = Array [] + [3] Const mutate $11 = Call mutate mayMutate$4(mutate b$10) + "] + bb0_instrs --> bb0_terminal(["If (read $11)"]) + end + + subgraph bb2 + bb2_instrs[" + [4] Call mutate a$9.push(read props$8.p0) + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["If (read props$8.p1)"]) + end + + subgraph bb4 + bb4_instrs[" + [5] Call mutate b$10.push(read props$8.p2) + "] + bb4_instrs --> bb4_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [6] Const mutate $19 = JSX + "] + bb3_instrs --> bb3_terminal(["Return read $19"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + + bb1_terminal -- then --> bb4 + bb1_terminal -- else --> bb3 + + bb4_terminal --> bb3 + +``` + ## Code ```javascript @@ -155,6 +260,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -170,6 +289,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md b/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md index db938165ec..a12866202b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/constructor.expect.md @@ -22,6 +22,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -45,6 +59,30 @@ bb0: Return read $15 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$10[1:3] = Array [] + [2] Const mutate b$11[2:6] = Object { } + [3] New mutate Foo$4(mutate a$10, mutate b$11) + [4] Const mutate $12 = 'div' + [5] Let mutate _$13 = JSX + [6] New mutate Foo$4(mutate b$11) + [7] Const mutate $14 = 'div' + [8] Const mutate $15 = JSX + "] + bb0_instrs --> bb0_terminal(["Return read $15"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md b/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md index cecedebf17..5ed0980796 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/frozen-after-alias.expect.md @@ -25,6 +25,26 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$5 = Array [] + [2] Const mutate b$6 = read a$5 + [3] Call read useFreeze$3(freeze a$5) + [4] Call mutate foo$4(read b$6) + "] + bb0_instrs --> bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -44,6 +64,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -59,6 +93,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md index 2aeaa9552f..276af34db0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hook-call.expect.md @@ -26,6 +26,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -41,6 +55,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -63,6 +91,29 @@ bb0: Return read $16 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate x$11 = Array [] + [2] Const mutate y$12 = Call read useFreeze$4(freeze x$11) + [3] Call mutate foo$5(read y$12, read x$11) + [4] Const mutate $13 = '\n ' + [5] Const mutate $14 = '\n ' + [6] Const mutate $15 = '\n ' + [7] Const mutate $16 = JSX {read $13}{read x$11}{read $14}{read y$12}{read $15} + "] + bb0_instrs --> bb0_terminal(["Return read $16"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md index 43841c4c64..4c20a077d0 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-arguments.expect.md @@ -26,6 +26,26 @@ bb0: Return read a$4 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$4 = Array [] + [2] Call read useFreeze$2(freeze a$4) + [3] Call read useFreeze$2(read a$4) + [4] Call mutate call$3(read a$4) + "] + bb0_instrs --> bb0_terminal(["Return read a$4"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -45,6 +65,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -60,6 +94,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md index 5a350ddf60..a6683d8e10 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/hooks-freeze-possibly-mutable-arguments.expect.md @@ -46,6 +46,55 @@ bb1: Return read a$4 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate cond$8 = read props$7.cond + [2] Const mutate x$9 = read props$7.x + [3] Let mutate a$10 = undefined + "] + bb0_instrs --> bb0_terminal(["If (read cond$8)"]) + end + + subgraph bb2 + bb2_instrs[" + [4] Reassign mutate a$4 = read x$9 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [5] Reassign mutate a$4 = Array [] + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [6] Call read useFreeze$5(freeze a$4) + [7] Call read useFreeze$5(read a$4) + [8] Call mutate call$6(read a$4) + "] + bb1_instrs --> bb1_terminal(["Return read a$4"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb3 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal --> bb1 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript @@ -73,6 +122,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -88,6 +151,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md index 77ec0a40aa..7762e9f03d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent-across-if.expect.md @@ -40,6 +40,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -55,6 +69,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -70,6 +98,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -85,6 +127,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -111,6 +167,43 @@ bb1: Return read $14 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$9[1:3] = Call mutate compute$3(read props$8.a) + [2] Const mutate b$10[2:4] = Call mutate compute$3(read props$8.b) + "] + bb0_instrs --> bb0_terminal(["If (read props$8.c)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Call mutate mutate$5(mutate a$9) + [4] Call mutate mutate$5(mutate b$10) + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [5] Const mutate $14 = JSX + "] + bb1_instrs --> bb1_terminal(["Return read $14"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md index 24b5b67c22..cd1651e27e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/independent.expect.md @@ -34,6 +34,25 @@ bb0: Return read $10 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$8 = Call mutate compute$3(read props$7.a) + [2] Const mutate b$9 = Call mutate compute$3(read props$7.b) + [3] Const mutate $10 = JSX + "] + bb0_instrs --> bb0_terminal(["Return read $10"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -51,6 +70,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -66,6 +99,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -81,6 +128,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md index a086d557c1..df1683b172 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/interdependent-across-if.expect.md @@ -34,6 +34,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -49,6 +63,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -64,6 +92,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -89,6 +131,42 @@ bb1: Return read $14 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$9[1:3] = Call mutate compute$3(read props$8.a) + [2] Const mutate b$10[2:3] = Call mutate compute$3(read props$8.b) + "] + bb0_instrs --> bb0_terminal(["If (read props$8.c)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Call mutate foo$5(mutate a$9, mutate b$10) + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [4] Const mutate $14 = JSX + "] + bb1_instrs --> bb1_terminal(["Return read $14"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md b/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md index 45febb30c1..b2b257b2e3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/interdependent.expect.md @@ -35,6 +35,26 @@ bb0: Return read $11 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$9[1:3] = Call mutate compute$3(read props$8.a) + [2] Const mutate b$10[2:3] = Call mutate compute$3(read props$8.b) + [3] Call mutate foo$5(mutate a$9, mutate b$10) + [4] Const mutate $11 = JSX + "] + bb0_instrs --> bb0_terminal(["Return read $11"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -53,6 +73,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -68,6 +102,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -83,6 +131,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md index 4687eea376..8bbbcd46a4 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/jsx-fragment.expect.md @@ -33,6 +33,33 @@ bb0: Return read $24 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate $14 = '\n Hello ' + [2] Const mutate $15 = ' ' + [3] Const mutate $16 = '\n ' + [4] Const mutate $17 = 'div' + [5] Const mutate $18 = '\n ' + [6] Const mutate $19 = 'Text' + [7] Const mutate $20 = JsxFragment [read $19] + [8] Const mutate $21 = '\n ' + [9] Const mutate $22 = JSX {read $18}{read $20}{read $21} + [10] Const mutate $23 = '\n ' + [11] Const mutate $24 = JsxFragment [read $14, read props$13.greeting, read $15, read $16, read $22, read $23] + "] + bb0_instrs --> bb0_terminal(["Return read $24"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md index 21669b28f6..21a8527baa 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/logical-expression.expect.md @@ -38,6 +38,48 @@ bb1: Return freeze $3 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate $5 = Call mutate f$1() + "] + bb0_instrs --> bb0_terminal(["If (read $5)"]) + end + + subgraph bb2 + bb2_instrs[" + [2] Const mutate $3 = Call mutate g$4() + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [3] Const mutate $3 = read $5 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Return freeze $3"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb3 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal --> bb1 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript @@ -68,6 +110,48 @@ bb1: Return freeze $3 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate $5 = Call mutate f$1() + "] + bb0_instrs --> bb0_terminal(["If (read $5)"]) + end + + subgraph bb2 + bb2_instrs[" + [2] Const mutate $3 = read $5 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [3] Const mutate $3 = Call mutate g$4() + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Return freeze $3"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb3 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal --> bb1 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript @@ -100,6 +184,50 @@ bb1: Return freeze $6 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate $9 = Call mutate f$2() + [2] Const mutate $10 = null + [3] Const mutate $11 = Binary read $9 != read $10 + "] + bb0_instrs --> bb0_terminal(["If (read $11)"]) + end + + subgraph bb2 + bb2_instrs[" + [4] Const mutate $6 = read $9 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [5] Const mutate $6 = Call mutate g$7() + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Return freeze $6"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb3 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal --> bb1 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript @@ -118,6 +246,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -133,6 +275,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md index 96657866dc..02475b7b45 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-loops.expect.md @@ -46,6 +46,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -61,6 +75,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -114,6 +142,97 @@ bb13: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate a$2 = Object { } + [2] Let mutate b$3 = Object { } + [3] Let mutate c$4 = Object { } + [4] Let mutate d$5 = Object { } + "] + bb0_instrs --> bb0_terminal(["While"]) + end + + subgraph bb1 + bb1_instrs[" + [5] Const mutate $17 = true + "] + bb1_instrs --> bb1_terminal(["If (read $17)"]) + end + + subgraph bb3 + bb3_instrs[" + [6] Let mutate z$19 = read a$2 + [7] Reassign mutate a$2 = read b$3 + [8] Reassign mutate b$3 = read c$4 + [9] Reassign mutate c$4 = read d$5 + [10] Reassign mutate d$5 = read z$19 + [11] Call mutate mutate$7(mutate a$2, mutate b$3) + [12] Const mutate $29 = Call mutate cond$8(mutate a$2) + "] + bb3_instrs --> bb3_terminal(["If (read $29)"]) + end + + subgraph bb4 + bb4_terminal(["Goto"]) + end + + subgraph bb2 + bb2_terminal(["If (read a$2)"]) + end + + subgraph bb7 + bb7_terminal(["If (read b$3)"]) + end + + subgraph bb9 + bb9_terminal(["If (read c$4)"]) + end + + subgraph bb11 + bb11_terminal(["If (read d$5)"]) + end + + subgraph bb13 + bb13_instrs[" + [13] Const mutate $34 = null + [14] Call mutate mutate$7(mutate d$5, read $34) + "] + bb13_instrs --> bb13_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- test --> bb1 + bb0_terminal -- loop --> bb3 + bb0_terminal -- fallthrough --> bb2 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb2 + + bb3_terminal -- then --> bb2 + bb3_terminal -- else --> bb4 + + bb4_terminal --> bb1 + + bb2_terminal -- then --> bb7 + bb2_terminal -- else --> bb7 + + bb7_terminal -- then --> bb9 + bb7_terminal -- else --> bb9 + + bb9_terminal -- then --> bb11 + bb9_terminal -- else --> bb11 + + bb11_terminal -- then --> bb13 + bb11_terminal -- else --> bb13 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md index 31977b9255..c924925a86 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-lifetime-with-aliasing.expect.md @@ -42,6 +42,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -81,6 +95,67 @@ bb9: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$11 = Object { } + [2] Const mutate b$12 = Array [read a$11] + [3] Const mutate c$13 = Object { } + [4] Const mutate d$14[4:7] = Object { c: read c$13 } + [5] Const mutate x$15[5:9] = Object { } + [6] Reassign mutate x$15.b[5:9] = read b$12 + [7] Const mutate y$16 = Call mutate mutate$8(mutate x$15, mutate d$14) + "] + bb0_instrs --> bb0_terminal(["If (read a$11)"]) + end + + subgraph bb1 + bb1_terminal(["If (read b$12)"]) + end + + subgraph bb3 + bb3_terminal(["If (read c$13)"]) + end + + subgraph bb5 + bb5_terminal(["If (read d$14)"]) + end + + subgraph bb7 + bb7_terminal(["If (read y$16)"]) + end + + subgraph bb9 + bb9_instrs[" + [8] Const mutate $17 = null + [9] Call mutate mutate$8(mutate x$15, read $17) + "] + bb9_instrs --> bb9_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb1 + bb0_terminal -- else --> bb1 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb3 + + bb3_terminal -- then --> bb5 + bb3_terminal -- else --> bb5 + + bb5_terminal -- then --> bb7 + bb5_terminal -- else --> bb7 + + bb7_terminal -- then --> bb9 + bb7_terminal -- else --> bb9 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md b/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md index fc84e7f48a..2f85b7b335 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/mutable-liverange-loop.expect.md @@ -41,6 +41,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -56,6 +70,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -104,6 +132,92 @@ bb13: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate a$12[1:7] = Object { } + [2] Let mutate b$13[2:6] = Object { } + [3] Let mutate c$14 = Object { } + [4] Let mutate d$15[4:9] = Object { } + "] + bb0_instrs --> bb0_terminal(["While"]) + end + + subgraph bb1 + bb1_instrs[" + [5] Const mutate $16 = true + "] + bb1_instrs --> bb1_terminal(["If (read $16)"]) + end + + subgraph bb3 + bb3_instrs[" + [6] Call mutate mutate$6(mutate a$12, mutate b$13) + [7] Const mutate $21 = Call mutate cond$7(mutate a$12) + "] + bb3_instrs --> bb3_terminal(["If (read $21)"]) + end + + subgraph bb4 + bb4_terminal(["Goto"]) + end + + subgraph bb2 + bb2_terminal(["If (read a$12)"]) + end + + subgraph bb7 + bb7_terminal(["If (read b$13)"]) + end + + subgraph bb9 + bb9_terminal(["If (read c$14)"]) + end + + subgraph bb11 + bb11_terminal(["If (read d$15)"]) + end + + subgraph bb13 + bb13_instrs[" + [8] Const mutate $28 = null + [9] Call mutate mutate$6(mutate d$15, read $28) + "] + bb13_instrs --> bb13_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- test --> bb1 + bb0_terminal -- loop --> bb3 + bb0_terminal -- fallthrough --> bb2 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb2 + + bb3_terminal -- then --> bb2 + bb3_terminal -- else --> bb4 + + bb4_terminal --> bb1 + + bb2_terminal -- then --> bb7 + bb2_terminal -- else --> bb7 + + bb7_terminal -- then --> bb9 + bb7_terminal -- else --> bb9 + + bb9_terminal -- then --> bb11 + bb9_terminal -- else --> bb11 + + bb11_terminal -- then --> bb13 + bb11_terminal -- else --> bb13 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md index de900df71c..8b81048b0b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/property-assignment.expect.md @@ -26,6 +26,28 @@ bb0: Return read $10 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate x$7[1:5] = Object { } + [2] Const mutate y$8 = Array [] + [3] Reassign mutate x$7.y[1:5] = read y$8 + [4] Const mutate child$9 = JSX + [5] Call mutate x$7.y.push(read props$6.p0) + [6] Const mutate $10 = JSX {read child$9} + "] + bb0_instrs --> bb0_terminal(["Return read $10"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md index 7ae0a7c8ab..c63eec5122 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment-conditional.expect.md @@ -39,6 +39,45 @@ bb1: Return read $15 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$2 = Array [] + [2] Call mutate x$2.push(read props$6.p0) + [3] Let mutate y$8 = read x$2 + "] + bb0_instrs --> bb0_terminal(["If (read props$6.p1)"]) + end + + subgraph bb2 + bb2_instrs[" + [4] Reassign mutate x$2 = Array [] + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [5] Let mutate _$12 = JSX + [6] Call read y$8.push(read props$6.p2) + [7] Const mutate $15 = JSX + "] + bb1_instrs --> bb1_terminal(["Return read $15"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md index e51b468c63..bbe2d9275f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reassignment.expect.md @@ -31,6 +31,29 @@ bb0: Return read $11 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$7[1:2] = Array [] + [2] Call mutate x$7.push(read props$6.p0) + [3] Let mutate y$8[3:6] = read x$7 + [4] Reassign mutate x$9 = Array [] + [5] Let mutate _$10 = JSX + [6] Call mutate y$8.push(read props$6.p1) + [7] Const mutate $11 = JSX + "] + bb0_instrs --> bb0_terminal(["Return read $11"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md b/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md index 79b996bb94..994e46d294 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/reverse-postorder.expect.md @@ -77,6 +77,101 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$7 = undefined + "] + bb0_instrs --> bb0_terminal(["If (read props$6.cond)"]) + end + + subgraph bb2 + bb2_instrs[" + [2] Const mutate $8 = 2 + [3] Const mutate $9 = 1 + [4] Const mutate $10 = 0 + "] + bb2_instrs --> bb2_terminal(["Switch (read props$6.test)"]) + end + + subgraph bb8 + bb8_instrs[" + [5] Reassign mutate x$2 = read props$6.v0 + "] + bb8_instrs --> bb8_terminal(["Goto"]) + end + + subgraph bb6 + bb6_instrs[" + [6] Reassign mutate x$2 = read props$6.v1 + "] + bb6_instrs --> bb6_terminal(["Goto"]) + end + + subgraph bb4 + bb4_instrs[" + [7] Reassign mutate x$2 = read props$6.v2 + "] + bb4_instrs --> bb4_terminal(["Goto"]) + end + + subgraph bb10 + bb10_terminal(["If (read props$6.cond2)"]) + end + + subgraph bb12 + bb12_instrs[" + [8] Reassign mutate x$2 = read props$6.b + "] + bb12_instrs --> bb12_terminal(["Goto"]) + end + + subgraph bb13 + bb13_instrs[" + [9] Reassign mutate x$2 = read props$6.c + "] + bb13_instrs --> bb13_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [10] read x$2 + "] + bb1_instrs --> bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb10 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal -- read $10 --> bb8 + bb2_terminal -- read $9 --> bb6 + bb2_terminal -- read $8 --> bb4 + bb2_terminal -- default --> bb4 + bb2_terminal -- fallthrough --> bb1 + + bb8_terminal --> bb1 + + bb6_terminal --> bb1 + + bb4_terminal --> bb1 + + bb10_terminal -- then --> bb12 + bb10_terminal -- else --> bb13 + bb10_terminal -- fallthrough --> bb1 + + bb12_terminal --> bb1 + + bb13_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md b/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md index 411bee861f..2675470747 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/simple.expect.md @@ -29,6 +29,39 @@ bb1: Return freeze $14 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["If (read x$8)"]) + end + + subgraph bb2 + bb2_instrs[" + [1] Const mutate $10 = false + [2] Const mutate $11 = Call read foo$0(read $10, read y$9) + "] + bb2_instrs --> bb2_terminal(["Return freeze $11"]) + end + + subgraph bb1 + bb1_instrs[" + [3] Const mutate $12 = 10 + [4] Const mutate $13 = Binary read y$9 * read $12 + [5] Const mutate $14 = Array [read $13] + "] + bb1_instrs --> bb1_terminal(["Return freeze $14"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md index 19b29ff95c..2be25f38a5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-arrayexpression.expect.md @@ -21,6 +21,25 @@ bb0: Return freeze x$8 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$6 = 1 + [2] Const mutate b$7 = 2 + [3] Const mutate x$8 = Array [read a$6, read b$7] + "] + bb0_instrs --> bb0_terminal(["Return freeze x$8"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md index 7e9396dad2..b3dcd192ae 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx-2.expect.md @@ -25,6 +25,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -55,6 +69,47 @@ bb1: Return read $20 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$11[1:3] = Array [] + [2] Const mutate b$12[2:7] = Object { } + [3] Call mutate foo$4(mutate a$11, mutate b$12) + [4] Const mutate $13 = Call mutate foo$4() + "] + bb0_instrs --> bb0_terminal(["If (read $13)"]) + end + + subgraph bb2 + bb2_instrs[" + [5] Const mutate $14 = 'div' + [6] Let mutate _$15 = JSX + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [7] Call mutate foo$4(read a$11, mutate b$12) + [8] Const mutate $19 = 'div' + [9] Const mutate $20 = JSX + "] + bb1_instrs --> bb1_terminal(["Return read $20"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md index 97d41cf519..32fb32bab9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-call-jsx.expect.md @@ -22,6 +22,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -45,6 +59,30 @@ bb0: Return read $15 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$10[1:3] = Array [] + [2] Const mutate b$11[2:6] = Object { } + [3] Call mutate foo$4(mutate a$10, mutate b$11) + [4] Const mutate $12 = 'div' + [5] Let mutate _$13 = JSX + [6] Call mutate foo$4(read a$10, mutate b$11) + [7] Const mutate $14 = 'div' + [8] Const mutate $15 = JSX + "] + bb0_instrs --> bb0_terminal(["Return read $15"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md index a57cbf2203..105ec822f3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-multiple-if.expect.md @@ -45,6 +45,64 @@ bb3: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$1 = 1 + [2] Let mutate y$8 = 2 + [3] Const mutate $9 = 2 + [4] Const mutate $10 = Binary read y$8 === read $9 + "] + bb0_instrs --> bb0_terminal(["If (read $10)"]) + end + + subgraph bb2 + bb2_instrs[" + [5] Reassign mutate x$1 = 3 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [6] Const mutate $12 = 3 + [7] Const mutate $14 = Binary read y$8 === read $12 + "] + bb1_instrs --> bb1_terminal(["If (read $14)"]) + end + + subgraph bb4 + bb4_instrs[" + [8] Reassign mutate x$1 = 5 + "] + bb4_instrs --> bb4_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [9] Reassign mutate y$18 = read x$1 + "] + bb3_instrs --> bb3_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + + bb1_terminal -- then --> bb4 + bb1_terminal -- else --> bb3 + + bb4_terminal --> bb3 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md index 79dedcc9c2..d4ade013e5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-complex-single-if.expect.md @@ -33,6 +33,44 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$1 = 1 + [2] Let mutate y$6 = 2 + [3] Const mutate $7 = 2 + [4] Const mutate $8 = Binary read y$6 === read $7 + "] + bb0_instrs --> bb0_terminal(["If (read $8)"]) + end + + subgraph bb2 + bb2_instrs[" + [5] Reassign mutate x$1 = 3 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [6] Reassign mutate y$11 = read x$1 + "] + bb1_instrs --> bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md index 85be3d0c9c..0f9d5ae07d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-for-of.expect.md @@ -40,6 +40,60 @@ bb2: Return freeze items$5 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate items$5 = Array [] + "] + bb0_instrs --> bb0_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["If (read items$5)"]) + end + + subgraph bb3 + bb3_instrs[" + [2] Let mutate y$7 = 0 + "] + bb3_instrs --> bb3_terminal(["If (read cond$4)"]) + end + + subgraph bb5 + bb5_instrs[" + [3] Reassign mutate y$9 = 1 + "] + bb5_instrs --> bb5_terminal(["Goto"]) + end + + subgraph bb4 + bb4_terminal(["Goto"]) + end + + subgraph bb2 + bb2_terminal(["Return freeze items$5"]) + end + + + %% Jumps + bb0_terminal --> bb1 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb2 + + bb3_terminal -- then --> bb5 + bb3_terminal -- else --> bb4 + + bb5_terminal --> bb4 + + bb4_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md index 72eb72ff41..fe96c43275 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-for.expect.md @@ -33,6 +33,49 @@ bb2: Return read x$1 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$1 = 0 + "] + bb0_instrs --> bb0_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [2] Const mutate $6 = 10 + [3] Const mutate $8 = Binary read x$1 < read $6 + "] + bb1_instrs --> bb1_terminal(["If (read $8)"]) + end + + subgraph bb4 + bb4_instrs[" + [4] Const mutate $9 = 1 + [5] Reassign mutate x$1 = Binary read x$1 + read $9 + "] + bb4_instrs --> bb4_terminal(["Goto"]) + end + + subgraph bb2 + bb2_terminal(["Return read x$1"]) + end + + + %% Jumps + bb0_terminal --> bb1 + + bb1_terminal -- then --> bb4 + bb1_terminal -- else --> bb2 + + bb4_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-if-else.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-if-else.expect.md index c7d44a43b5..2eae141d9f 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-if-else.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-if-else.expect.md @@ -35,6 +35,49 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$5 = 1 + [2] Let mutate y$6 = 2 + "] + bb0_instrs --> bb0_terminal(["If (read y$6)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Let mutate z$7 = Binary read x$5 + read y$6 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [4] Let mutate z$8 = read x$5 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb3 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal --> bb1 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-loops-no-reassign.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-loops-no-reassign.expect.md index 194283bab1..2caa9497ce 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-loops-no-reassign.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-nested-loops-no-reassign.expect.md @@ -54,6 +54,89 @@ bb2: Return read x$9 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$9 = 0 + "] + bb0_instrs --> bb0_terminal(["While"]) + end + + subgraph bb1 + bb1_terminal(["If (read a$6)"]) + end + + subgraph bb3 + bb3_terminal(["While"]) + end + + subgraph bb4 + bb4_terminal(["If (read b$7)"]) + end + + subgraph bb6 + bb6_terminal(["While"]) + end + + subgraph bb7 + bb7_terminal(["If (read c$8)"]) + end + + subgraph bb9 + bb9_instrs[" + [2] Const mutate $13 = 1 + [3] Binary read x$9 + read $13 + "] + bb9_instrs --> bb9_terminal(["Goto"]) + end + + subgraph bb8 + bb8_terminal(["Goto"]) + end + + subgraph bb5 + bb5_terminal(["Goto"]) + end + + subgraph bb2 + bb2_terminal(["Return read x$9"]) + end + + + %% Jumps + bb0_terminal -- test --> bb1 + bb0_terminal -- loop --> bb3 + bb0_terminal -- fallthrough --> bb2 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb2 + + bb3_terminal -- test --> bb4 + bb3_terminal -- loop --> bb6 + bb3_terminal -- fallthrough --> bb5 + + bb4_terminal -- then --> bb6 + bb4_terminal -- else --> bb5 + + bb6_terminal -- test --> bb7 + bb6_terminal -- loop --> bb9 + bb6_terminal -- fallthrough --> bb8 + + bb7_terminal -- then --> bb9 + bb7_terminal -- else --> bb8 + + bb9_terminal --> bb7 + + bb8_terminal --> bb4 + + bb5_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md index 6396717787..ff5b40d288 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-newexpression.expect.md @@ -20,6 +20,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -38,6 +52,25 @@ bb0: Return freeze c$9 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$7[1:3] = Array [] + [2] Const mutate b$8[2:3] = Object { } + [3] Let mutate c$9 = New mutate Foo$5(mutate a$7, mutate b$8) + "] + bb0_instrs --> bb0_terminal(["Return freeze c$9"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md index 05faad4bfc..2d4996bb6e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression-phi.expect.md @@ -41,6 +41,54 @@ bb1: Return freeze t$14 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$1 = 1 + [2] Let mutate y$2 = 2 + [3] Const mutate $8 = 1 + [4] Const mutate $9 = Binary read x$1 > read $8 + "] + bb0_instrs --> bb0_terminal(["If (read $9)"]) + end + + subgraph bb2 + bb2_instrs[" + [5] Reassign mutate x$1 = 2 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [6] Reassign mutate y$2 = 3 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [7] Let mutate t$14 = Object { x: read x$1, y: read y$2 } + "] + bb1_instrs --> bb1_terminal(["Return freeze t$14"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb3 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal --> bb1 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md index 6d30e24098..612af99973 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-objectexpression.expect.md @@ -21,6 +21,25 @@ bb0: Return freeze x$8 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate a$6 = 1 + [2] Const mutate b$7 = 2 + [3] Const mutate x$8 = Object { a: read a$6, b: read b$7 } + "] + bb0_instrs --> bb0_terminal(["Return freeze x$8"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md index 6bb23e8e1e..bd485766a8 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property-call.expect.md @@ -22,6 +22,26 @@ bb0: Return freeze y$5 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate x$4 = Array [] + [2] Const mutate y$5[2:4] = Object { x: read x$4 } + [3] Const mutate $6[3:4] = Array [] + [4] Call mutate y$5.x.push(mutate $6) + "] + bb0_instrs --> bb0_terminal(["Return freeze y$5"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md index bf0031ed4c..505b8b3186 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-property.expect.md @@ -21,6 +21,25 @@ bb0: Return freeze y$4 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Const mutate x$3 = Array [] + [2] Const mutate y$4[2:3] = Object { } + [3] Reassign mutate y$4.x[2:3] = read x$3 + "] + bb0_instrs --> bb0_terminal(["Return freeze y$4"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md index 09cc1158a0..2b17eee52a 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-return.expect.md @@ -30,6 +30,40 @@ bb1: Return read x$1 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$1 = 1 + [2] Const mutate $5 = 1 + [3] Const mutate $6 = Binary read x$1 === read $5 + "] + bb0_instrs --> bb0_terminal(["If (read $6)"]) + end + + subgraph bb2 + bb2_instrs[" + [4] Reassign mutate x$1 = 2 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Return read x$1"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md index f210b0f70b..2e4ee343d9 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-shadowing.expect.md @@ -24,6 +24,20 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript @@ -53,6 +67,52 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate str$2 = '' + "] + bb0_instrs --> bb0_terminal(["If (read cond$5)"]) + end + + subgraph bb2 + bb2_instrs[" + [2] Let mutate str$7 = 'other test' + [3] Call mutate log$4(read str$7) + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [4] Reassign mutate str$2 = 'fallthrough test' + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [5] Call mutate log$4(read str$2) + "] + bb1_instrs --> bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb3 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal --> bb1 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md index a4e9a1d1b8..5ab6e1e0d3 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-simple-phi.expect.md @@ -38,6 +38,53 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate y$5 = 2 + [2] Const mutate $6 = 1 + [3] Const mutate $7 = Binary read y$5 > read $6 + "] + bb0_instrs --> bb0_terminal(["If (read $7)"]) + end + + subgraph bb2 + bb2_instrs[" + [4] Reassign mutate y$1 = 1 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [5] Reassign mutate y$1 = 2 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [6] Let mutate x$11 = read y$1 + "] + bb1_instrs --> bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb3 + bb0_terminal -- fallthrough --> bb1 + + bb2_terminal --> bb1 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-simple.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-simple.expect.md index b99f9e9874..800c8e6bf5 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-simple.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-simple.expect.md @@ -18,6 +18,24 @@ bb0: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$3 = 1 + [2] Let mutate y$4 = 2 + "] + bb0_instrs --> bb0_terminal(["Return"]) + end + + + %% Jumps + %% empty +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-single-if.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-single-if.expect.md index 3b12fe25ed..38da735009 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-single-if.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-single-if.expect.md @@ -29,6 +29,39 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$4 = 1 + [2] Let mutate y$5 = 2 + "] + bb0_instrs --> bb0_terminal(["If (read y$5)"]) + end + + subgraph bb2 + bb2_instrs[" + [3] Let mutate z$6 = Binary read x$4 + read y$5 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md index 34e0f1cf89..c0caf481ec 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-switch.expect.md @@ -58,6 +58,68 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$10 = 1 + [2] Const mutate $11 = 2 + [3] Const mutate $12 = Binary read x$10 === read $11 + [4] Const mutate $13 = 1 + [5] Const mutate $14 = Binary read x$10 === read $13 + "] + bb0_instrs --> bb0_terminal(["Switch (read x$10)"]) + end + + subgraph bb5 + bb5_instrs[" + [6] Const mutate $15 = 1 + [7] Reassign mutate x$1 = Binary read x$10 + read $15 + "] + bb5_instrs --> bb5_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [8] Const mutate $17 = 2 + [9] Reassign mutate x$1 = Binary read x$10 + read $17 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb2 + bb2_instrs[" + [10] Const mutate $19 = 3 + [11] Reassign mutate x$1 = Binary read x$10 + read $19 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [12] Let mutate y$22 = read x$1 + "] + bb1_instrs --> bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- read $14 --> bb5 + bb0_terminal -- read $12 --> bb3 + bb0_terminal -- default --> bb2 + bb0_terminal -- fallthrough --> bb1 + + bb5_terminal --> bb1 + + bb3_terminal --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md index 82958321a0..f14988f164 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-throw.expect.md @@ -29,6 +29,40 @@ bb1: Throw read x$1 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$1 = 1 + [2] Const mutate $5 = 1 + [3] Const mutate $6 = Binary read x$1 === read $5 + "] + bb0_instrs --> bb0_terminal(["If (read $6)"]) + end + + subgraph bb2 + bb2_instrs[" + [4] Reassign mutate x$1 = 2 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Throw read x$1"]) + end + + + %% Jumps + bb0_terminal -- then --> bb2 + bb0_terminal -- else --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-while-no-reassign.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-while-no-reassign.expect.md index 1598c99c65..30fa94128b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-while-no-reassign.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-while-no-reassign.expect.md @@ -34,6 +34,51 @@ bb2: Return read x$5 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$5 = 1 + "] + bb0_instrs --> bb0_terminal(["While"]) + end + + subgraph bb1 + bb1_instrs[" + [2] Const mutate $6 = 10 + [3] Const mutate $8 = Binary read x$5 < read $6 + "] + bb1_instrs --> bb1_terminal(["If (read $8)"]) + end + + subgraph bb3 + bb3_instrs[" + [4] Const mutate $9 = 1 + [5] Binary read x$5 + read $9 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb2 + bb2_terminal(["Return read x$5"]) + end + + + %% Jumps + bb0_terminal -- test --> bb1 + bb0_terminal -- loop --> bb3 + bb0_terminal -- fallthrough --> bb2 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb2 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md b/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md index 94bf0c7737..6f4024db87 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/ssa-while.expect.md @@ -34,6 +34,51 @@ bb2: Return read x$1 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$1 = 1 + "] + bb0_instrs --> bb0_terminal(["While"]) + end + + subgraph bb1 + bb1_instrs[" + [2] Const mutate $6 = 10 + [3] Const mutate $8 = Binary read x$1 < read $6 + "] + bb1_instrs --> bb1_terminal(["If (read $8)"]) + end + + subgraph bb3 + bb3_instrs[" + [4] Const mutate $9 = 1 + [5] Reassign mutate x$1 = Binary read x$1 + read $9 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb2 + bb2_terminal(["Return read x$1"]) + end + + + %% Jumps + bb0_terminal -- test --> bb1 + bb0_terminal -- loop --> bb3 + bb0_terminal -- fallthrough --> bb2 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb2 + + bb3_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md index ab7d946d2d..225ca677b6 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch-non-final-default.expect.md @@ -59,6 +59,60 @@ bb1: Return read $22 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$10[1:6] = Array [] + [2] Let mutate y$3 = undefined + [3] Const mutate $12 = false + [4] Const mutate $13 = true + [5] Const mutate $14 = 1 + "] + bb0_instrs --> bb0_terminal(["Switch (read props$9.p0)"]) + end + + subgraph bb6 + bb6_instrs[" + [6] Call mutate x$10.push(read props$9.p2) + [7] Reassign mutate y$3 = Array [] + "] + bb6_instrs --> bb6_terminal(["Goto"]) + end + + subgraph bb2 + bb2_instrs[" + [8] Reassign mutate y$3 = read x$10 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [9] Const mutate child$19 = JSX + [10] Call read y$3.push(read props$9.p4) + [11] Const mutate $22 = JSX {read child$19} + "] + bb1_instrs --> bb1_terminal(["Return read $22"]) + end + + + %% Jumps + bb0_terminal -- read $14 --> bb1 + bb0_terminal -- read $13 --> bb6 + bb0_terminal -- default --> bb1 + bb0_terminal -- read $12 --> bb2 + bb0_terminal -- fallthrough --> bb1 + + bb6_terminal --> bb1 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch-with-fallthrough.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch-with-fallthrough.expect.md index 25b4c66acc..4a65868526 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch-with-fallthrough.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch-with-fallthrough.expect.md @@ -80,6 +80,95 @@ bb1: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate y$10 = undefined + [2] Const mutate $11 = 5 + [3] Const mutate $12 = 4 + [4] Const mutate $13 = 3 + [5] Const mutate $14 = 2 + [6] Const mutate $15 = 1 + [7] Const mutate $16 = 0 + "] + bb0_instrs --> bb0_terminal(["Switch (read x$9)"]) + end + + subgraph bb10 + bb10_instrs[" + [8] Reassign mutate y$17 = 0 + "] + bb10_instrs --> bb10_terminal(["Goto"]) + end + + subgraph bb9 + bb9_instrs[" + [9] Reassign mutate y$18 = 1 + "] + bb9_instrs --> bb9_terminal(["Goto"]) + end + + subgraph bb5 + bb5_instrs[" + [10] Reassign mutate y$19 = 3 + "] + bb5_instrs --> bb5_terminal(["Goto"]) + end + + subgraph bb4 + bb4_instrs[" + [11] Reassign mutate y$20 = 4 + "] + bb4_instrs --> bb4_terminal(["Goto"]) + end + + subgraph bb3 + bb3_instrs[" + [12] Reassign mutate y$21 = 5 + "] + bb3_instrs --> bb3_terminal(["Goto"]) + end + + subgraph bb2 + bb2_instrs[" + [13] Reassign mutate y$22 = 0 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- read $16 --> bb10 + bb0_terminal -- read $15 --> bb9 + bb0_terminal -- read $14 --> bb1 + bb0_terminal -- read $13 --> bb5 + bb0_terminal -- read $12 --> bb4 + bb0_terminal -- read $11 --> bb3 + bb0_terminal -- default --> bb2 + bb0_terminal -- fallthrough --> bb1 + + bb10_terminal --> bb9 + + bb9_terminal --> bb1 + + bb5_terminal --> bb1 + + bb4_terminal --> bb3 + + bb3_terminal --> bb2 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md index 7ff960925a..3dca25095e 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/switch.expect.md @@ -54,6 +54,59 @@ bb1: Return read $23 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_instrs[" + [1] Let mutate x$9[1:6] = Array [] + [2] Let mutate y$3 = undefined + [3] Const mutate $11 = false + [4] Const mutate $12 = true + "] + bb0_instrs --> bb0_terminal(["Switch (read props$8.p0)"]) + end + + subgraph bb4 + bb4_instrs[" + [5] Call mutate x$9.push(read props$8.p2) + [6] Call mutate x$9.push(read props$8.p3) + [7] Reassign mutate y$13 = Array [] + "] + bb4_instrs --> bb4_terminal(["Goto"]) + end + + subgraph bb2 + bb2_instrs[" + [8] Reassign mutate y$3 = read x$9 + "] + bb2_instrs --> bb2_terminal(["Goto"]) + end + + subgraph bb1 + bb1_instrs[" + [9] Const mutate child$19 = JSX + [10] Call read y$3.push(read props$8.p4) + [11] Const mutate $23 = JSX {read child$19} + "] + bb1_instrs --> bb1_terminal(["Return read $23"]) + end + + + %% Jumps + bb0_terminal -- read $12 --> bb4 + bb0_terminal -- read $11 --> bb2 + bb0_terminal -- default --> bb1 + bb0_terminal -- fallthrough --> bb1 + + bb4_terminal --> bb2 + + bb2_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/while-break.expect.md b/compiler/forget/src/__tests__/fixtures/hir/while-break.expect.md index d7fd0cc031..eb7abed67b 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/while-break.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/while-break.expect.md @@ -24,6 +24,34 @@ bb2: Return read b$4 ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["While"]) + end + + subgraph bb1 + bb1_terminal(["If (read a$3)"]) + end + + subgraph bb2 + bb2_terminal(["Return read b$4"]) + end + + + %% Jumps + bb0_terminal -- test --> bb1 + bb0_terminal -- loop --> bb2 + bb0_terminal -- fallthrough --> bb2 + + bb1_terminal -- then --> bb2 + bb1_terminal -- else --> bb2 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/fixtures/hir/while-conditional-continue.expect.md b/compiler/forget/src/__tests__/fixtures/hir/while-conditional-continue.expect.md index e0e2d90577..c5a552225d 100644 --- a/compiler/forget/src/__tests__/fixtures/hir/while-conditional-continue.expect.md +++ b/compiler/forget/src/__tests__/fixtures/hir/while-conditional-continue.expect.md @@ -39,6 +39,59 @@ bb2: Return ``` +### CFG + +```mermaid +flowchart TB + %% Basic Blocks + subgraph bb0 + bb0_terminal(["While"]) + end + + subgraph bb1 + bb1_terminal(["If (read a$5)"]) + end + + subgraph bb3 + bb3_terminal(["If (read b$6)"]) + end + + subgraph bb5 + bb5_terminal(["Goto"]) + end + + subgraph bb4 + bb4_instrs[" + [1] Call read c$7() + "] + bb4_instrs --> bb4_terminal(["Goto"]) + end + + subgraph bb2 + bb2_instrs[" + [2] Call read d$8() + "] + bb2_instrs --> bb2_terminal(["Return"]) + end + + + %% Jumps + bb0_terminal -- test --> bb1 + bb0_terminal -- loop --> bb3 + bb0_terminal -- fallthrough --> bb2 + + bb1_terminal -- then --> bb3 + bb1_terminal -- else --> bb2 + + bb3_terminal -- then --> bb5 + bb3_terminal -- else --> bb4 + + bb5_terminal --> bb1 + + bb4_terminal --> bb1 + +``` + ## Code ```javascript diff --git a/compiler/forget/src/__tests__/hir-test.ts b/compiler/forget/src/__tests__/hir-test.ts index 2b7a03b65f..ddeb359c35 100644 --- a/compiler/forget/src/__tests__/hir-test.ts +++ b/compiler/forget/src/__tests__/hir-test.ts @@ -24,6 +24,7 @@ import { inferMutableRanges } from "../HIR/InferMutableLifetimes"; import inferReferenceEffects from "../HIR/InferReferenceEffects"; import leaveSSA from "../HIR/LeaveSSA"; import printHIR from "../HIR/PrintHIR"; +import visualizeHIRMermaid from "../HIR/VisualizeHIRMermaid"; import generateTestsFromFixtures from "./test-utils/generateTestsFromFixtures"; function wrapWithTripleBackticks(s: string, ext?: string) { @@ -59,7 +60,7 @@ describe("React Forget (HIR version)", () => { sourceFilename: file, plugins: ["typescript", "jsx"], }); - let items: Array<[string, string]> = []; + let items: Array<[string, string, string]> = []; traverse(ast, { FunctionDeclaration: { enter(nodePath) { @@ -71,6 +72,7 @@ describe("React Forget (HIR version)", () => { inferMutableRanges(ir); leaveSSA(ir); const textHIR = printHIR(ir.body); + const visualization = visualizeHIRMermaid(ir); const ast = codegen(ir); const text = prettier.format( @@ -80,7 +82,7 @@ describe("React Forget (HIR version)", () => { parser: "babel-ts", } ); - items.push([textHIR, text]); + items.push([textHIR, text, visualization]); }, }, }); @@ -88,12 +90,16 @@ describe("React Forget (HIR version)", () => { items.length > 0, "Visitor failed, check that the input has a function" ); - const outputs = items.map(([hir, text]) => { + const outputs = items.map(([hir, text, visualization]) => { return ` ## HIR ${wrapWithTripleBackticks(hir)} +### CFG + +${wrapWithTripleBackticks(visualization, "mermaid")} + ## Code ${wrapWithTripleBackticks(text, "javascript")}