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")}