@samitouri / QOS-React / commits / 40474b8eaf

[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";