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) {
Domain
Subdomains
Source
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