Home / Function/ eliminateRedundantPhi() — react Function Reference

eliminateRedundantPhi() — react Function Reference

Architecture documentation for the eliminateRedundantPhi() function in EliminateRedundantPhi.ts from the react codebase.

Entity Profile

Dependency Diagram

graph TD
  bb44971b_3fb2_facf_d3bd_8a33c436c5ca["eliminateRedundantPhi()"]
  d9a8ed15_9e19_8782_09a4_5122ac3f1a64["EliminateRedundantPhi.ts"]
  bb44971b_3fb2_facf_d3bd_8a33c436c5ca -->|defined in| d9a8ed15_9e19_8782_09a4_5122ac3f1a64
  0ae43a4a_0f8b_aa1a_7dc3_83d069c62191["rewritePlace()"]
  bb44971b_3fb2_facf_d3bd_8a33c436c5ca -->|calls| 0ae43a4a_0f8b_aa1a_7dc3_83d069c62191
  041ca752_10c1_3cda_1f5c_02f44a01310e["invariant()"]
  bb44971b_3fb2_facf_d3bd_8a33c436c5ca -->|calls| 041ca752_10c1_3cda_1f5c_02f44a01310e
  10043bf1_f7ee_9ed9_307a_fe3edfd02b09["eachInstructionLValue()"]
  bb44971b_3fb2_facf_d3bd_8a33c436c5ca -->|calls| 10043bf1_f7ee_9ed9_307a_fe3edfd02b09
  ccace1c3_85b7_a05e_c2a5_7eff8b3422ed["eachInstructionOperand()"]
  bb44971b_3fb2_facf_d3bd_8a33c436c5ca -->|calls| ccace1c3_85b7_a05e_c2a5_7eff8b3422ed
  41232a25_deb6_6e83_05a8_ae9f961656f7["eachTerminalOperand()"]
  bb44971b_3fb2_facf_d3bd_8a33c436c5ca -->|calls| 41232a25_deb6_6e83_05a8_ae9f961656f7
  style bb44971b_3fb2_facf_d3bd_8a33c436c5ca fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

compiler/packages/babel-plugin-react-compiler/src/SSA/EliminateRedundantPhi.ts lines 38–167

export function eliminateRedundantPhi(
  fn: HIRFunction,
  sharedRewrites?: Map<Identifier, Identifier>,
): void {
  const ir = fn.body;
  const rewrites: Map<Identifier, Identifier> =
    sharedRewrites != null ? sharedRewrites : new Map();

  /*
   * Whether or the CFG has a back-edge (a loop). We determine this dynamically
   * during the first iteration over the CFG by recording which blocks were already
   * visited, and checking if a block has any predecessors that weren't visited yet.
   * Because blocks are in reverse postorder, the only time this can occur is a loop.
   */
  let hasBackEdge = false;
  const visited: Set<BlockId> = new Set();

  /*
   * size tracks the number of rewrites at the beginning of each iteration, so we can
   * compare to see if any new rewrites were added in that iteration.
   */
  let size = rewrites.size;
  do {
    size = rewrites.size;
    for (const [blockId, block] of ir.blocks) {
      /*
       * On the first iteration of the loop check for any back-edges.
       * if there aren't any then there won't be a second iteration
       */
      if (!hasBackEdge) {
        for (const predId of block.preds) {
          if (!visited.has(predId)) {
            hasBackEdge = true;
          }
        }
      }
      visited.add(blockId);

      // Find any redundant phis
      phis: for (const phi of block.phis) {
        // Remap phis in case operands are from eliminated phis
        phi.operands.forEach((place, _) => rewritePlace(place, rewrites));
        // Find if the phi can be eliminated
        let same: Identifier | null = null;
        for (const [_, operand] of phi.operands) {
          if (
            (same !== null && operand.identifier.id === same.id) ||
            operand.identifier.id === phi.place.identifier.id
          ) {
            /*
             * This operand is the same as the phi or is the same as the
             * previous non-phi operands
             */
            continue;
          } else if (same !== null) {
            /*
             * There are multiple operands not equal to the phi itself,
             * this phi can't be eliminated.
             */
            continue phis;
          } else {
            // First non-phi operand
            same = operand.identifier;
          }
        }
        CompilerError.invariant(same !== null, {
          reason: 'Expected phis to be non-empty',
          loc: GeneratedSource,
        });
        rewrites.set(phi.place.identifier, same);
        block.phis.delete(phi);
      }

      // Rewrite all instruction lvalues and operands
      for (const instr of block.instructions) {
        for (const place of eachInstructionLValue(instr)) {
          rewritePlace(place, rewrites);
        }
        for (const place of eachInstructionOperand(instr)) {
          rewritePlace(place, rewrites);
        }

Subdomains

Frequently Asked Questions

What does eliminateRedundantPhi() do?
eliminateRedundantPhi() is a function in the react codebase, defined in compiler/packages/babel-plugin-react-compiler/src/SSA/EliminateRedundantPhi.ts.
Where is eliminateRedundantPhi() defined?
eliminateRedundantPhi() is defined in compiler/packages/babel-plugin-react-compiler/src/SSA/EliminateRedundantPhi.ts at line 38.
What does eliminateRedundantPhi() call?
eliminateRedundantPhi() calls 5 function(s): eachInstructionLValue, eachInstructionOperand, eachTerminalOperand, invariant, rewritePlace.

Analyze Your Own Codebase

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

Try Supermodel Free