Home / File/ PruneMaybeThrows.ts — react Source File

PruneMaybeThrows.ts — react Source File

Architecture documentation for PruneMaybeThrows.ts, a typescript file in the react codebase. 9 imports, 0 dependents.

File typescript BabelCompiler Optimization 9 imports 3 functions

Entity Profile

Dependency Diagram

graph LR
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa["PruneMaybeThrows.ts"]
  0423f759_97e0_9101_4634_ed555abc5ca9["index.ts"]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> 0423f759_97e0_9101_4634_ed555abc5ca9
  df6865e0_b573_e905_84d6_4eb6b419a888["HIRBuilder.ts"]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> df6865e0_b573_e905_84d6_4eb6b419a888
  0c09df5a_6c07_11e5_1a6b_9253007463b8["markInstructionIds"]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> 0c09df5a_6c07_11e5_1a6b_9253007463b8
  ba25d103_adb3_8e17_0348_cdf4b23496b5["removeDeadDoWhileStatements"]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> ba25d103_adb3_8e17_0348_cdf4b23496b5
  c678dac0_f0b5_fd43_e8fe_97067c37de7d["removeUnnecessaryTryCatch"]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> c678dac0_f0b5_fd43_e8fe_97067c37de7d
  4fd451a9_a7fd_9520_07fd_783e18d24c84["removeUnreachableForUpdates"]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> 4fd451a9_a7fd_9520_07fd_783e18d24c84
  6976a9ee_9d8e_4f16_3016_495f39aff2fd["PrintHIR.ts"]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> 6976a9ee_9d8e_4f16_3016_495f39aff2fd
  bf7f1cf7_fc0e_6bac_827c_8d36d98126da["printPlace"]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> bf7f1cf7_fc0e_6bac_827c_8d36d98126da
  2ed45bcd_6c82_3ccd_0e20_fa96b5111055[".."]
  7b84c51c_1c0f_cc0c_c3be_9da73dc183aa --> 2ed45bcd_6c82_3ccd_0e20_fa96b5111055
  style 7b84c51c_1c0f_cc0c_c3be_9da73dc183aa fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

/**
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

import {CompilerError} from '..';
import {
  BlockId,
  GeneratedSource,
  HIRFunction,
  Instruction,
  assertConsistentIdentifiers,
  assertTerminalSuccessorsExist,
  mergeConsecutiveBlocks,
  reversePostorderBlocks,
} from '../HIR';
import {
  markInstructionIds,
  removeDeadDoWhileStatements,
  removeUnnecessaryTryCatch,
  removeUnreachableForUpdates,
} from '../HIR/HIRBuilder';
import {printPlace} from '../HIR/PrintHIR';

/**
 * This pass updates `maybe-throw` terminals for blocks that can provably *never* throw,
 * nulling out the handler to indicate that control will always continue. Note that
 * rewriting to a `goto` disrupts the structure of the HIR, making it more difficult to
 * reconstruct an ast during BuildReactiveFunction. Preserving the maybe-throw makes the
 * continuations clear, while nulling out the handler tells us that control cannot flow
 * to the handler.
 *
 * For now the analysis is very conservative, and only affects blocks with primitives or
 * array/object literals. Even a variable reference could throw bc of the TDZ.
 */
export function pruneMaybeThrows(fn: HIRFunction): void {
  const terminalMapping = pruneMaybeThrowsImpl(fn);
  if (terminalMapping) {
    /*
     * If terminals have changed then blocks may have become newly unreachable.
     * Re-run minification of the graph (incl reordering instruction ids)
     */
    reversePostorderBlocks(fn.body);
    removeUnreachableForUpdates(fn.body);
    removeDeadDoWhileStatements(fn.body);
    removeUnnecessaryTryCatch(fn.body);
    markInstructionIds(fn.body);
    mergeConsecutiveBlocks(fn);

    // Rewrite phi operands to reference the updated predecessor blocks
    for (const [, block] of fn.body.blocks) {
      for (const phi of block.phis) {
        for (const [predecessor, operand] of phi.operands) {
          if (!block.preds.has(predecessor)) {
            const mappedTerminal = terminalMapping.get(predecessor);
            CompilerError.invariant(mappedTerminal != null, {
              reason: `Expected non-existing phi operand's predecessor to have been mapped to a new terminal`,
              description: `Could not find mapping for predecessor bb${predecessor} in block bb${
                block.id
              } for phi ${printPlace(phi.place)}`,
              loc: GeneratedSource,
            });
            phi.operands.delete(predecessor);
            phi.operands.set(mappedTerminal, operand);
          }
        }
      }
    }

    assertConsistentIdentifiers(fn);
    assertTerminalSuccessorsExist(fn);
  }
}

function pruneMaybeThrowsImpl(fn: HIRFunction): Map<BlockId, BlockId> | null {
  const terminalMapping = new Map<BlockId, BlockId>();
  for (const [_, block] of fn.body.blocks) {
    const terminal = block.terminal;
    if (terminal.kind !== 'maybe-throw') {
      continue;
    }
    const canThrow = block.instructions.some(instr =>
      instructionMayThrow(instr),
    );
    if (!canThrow) {
      const source = terminalMapping.get(block.id) ?? block.id;
      terminalMapping.set(terminal.continuation, source);
      terminal.handler = null;
    }
  }
  return terminalMapping.size > 0 ? terminalMapping : null;
}

function instructionMayThrow(instr: Instruction): boolean {
  switch (instr.value.kind) {
    case 'Primitive':
    case 'ArrayExpression':
    case 'ObjectExpression': {
      return false;
    }
    default: {
      return true;
    }
  }
}

Domain

Subdomains

Frequently Asked Questions

What does PruneMaybeThrows.ts do?
PruneMaybeThrows.ts is a source file in the react codebase, written in typescript. It belongs to the BabelCompiler domain, Optimization subdomain.
What functions are defined in PruneMaybeThrows.ts?
PruneMaybeThrows.ts defines 3 function(s): instructionMayThrow, pruneMaybeThrows, pruneMaybeThrowsImpl.
What does PruneMaybeThrows.ts depend on?
PruneMaybeThrows.ts imports 9 module(s): .., HIRBuilder.ts, PrintHIR.ts, index.ts, markInstructionIds, printPlace, removeDeadDoWhileStatements, removeUnnecessaryTryCatch, and 1 more.
Where is PruneMaybeThrows.ts in the architecture?
PruneMaybeThrows.ts is located at compiler/packages/babel-plugin-react-compiler/src/Optimization/PruneMaybeThrows.ts (domain: BabelCompiler, subdomain: Optimization, directory: compiler/packages/babel-plugin-react-compiler/src/Optimization).

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free