-
Notifications
You must be signed in to change notification settings - Fork 5.2k
JIT: GDV Cleanup Phase #116992
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
JIT: GDV Cleanup Phase #116992
Conversation
If a method has GDVs and the JIT is able to to improve types during inlining, run a pass after inlining that tries to resolve GDVs using those improved types. This typically happens when the object tested in a GDV is returned from some kind of factory method where the exact type becomes apparent only after inlining. Contributes to dotnet#25448.
Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch |
@EgorBot --filter "System.Collections.IterateForEach*.*Dictionary" |
libraries tests and SPMI both hit an assert
EgorBot confirms this improves the |
Can't repro the SPMI assert. I have some other changes to make here so will see if it recurs when I push those. |
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.
Pull Request Overview
This PR introduces a new JIT phase that resolves Guarded Devirtualization (GDV) checks using improved type information discovered during inlining. Key changes include additions to the GuardInfo structure, a new static IsGuard method implementation, a new fgResolveGDVs phase in fgopt.cpp, and updates in the compiler phase handling to integrate this new functionality.
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
src/coreclr/jit/objectalloc.h | Added new fields (m_stmt, m_relop) in GuardInfo and updated the IsGuard method signature. |
src/coreclr/jit/objectalloc.cpp | Updated IsGuard implementation to capture guard-related nodes, but missing assignment of m_block. |
src/coreclr/jit/fgopt.cpp | Added a new fgResolveGDVs phase that resolves GDV checks based on improved type information. |
src/coreclr/jit/fginline.cpp | Updated inline walker to set hasUpdatedTypeLocals when type updates occur during inlining. |
src/coreclr/jit/compphases.h | Registered the new PHASE_RESOLVE_GDVS phase. |
src/coreclr/jit/compiler.h | Added a flag and declaration for fgResolveGDVs. |
src/coreclr/jit/compiler.cpp | Invoked fgResolveGDVs in the main compile flow if optimizations are enabled. |
@dotnet/jit-contrib PTAL Arguably we should try folding other branches here too, though I don't know of any other cases where we'd expect to succeed, so have kept this narrowly focused for now. |
// Passed the checks... fill in the info. | ||
// | ||
info->m_local = addr->AsLclVar()->GetLclNum(); | ||
bool isNonNull = false; |
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.
nit for style:
- GenTree* ObjectAllocator::IsGuard(BasicBlock* block, GuardInfo* info)
+ /* static */ GenTree* ObjectAllocator::IsGuard(BasicBlock* block, GuardInfo* info)
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. I will add this to my (growing) list of deferred cleanups.
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.
Is that actually in our coding conventions? I certainly never add those and prefer to keep them only in the header.
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.
It's mentioned here, though with a slightly different format. To be honest, I based this suggestion on what I've seen elsewhere in the codebase, rather than what the guidelines say -- in some respects, we've diverged quite a bit from them (or the document hasn't been maintained).
If a method has GDVs and the JIT is able to to improve types during inlining, run a pass after inlining that tries to resolve GDVs using those improved types.
This typically happens when the object tested in a GDV is returned from some kind of factory method where the exact type becomes apparent only after inlining.
Contributes to #25448.