Home / Function/ mergeConsecutiveBlocks() — react Function Reference

mergeConsecutiveBlocks() — react Function Reference

Architecture documentation for the mergeConsecutiveBlocks() function in MergeConsecutiveBlocks.ts from the react codebase.

Entity Profile

Dependency Diagram

graph TD
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a["mergeConsecutiveBlocks()"]
  010bd3a7_d091_50ea_4e1f_20541d841f85["MergeConsecutiveBlocks.ts"]
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a -->|defined in| 010bd3a7_d091_50ea_4e1f_20541d841f85
  127c19ef_021e_5644_a84e_da0d0ed84999["terminalFallthrough()"]
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a -->|calls| 127c19ef_021e_5644_a84e_da0d0ed84999
  c037181b_4cfb_039c_81d1_8f129348cda7["get()"]
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a -->|calls| c037181b_4cfb_039c_81d1_8f129348cda7
  041ca752_10c1_3cda_1f5c_02f44a01310e["invariant()"]
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a -->|calls| 041ca752_10c1_3cda_1f5c_02f44a01310e
  15ce5dd6_b99d_ce73_8748_87fb1267ffd7["merge()"]
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a -->|calls| 15ce5dd6_b99d_ce73_8748_87fb1267ffd7
  6d209f7d_6d38_4dee_c66c_76af0358f508["markPredecessors()"]
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a -->|calls| 6d209f7d_6d38_4dee_c66c_76af0358f508
  d0cd56ee_e8d2_fa25_8e21_652a56c56855["terminalHasFallthrough()"]
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a -->|calls| d0cd56ee_e8d2_fa25_8e21_652a56c56855
  53244187_914c_cc90_5880_7bfc1fc9c0bb["push()"]
  7b930d0b_9ec9_a382_a51f_3ffb682d5b9a -->|calls| 53244187_914c_cc90_5880_7bfc1fc9c0bb
  style 7b930d0b_9ec9_a382_a51f_3ffb682d5b9a fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts lines 30–123

export function mergeConsecutiveBlocks(fn: HIRFunction): void {
  const merged = new MergedBlocks();
  const fallthroughBlocks = new Set<BlockId>();
  for (const [, block] of fn.body.blocks) {
    const fallthrough = terminalFallthrough(block.terminal);
    if (fallthrough !== null) {
      fallthroughBlocks.add(fallthrough);
    }

    for (const instr of block.instructions) {
      if (
        instr.value.kind === 'FunctionExpression' ||
        instr.value.kind === 'ObjectMethod'
      ) {
        mergeConsecutiveBlocks(instr.value.loweredFunc.func);
      }
    }

    if (
      // Can only merge blocks with a single predecessor
      block.preds.size !== 1 ||
      // Value blocks cannot merge
      block.kind !== 'block' ||
      // Merging across fallthroughs could move the predecessor out of its block scope
      fallthroughBlocks.has(block.id)
    ) {
      continue;
    }
    const originalPredecessorId = Array.from(block.preds)[0]!;
    const predecessorId = merged.get(originalPredecessorId);
    const predecessor = fn.body.blocks.get(predecessorId);
    CompilerError.invariant(predecessor !== undefined, {
      reason: `Expected predecessor ${predecessorId} to exist`,
      loc: GeneratedSource,
    });
    if (predecessor.terminal.kind !== 'goto' || predecessor.kind !== 'block') {
      /*
       * The predecessor is not guaranteed to transfer control to this block,
       * they aren't consecutive.
       */
      continue;
    }

    // Replace phis in the merged block with canonical assignments to the single operand value
    for (const phi of block.phis) {
      CompilerError.invariant(phi.operands.size === 1, {
        reason: `Found a block with a single predecessor but where a phi has multiple (${phi.operands.size}) operands`,
        loc: GeneratedSource,
      });
      const operand = Array.from(phi.operands.values())[0]!;
      const lvalue: Place = {
        kind: 'Identifier',
        identifier: phi.place.identifier,
        effect: Effect.ConditionallyMutate,
        reactive: false,
        loc: GeneratedSource,
      };
      const instr: Instruction = {
        id: predecessor.terminal.id,
        lvalue: {...lvalue},
        value: {
          kind: 'LoadLocal',
          place: {...operand},
          loc: GeneratedSource,
        },
        effects: [{kind: 'Alias', from: {...operand}, into: {...lvalue}}],
        loc: GeneratedSource,
      };
      predecessor.instructions.push(instr);
    }

    predecessor.instructions.push(...block.instructions);
    predecessor.terminal = block.terminal;
    merged.merge(block.id, predecessorId);
    fn.body.blocks.delete(block.id);
  }
  for (const [, block] of fn.body.blocks) {
    for (const phi of block.phis) {
      for (const [predecessorId, operand] of phi.operands) {
        const mapped = merged.get(predecessorId);
        if (mapped !== predecessorId) {

Subdomains

Frequently Asked Questions

What does mergeConsecutiveBlocks() do?
mergeConsecutiveBlocks() is a function in the react codebase, defined in compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts.
Where is mergeConsecutiveBlocks() defined?
mergeConsecutiveBlocks() is defined in compiler/packages/babel-plugin-react-compiler/src/HIR/MergeConsecutiveBlocks.ts at line 30.
What does mergeConsecutiveBlocks() call?
mergeConsecutiveBlocks() calls 7 function(s): get, invariant, markPredecessors, merge, push, terminalFallthrough, terminalHasFallthrough.

Analyze Your Own Codebase

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

Try Supermodel Free