From 3b3107fb3e335d39287589a37b68495d47862cf3 Mon Sep 17 00:00:00 2001 From: Lauren Tan Date: Thu, 10 Nov 2022 17:09:28 -0500 Subject: [PATCH] Add Mermaid visualizations for CFG into fixtures This PR adds a new section to fixture tests, which renders the HIR into a visualization using mermaid.js syntax which can then be embedded directly into markdown. The nice thing about the mermaid syntax is that it's quite readable, so if desired we could replace the current basic block textual output with the mermaid block. I'm opting to append it for now and wait for feedback if we want to keep both or replace. To view the graphs in your editor, download an extension that adds mermaid.js support: https://mermaid-js.github.io/mermaid/#/integrations?id=editor-plugins. In vscode you can use this plugin by right clicking on "Open Preview" on any expect.md file. No extra dependencies are required for GitHub which should have builtin support for mermaid in markdown --- .../forget/src/HIR/VisualizeHIRMermaid.ts | 180 ++++++++++++++++++ .../src/__tests__/fixtures/hir/call.expect.md | 38 ++++ .../fixtures/hir/complex-while.expect.md | 48 +++++ .../fixtures/hir/component.expect.md | 108 +++++++++++ .../fixtures/hir/conditional-break.expect.md | 175 +++++++++++++++++ .../hir/conditional-on-mutable.expect.md | 133 +++++++++++++ .../fixtures/hir/constructor.expect.md | 38 ++++ .../fixtures/hir/frozen-after-alias.expect.md | 48 +++++ .../fixtures/hir/hook-call.expect.md | 51 +++++ .../hir/hooks-freeze-arguments.expect.md | 48 +++++ ...reeze-possibly-mutable-arguments.expect.md | 77 ++++++++ .../hir/independent-across-if.expect.md | 93 +++++++++ .../fixtures/hir/independent.expect.md | 61 ++++++ .../hir/interdependent-across-if.expect.md | 78 ++++++++ .../fixtures/hir/interdependent.expect.md | 62 ++++++ .../fixtures/hir/jsx-fragment.expect.md | 27 +++ .../fixtures/hir/logical-expression.expect.md | 156 +++++++++++++++ .../hir/mutable-lifetime-loops.expect.md | 119 ++++++++++++ .../mutable-lifetime-with-aliasing.expect.md | 75 ++++++++ .../hir/mutable-liverange-loop.expect.md | 114 +++++++++++ .../hir/property-assignment.expect.md | 22 +++ .../hir/reassignment-conditional.expect.md | 39 ++++ .../fixtures/hir/reassignment.expect.md | 23 +++ .../fixtures/hir/reverse-postorder.expect.md | 95 +++++++++ .../__tests__/fixtures/hir/simple.expect.md | 33 ++++ .../hir/ssa-arrayexpression.expect.md | 19 ++ .../fixtures/hir/ssa-call-jsx-2.expect.md | 55 ++++++ .../fixtures/hir/ssa-call-jsx.expect.md | 38 ++++ .../hir/ssa-complex-multiple-if.expect.md | 58 ++++++ .../hir/ssa-complex-single-if.expect.md | 38 ++++ .../fixtures/hir/ssa-for-of.expect.md | 54 ++++++ .../__tests__/fixtures/hir/ssa-for.expect.md | 43 +++++ .../fixtures/hir/ssa-if-else.expect.md | 43 +++++ .../ssa-nested-loops-no-reassign.expect.md | 83 ++++++++ .../fixtures/hir/ssa-newexpression.expect.md | 33 ++++ .../hir/ssa-objectexpression-phi.expect.md | 48 +++++ .../hir/ssa-objectexpression.expect.md | 19 ++ .../fixtures/hir/ssa-property-call.expect.md | 20 ++ .../fixtures/hir/ssa-property.expect.md | 19 ++ .../fixtures/hir/ssa-return.expect.md | 34 ++++ .../fixtures/hir/ssa-shadowing.expect.md | 60 ++++++ .../fixtures/hir/ssa-simple-phi.expect.md | 47 +++++ .../fixtures/hir/ssa-simple.expect.md | 18 ++ .../fixtures/hir/ssa-single-if.expect.md | 33 ++++ .../fixtures/hir/ssa-switch.expect.md | 62 ++++++ .../fixtures/hir/ssa-throw.expect.md | 34 ++++ .../hir/ssa-while-no-reassign.expect.md | 45 +++++ .../fixtures/hir/ssa-while.expect.md | 45 +++++ .../hir/switch-non-final-default.expect.md | 54 ++++++ .../hir/switch-with-fallthrough.expect.md | 89 +++++++++ .../__tests__/fixtures/hir/switch.expect.md | 53 ++++++ .../fixtures/hir/while-break.expect.md | 28 +++ .../hir/while-conditional-continue.expect.md | 53 ++++++ compiler/forget/src/__tests__/hir-test.ts | 12 +- 54 files changed, 3175 insertions(+), 3 deletions(-) create mode 100644 compiler/forget/src/HIR/VisualizeHIRMermaid.ts 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")}