Skip to content

Conversation

mofeiZ
Copy link
Contributor

@mofeiZ mofeiZ commented Sep 23, 2024

Stack from ghstack (oldest at bottom):

Prior to this PR, we check whether the property load source (e.g. the evaluation of <base> in <base>.property) is mutable + scoped to determine whether the property load itself is eligible for hoisting. This changes to check the base identifier of the load.

  • This is needed for the next PR [compiler][hir] Only hoist always-accessed PropertyLoads from function decls #31066. We want to evaluate whether the base identifier is mutable within the context of the outermost function. This is because all LoadLocals and PropertyLoads within a nested function declaration have mutable-ranges within the context of the function, but the base identifier is a context variable.
  • A side effect is that we no longer infer loads from props / other function arguments as mutable in edge cases (e.g. props escaping out of try-blocks or being assigned to context variables)

[ghstack-poisoned]
[ghstack-poisoned]
Copy link

vercel bot commented Sep 23, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
react-compiler-playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 2, 2024 8:20pm

[ghstack-poisoned]
[ghstack-poisoned]
mofeiZ added a commit that referenced this pull request Sep 30, 2024
Followup from #30894 , not sure how these got missed. Note that this PR just copies the fixtures without adding `@enablePropagateDepsInHIR`. #31032 follows and actually enables the HIR-version of propagateScopeDeps to run. I split this out into two PRs to make snapshot differences easier to review, but also happy to merge

Fixtures found from locally setting snap test runner to default to `enablePropagateDepsInHIR: 'enabled_baseline'` and forking fixtures files with different output.

ghstack-source-id: 7d7cf41
Pull Request resolved: #31030
[ghstack-poisoned]
[ghstack-poisoned]
[ghstack-poisoned]
[ghstack-poisoned]
Comment on lines +3 to +16
/**
* Not safe to hoist read of maybeNullObject.value.inner outside of the
* try-catch block, as that might throw
*/
function useFoo(maybeNullObject: {value: {inner: number}} | null) {
const y = [];
try {
y.push(identity(maybeNullObject.value.inner));
} catch {
y.push('null');
}

return y;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug repro is unrelated to this fix

let x;
if ($[0] !== props) {
if ($[0] !== props.y || $[1] !== props.e) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that we're now inferring props as non-mutable. Previously, props.y was not marked hoistable because the evaluation of LoadLocal props had a mutable range (due to the try-catch).

@mofeiZ mofeiZ marked this pull request as ready for review October 1, 2024 15:41
[ghstack-poisoned]
[ghstack-poisoned]
mofeiZ added 2 commits October 2, 2024 12:53
[ghstack-poisoned]
[ghstack-poisoned]
mofeiZ added 2 commits October 2, 2024 16:18
[ghstack-poisoned]
[ghstack-poisoned]
@mofeiZ mofeiZ changed the base branch from gh/mofeiZ/17/base to main October 3, 2024 17:55
@mofeiZ mofeiZ merged commit edacbde into main Oct 3, 2024
19 checks passed
mofeiZ added a commit that referenced this pull request Oct 3, 2024
…n decls (#31066)

Stack from [ghstack](https://github.com/ezyang/ghstack) (oldest at
bottom):
* __->__ #31066
* #31032

Prior to this PR, we consider all of a nested function's accessed paths
as 'hoistable' (to the basic block in which the function was defined).
Now, we traverse nested functions and find all paths hoistable to their
*entry block*.

Note that this only replaces the *hoisting* part of function
declarations, not dependencies. This realistically only affects optional
chains within functions, which always get truncated to its inner
non-optional path (see
[todo-infer-function-uncond-optionals-hoisted.tsx](https://github.com/facebook/react/blob/576f3c0aa898cb99da1b7bf15317756e25c13708/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/propagate-scope-deps-hir-fork/reduce-reactive-deps/todo-infer-function-uncond-optionals-hoisted.tsx))

See newly added test fixtures for details

Update: Note that toggling `enableTreatFunctionDepsAsConditional` makes
a non-trivial impact on granularity of inferred deps (i.e. we find that
function declarations uniquely identify some paths as hoistable).
Snapshot comparison of internal code shows ~2.5% of files get worse
dependencies ([internal
link](https://www.internalfb.com/phabricator/paste/view/P1625792186))
Testmasha pushed a commit to Testmasha/Test that referenced this pull request Apr 15, 2025
…ting

Prior to this PR, we check whether the property load source (e.g. the evaluation of `<base>` in `<base>.property`) is mutable + scoped to determine whether the property load itself is eligible for hoisting. This changes to check the base identifier of the load.
- This is needed for the next PR #31066. We want to evaluate whether the base identifier is mutable within the context of the *outermost function*. This is because all LoadLocals and PropertyLoads within a nested function declaration have mutable-ranges within the context of the function, but the base identifier is a context variable.
- A side effect is that we no longer infer loads from props / other function arguments as mutable in edge cases (e.g. props escaping out of try-blocks or being assigned to context variables)

ghstack-source-id: 83d20e1
Pull Request resolved: facebook/react#31032
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed React Core Team Opened by a member of the React Core Team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants