-
Notifications
You must be signed in to change notification settings - Fork 47k
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
[compiler] Add lowerContextAccess pass #30548
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: 3dde92d74a7ebb4fc688074c628038eb6eff8fb9 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: 0cefe6c7127da23bf2d3f199898ec2030b394527 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: f01152c777fa2877d4118894557a6b96d572e18f 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: 6a8d58e9f18a34c00e7555fe1e961d6f2420b01c 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: 45b59f0cc825b010ec9c034ceea447fafeef6ed6 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: 8a1ba69989c13939c6646b7ac6fc5255b4770ac2 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: 92d0f6ff2fe95cda93f66786f56e97ba9ace95fa 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.