[compiler][hir] Correctly remove non-existent terminal preds when pruning labels
Missed this initially in `pruneUnusedLabelsHIR`. It wasn't an active bug as `preds` wasn't referenced by later passes, until #30079 ghstack-source-id: 3e151b74c31554299e870f001c0ac3f72706318c Pull Request resolved: https://github.com/facebook/react/pull/30076
Mofei Zhang committed
Jun 25, 2024 at 16:06 UTC
7d9861e70642719b120a5236ade5124912e42a92
4 files changed
+38
-2
compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts
+3
@@ -13,6 +13,7 @@ import {
13
HIRFunction,
14
ReactiveFunction,
15
assertConsistentIdentifiers,
16
+ assertTerminalPredsExist,
17
assertTerminalSuccessorsExist,
18
assertValidBlockNesting,
19
assertValidMutableRanges,
@@ -303,6 +304,8 @@ function* runWithEnvironment(
304
name: "FlattenScopesWithHooksOrUseHIR",
305
value: hir,
306
});
307
+ assertTerminalSuccessorsExist(hir);
308
+ assertTerminalPredsExist(hir);
309
}
310
311
const reactiveFunction = buildReactiveFunction(hir);
compiler/packages/babel-plugin-react-compiler/src/HIR/AssertTerminalBlocksExist.ts
renamed
+21
-1
@@ -8,7 +8,7 @@
8
import { CompilerError } from "../CompilerError";
9
import { GeneratedSource, HIRFunction } from "./HIR";
10
import { printTerminal } from "./PrintHIR";
11
-import { mapTerminalSuccessors } from "./visitors";
11
+import { eachTerminalSuccessor, mapTerminalSuccessors } from "./visitors";
12
13
export function assertTerminalSuccessorsExist(fn: HIRFunction): void {
14
for (const [, block] of fn.body.blocks) {
@@ -25,3 +25,23 @@ export function assertTerminalSuccessorsExist(fn: HIRFunction): void {
25
});
26
}
27
}
28
+
29
+export function assertTerminalPredsExist(fn: HIRFunction): void {
30
+ for (const [, block] of fn.body.blocks) {
31
+ for (const pred of block.preds) {
32
+ const predBlock = fn.body.blocks.get(pred);
33
+ CompilerError.invariant(predBlock != null, {
34
+ reason: "Expected predecessor block to exist",
35
+ description: `Block ${block.id} references non-existent ${pred}`,
36
+ loc: GeneratedSource,
37
+ });
38
+ CompilerError.invariant(
39
+ [...eachTerminalSuccessor(predBlock.terminal)].includes(block.id),
40
+ {
41
+ reason: "Terminal successor does not reference correct predecessor",
42
+ loc: GeneratedSource,
43
+ }
44
+ );
45
+ }
46
+ }
47
+}
compiler/packages/babel-plugin-react-compiler/src/HIR/PruneUnusedLabelsHIR.ts
+10
@@ -67,4 +67,14 @@ export function pruneUnusedLabelsHIR(fn: HIRFunction): void {
67
fn.body.blocks.delete(fallthroughId);
68
rewrites.set(fallthroughId, labelId);
69
}
70
+
71
+ for (const [_, block] of fn.body.blocks) {
72
+ for (const pred of block.preds) {
73
+ const rewritten = rewrites.get(pred);
74
+ if (rewritten != null) {
75
+ block.preds.delete(pred);
76
+ block.preds.add(rewritten);
77
+ }
78
+ }
79
+ }
80
}
compiler/packages/babel-plugin-react-compiler/src/HIR/index.ts
+4
-1
@@ -6,7 +6,10 @@
6
*/
7
8
export { assertConsistentIdentifiers } from "./AssertConsistentIdentifiers";
9
-export { assertTerminalSuccessorsExist } from "./AssertTerminalSuccessorsExist";
9
+export {
10
+ assertTerminalSuccessorsExist,
11
+ assertTerminalPredsExist,
12
+} from "./AssertTerminalBlocksExist";
13
export { assertValidBlockNesting } from "./AssertValidBlockNesting";
14
export { assertValidMutableRanges } from "./AssertValidMutableRanges";
15
export { lower } from "./BuildHIR";