-
Notifications
You must be signed in to change notification settings - Fork 48.8k
[compiler] Add lowerContextAccess pass #30548
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. ghstack-source-id: 3dde92d Pull Request resolved: #30548
I ended up synthesizing new functions in the IR as it works well with the outlining infra, but it does add a fair amount of code. If anyone feels strongly, I'm happy to move this to codegen and emit babel AST directly. There's still a bunch of follow ups after this lands:
cc @jackpope |
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. ghstack-source-id: 0cefe6c Pull Request resolved: #30548
Assuming we can enable the flag internally only, we can compile to an intermediate hook defined on WWW which can handle the GK/QE. Something like |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awesome, super exciting to see this come together. I'm really curious about the results of the experiment.
In terms of the implementation, see comments. The key thing to address is the ArrayPattern case - make it a todo or add tests - but also using createTemporaryPlace()
will reduce the boilerplate by quite a bit.
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
Show resolved
Hide resolved
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
Outdated
Show resolved
Hide resolved
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
Outdated
Show resolved
Hide resolved
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
Outdated
Show resolved
Hide resolved
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
Outdated
Show resolved
Hide resolved
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
Outdated
Show resolved
Hide resolved
compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts
Outdated
Show resolved
Hide resolved
I like the overall approach here of using HIR to construct the function. |
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. ghstack-source-id: f01152c Pull Request resolved: #30548
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. ghstack-source-id: 6a8d58e Pull Request resolved: #30548
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. ghstack-source-id: 45b59f0 Pull Request resolved: #30548
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the updates and extra tests, this looks great! See comment below, i could see landing this with missing fixtures temporarily, but it seems like the next steps are fairly straightforward and could also happen directly in this PR (convert the destructure to an ArrayPattern, make the fixtures run in sprout).
``` | ||
|
||
### Eval output | ||
(kind: exception) Fixture not implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing fixture
``` | ||
|
||
### Eval output | ||
(kind: exception) Fixture not implemented |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixture
const { foo, bar } = useContext(MyContext, _temp); | ||
let t0; | ||
if ($[0] !== foo || $[1] !== bar) { | ||
t0 = <Bar foo={foo} bar={bar} />; | ||
$[0] = foo; | ||
$[1] = bar; | ||
$[2] = t0; | ||
} else { | ||
t0 = $[2]; | ||
} | ||
return t0; | ||
} | ||
function _temp(t0) { | ||
return [t0.foo, t0.bar]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How are you thinking about sequencing the next steps here? Asking because the generated code doesn't seem like it could work yet: the temp function returns an array, but the context value is destructured into an object and there's nothing that tells us how to map the array into the object.
Seems like we'd need to convert the destructuring into an ArrayPattern to match? Also, if we take Jack's suggestion of compiling into a custom useContextSelector
-style hook, then we can implement a basic version of that in shared-runtime and this could be an end-to-end test with sprout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return value of the selector isn't returned from the useContext call. The runtime simply compares the return values from the selector to determine if the context is dirty. If the values are different, then it returns the context object from useContext call, not the values from the selector function.
Ideally we'd just compile the selector function with Forget and compare the result, rather than iterate over an array, but that's optimisation for the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ahhhhh got it, makes sense
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. ghstack-source-id: 8a1ba69 Pull Request resolved: #30548
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
Lowering to a different function call implemented here: #30612 |
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. [ghstack-poisoned]
*This is only for internal profiling, not intended to ship.* This pass is intended to be used with #30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. ghstack-source-id: 92d0f6f Pull Request resolved: #30548
Stack from ghstack (oldest at bottom):
This is only for internal profiling, not intended to ship.
This pass is intended to be used with #30407.
This pass synthesizes selector functions by collecting immediately
destructured context acesses. We bailout for other types of context
access.
This pass lowers context access to use a selector function by passing
the synthesized selector function as the second argument.