main
ts 47 lines 1.73 KB
Raw
1 /**
2 * Copyright (c) Meta Platforms, Inc. and affiliates.
3 *
4 * This source code is licensed under the MIT license found in the
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 import {CompilerError} from '../CompilerError';
9 import {GeneratedSource, HIRFunction} from './HIR';
10 import {printTerminal} from './PrintHIR';
11 import {eachTerminalSuccessor, mapTerminalSuccessors} from './visitors';
12
13 export function assertTerminalSuccessorsExist(fn: HIRFunction): void {
14 for (const [, block] of fn.body.blocks) {
15 mapTerminalSuccessors(block.terminal, successor => {
16 CompilerError.invariant(fn.body.blocks.has(successor), {
17 reason: `Terminal successor references unknown block`,
18 description: `Block bb${successor} does not exist for terminal '${printTerminal(
19 block.terminal,
20 )}'`,
21 loc: (block.terminal as any).loc ?? GeneratedSource,
22 });
23 return successor;
24 });
25 }
26 }
27
28 export function assertTerminalPredsExist(fn: HIRFunction): void {
29 for (const [, block] of fn.body.blocks) {
30 for (const pred of block.preds) {
31 const predBlock = fn.body.blocks.get(pred);
32 CompilerError.invariant(predBlock != null, {
33 reason: 'Expected predecessor block to exist',
34 description: `Block ${block.id} references non-existent ${pred}`,
35 loc: GeneratedSource,
36 });
37 CompilerError.invariant(
38 [...eachTerminalSuccessor(predBlock.terminal)].includes(block.id),
39 {
40 reason: 'Terminal successor does not reference correct predecessor',
41 description: `Block bb${block.id} has bb${predBlock.id} as a predecessor, but bb${predBlock.id}'s successors do not include bb${block.id}`,
42 loc: GeneratedSource,
43 },
44 );
45 }
46 }
47 }