[HIR] Naive implementation of pruneUnusedLabels in HIR
ghstack-source-id: 6d55db3d5c0fd7736a59d48c6afb2de9b5729d16 Pull Request resolved: https://github.com/facebook/react-forget/pull/2866
Mofei Zhang committed
Apr 23, 2024 at 10:18 UTC
40474b8eaff43bfa6b8b0d84181a0f37a9970e3c
3 files changed
+77
compiler/packages/babel-plugin-react-forget/src/Entrypoint/Pipeline.ts
+8
@@ -17,6 +17,7 @@ import {
17
assertValidMutableRanges,
18
lower,
19
mergeConsecutiveBlocks,
20
+ pruneUnusedLabelsHIR,
21
} from "../HIR";
22
import {
23
Environment,
@@ -236,6 +237,13 @@ function* runWithEnvironment(
237
});
238
239
if (env.config.enableAlignReactiveScopesToBlockScopesHIR) {
240
+ pruneUnusedLabelsHIR(hir);
241
+ yield log({
242
+ kind: "hir",
243
+ name: "PruneUnusedLabelsHIR",
244
+ value: hir,
245
+ });
246
+
247
alignReactiveScopesToBlockScopesHIR(hir);
248
yield log({
249
kind: "hir",
compiler/packages/babel-plugin-react-forget/src/HIR/PruneUnusedLabelsHIR.ts
new
+68
@@ -0,0 +1,68 @@
1
+import { CompilerError } from "..";
2
+import { BlockId, GotoVariant, HIRFunction } from "./HIR";
3
+
4
+export function pruneUnusedLabelsHIR(fn: HIRFunction): void {
5
+ const merged: Array<{
6
+ label: BlockId;
7
+ next: BlockId;
8
+ fallthrough: BlockId;
9
+ }> = [];
10
+
11
+ for (const [blockId, block] of fn.body.blocks) {
12
+ const terminal = block.terminal;
13
+ if (terminal.kind === "label") {
14
+ const { block: nextId, fallthrough: fallthroughId } = terminal;
15
+ const next = fn.body.blocks.get(nextId)!;
16
+ const fallthrough = fn.body.blocks.get(fallthroughId)!;
17
+ if (
18
+ next.terminal.kind === "goto" &&
19
+ next.terminal.variant === GotoVariant.Break &&
20
+ next.terminal.block === fallthroughId
21
+ ) {
22
+ if (next.kind === "block" && fallthrough.kind === "block") {
23
+ // Only merge normal block types
24
+ merged.push({
25
+ label: blockId,
26
+ next: nextId,
27
+ fallthrough: fallthroughId,
28
+ });
29
+ }
30
+ }
31
+ }
32
+ }
33
+
34
+ for (const {
35
+ label: labelId,
36
+ next: nextId,
37
+ fallthrough: fallthroughId,
38
+ } of merged) {
39
+ const label = fn.body.blocks.get(labelId)!;
40
+ const next = fn.body.blocks.get(nextId)!;
41
+ const fallthrough = fn.body.blocks.get(fallthroughId)!;
42
+
43
+ // Merge block and fallthrough
44
+ CompilerError.invariant(
45
+ next.phis.size === 0 && fallthrough.phis.size === 0,
46
+ {
47
+ reason: "Unexpected phis when merging label blocks",
48
+ loc: label.terminal.loc,
49
+ }
50
+ );
51
+
52
+ CompilerError.invariant(
53
+ next.preds.size === 1 &&
54
+ fallthrough.preds.size === 1 &&
55
+ next.preds.has(labelId) &&
56
+ fallthrough.preds.has(nextId),
57
+ {
58
+ reason: "Unexpected block predecessors when merging label blocks",
59
+ loc: label.terminal.loc,
60
+ }
61
+ );
62
+
63
+ label.instructions.push(...next.instructions, ...fallthrough.instructions);
64
+ label.terminal = fallthrough.terminal;
65
+ fn.body.blocks.delete(nextId);
66
+ fn.body.blocks.delete(fallthroughId);
67
+ }
68
+}
compiler/packages/babel-plugin-react-forget/src/HIR/index.ts
+1
@@ -27,3 +27,4 @@ export {
27
} from "./HIRBuilder";
28
export { mergeConsecutiveBlocks } from "./MergeConsecutiveBlocks";
29
export { printFunction, printHIR } from "./PrintHIR";
30
+export { pruneUnusedLabelsHIR } from "./PruneUnusedLabelsHIR";