Files
react/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineFunctions.ts
T
mofeiZ d99f8bba2e [compiler] Delete LoweredFunction.dependencies and hoisted instructions (#32096)
LoweredFunction dependencies were exclusively used for dependency
extraction (in `propagateScopeDeps`). Now that we have a
`propagateScopeDepsHIR` that recursively traverses into nested
functions, we can delete `dependencies` and their associated synthetic
`LoadLocal`/`PropertyLoad` instructions.

[Internal snapshot
diff](https://www.internalfb.com/phabricator/paste/view/P1716950202) for
this change shows ~.2% of files changed. I [read through ~60 of the
changed
files](https://www.internalfb.com/phabricator/paste/view/P1733074307)
- most changes are due to better outlining (due to better DCE)
- a few changes in memo inference are due to changed ordering
```
// source
arr.map(() => contextVar.inner);

// previous instructions
$0 = LoadLocal arr
$1 = $0.map
// Below instructions are synthetic
$2 = LoadLocal contextVar
$3 = $2.inner
$4 = Function deps=$3 context=contextVar {
  ...
}
```
- a few changes are effectively bugfixes (see
`aliased-nested-scope-fn-expr`)
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/facebook/react/pull/32096).
* #32099
* #32286
* #32104
* #32098
* #32097
* __->__ #32096
2025-02-18 09:32:49 -07:00

50 lines
1.4 KiB
TypeScript

/**
* 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 {HIRFunction, IdentifierId} from '../HIR';
export function outlineFunctions(
fn: HIRFunction,
fbtOperands: Set<IdentifierId>,
): void {
for (const [, block] of fn.body.blocks) {
for (const instr of block.instructions) {
const {value, lvalue} = instr;
if (
value.kind === 'FunctionExpression' ||
value.kind === 'ObjectMethod'
) {
// Recurse in case there are inner functions which can be outlined
outlineFunctions(value.loweredFunc.func, fbtOperands);
}
if (
value.kind === 'FunctionExpression' &&
value.loweredFunc.func.context.length === 0 &&
// TODO: handle outlining named functions
value.loweredFunc.func.id === null &&
!fbtOperands.has(lvalue.identifier.id)
) {
const loweredFunc = value.loweredFunc.func;
const id = fn.env.generateGloballyUniqueIdentifierName(loweredFunc.id);
loweredFunc.id = id.value;
fn.env.outlineFunction(loweredFunc, null);
instr.value = {
kind: 'LoadGlobal',
binding: {
kind: 'Global',
name: id.value,
},
loc: value.loc,
};
}
}
}
}