Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Track return type for shared generics via exact context - #129373

#129373
Open
MichalPetryka wants to merge 6 commits into
dotnet:maindotnet/runtime:mainfrom
MichalPetryka:return-contextMichalPetryka/runtime:return-contextCopy head branch name to clipboard
Open

Track return type for shared generics via exact context#129373
MichalPetryka wants to merge 6 commits into
dotnet:maindotnet/runtime:mainfrom
MichalPetryka:return-contextMichalPetryka/runtime:return-contextCopy head branch name to clipboard

Conversation

@MichalPetryka

@MichalPetryka MichalPetryka commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Retrying #100041, seems to work locally but not sure if everything is correct since I was getting a bunch of asserts.

Example code this improves: https://compiler-explorer.com/z/q437fGGnW

@github-actions github-actions Bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Jun 13, 2026
@MichalPetryka

Copy link
Copy Markdown
Contributor Author

@MihuBot

@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @jakobbotsch
See info in area-owners.md if you want to be subscribed.

Comment thread src/coreclr/jit/fginline.cpp
Comment thread src/coreclr/vm/methodtable.cpp Outdated
Comment thread src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Outdated
@jkotas
jkotas marked this pull request as ready for review June 14, 2026 14:03
@jkotas
jkotas requested a review from MichalStrehovsky as a code owner June 14, 2026 14:03
Copilot AI review requested due to automatic review settings June 14, 2026 14:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 extends CoreCLR JIT “exact context” tracking so that calls with shared generic return types can later recover a more precise return type (avoiding __Canon), enabling improved downstream optimizations (e.g., devirtualization / inlining decisions based on sharper types).

Changes:

  • Introduces ExactContextInfo (renamed from LateDevirtualizationInfo) and stores it on GT_CALL nodes for virtual calls and certain shared-generic-return calls.
  • Uses the saved exact context in gtGetClassHandle to query the EE for a more precise call return type.
  • Adjusts NativeAOT/CoreCLR tooling JitInterface logic around method signature instantiation and callsite-specific intrinsic expansion context.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/coreclr/vm/methodtable.cpp Adds a reverse hierarchy lookup when retrieving parent instantiation.
src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs Changes how memberParent is handled when computing a method signature.
src/coreclr/tools/aot/ILCompiler.RyuJit/JitInterface/CorInfoImpl.RyuJit.cs Updates contextHandle when an intrinsic expands to a different callsite-specific helper method.
src/coreclr/jit/inline.h Renames LateDevirtualizationInfoExactContextInfo and updates associated comment.
src/coreclr/jit/importercalls.cpp Saves ExactContextInfo for virtual calls and shared generic returns.
src/coreclr/jit/gentree.h Renames the per-call field to gtExactContextInfo.
src/coreclr/jit/gentree.cpp Initializes/clones gtExactContextInfo and uses it to refine return-type signature queries.
src/coreclr/jit/fginline.cpp Updates late devirtualization to use gtExactContextInfo.
Comments suppressed due to low confidence (1)

src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs:1233

  • This change avoids the Debug.Assert by skipping re-instantiation when memberParent isn't the same type definition as method.OwningType. However, RyuJIT can pass a derived type as memberParent (e.g., Derived when the method is declared on Base), and in that case we still need to locate the corresponding instantiation of the owning type up the BaseType chain to produce the correct signature. Otherwise the returned signature can remain canonical/shared (e.g., with __Canon) and defeat the purpose of passing memberParent.
                    else if (type is InstantiatedType instantiatedType && method.OwningType.HasSameTypeDefinition(instantiatedType))
                    {
                        Instantiation methodInst = method.Instantiation;
                        method = _compilation.TypeSystemContext.GetMethodForInstantiatedType(method.GetTypicalMethodDefinition(), instantiatedType);
                        if (methodInst.Length > 0)
                        {
                            method = method.MakeInstantiatedMethod(methodInst);
                        }
                    }

Comment thread src/coreclr/jit/gentree.cpp Outdated
Comment thread src/coreclr/vm/methodtable.cpp Outdated
Comment thread src/coreclr/jit/inline.h
Update the exact context info after late devirtualization
@MichalPetryka

Copy link
Copy Markdown
Contributor Author

@MihuBot -nuget

Comment thread src/coreclr/jit/fginline.cpp Outdated
Comment thread src/coreclr/jit/fginline.cpp Outdated
Co-authored-by: Steve <hez2010@outlook.com>
@MihaZupan

Copy link
Copy Markdown
Member

@MihuBot -nuget -jitutils-repo EgorBo/jitutils -jitutils-branch pmi-deterministic-cctors

@MichalPetryka

Copy link
Copy Markdown
Contributor Author

The bot shows a bunch of diffs in NuGet libraries but only 2 ones in the BCL so it seems like the BCL just doesn't hit this pattern?

@AndyAyersMS does this answer your question from the last time?

@github-actions

github-actions Bot commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Workflow state for the Holistic Review Orchestrator.

{
  "version": 5,
  "last_dispatched_commit": "e91c12de49c642b60b9be49c91e8421c1c289596",
  "last_dispatched_base_ref": "main",
  "last_dispatched_base_sha": "f36379692fdd0448b5b1276a1a4aa075a0d2c1e0",
  "last_reviewed_commit": "e91c12de49c642b60b9be49c91e8421c1c289596",
  "last_reviewed_base_ref": "main",
  "last_reviewed_base_sha": "f36379692fdd0448b5b1276a1a4aa075a0d2c1e0",
  "last_recorded_worker_run_id": "29676143510",
  "review_attempt_commit": "",
  "review_attempt_base_ref": "",
  "review_attempt_count": 0,
  "max_review_attempts": 5,
  "review_history_format": "holistic-review-disclosure-v1",
  "review_history": [
    {
      "commit": "e91c12de49c642b60b9be49c91e8421c1c289596",
      "review_id": 4730524423
    }
  ]
}

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Holistic Review

Motivation: When the JIT queries a call's return type via gtGetClassHandle for a user call, it previously discarded the exact generic context, so for shared generic instantiations it could only recover an approximate (canonical) return type. This blocks type-driven optimizations on values flowing out of such calls. The PR revives the earlier attempt (#100041) to preserve the exact context so the precise return type is available. Example improvement: (compilerexplorer.com/redacted)

Approach: The existing per-call LateDevirtualizationInfo side structure is generalized and renamed to ExactContextInfo (gtLateDevirtualizationInfo -> gtExactContextInfo). It is now populated not only for devirtualization candidates but also for calls whose signature return type is a shared instantiation (eeIsSharedInst(sig->retTypeSigClass), excluding byrefs). A new eeGetMethodFromContext helper factors the method-context decoding out of eeGetClassFromContext. gtGetClassHandle consumes the saved context to compute an exactClass (and, for method contexts, an exact method) before calling eeGetMethodSig, yielding the precise return type. The RyuJit AOT getCallInfo path is updated to set contextHandle when intrinsic-for-callsite expansion swaps the target method, so the JIT sees a consistent exact context in that case.

Summary: The change is well-scoped and internally consistent. The rename is applied uniformly (no stale LateDevirtualizationInfo references remain), gtExactContextInfo is initialized in gtNewCallNode and copied in gtCloneExprCallHelper, and the unconditional deref in LateDevirtualization remains safe because the field is still always set for devirtualization candidates. All new reads outside that path are null-guarded, and eeGetMethodFromContext asserts its context encoding. The main residual risk is correctness of the newly-derived exact return types across the full generics matrix (CoreCLR and NativeAOT) — the author noted encountering asserts while iterating — so this is primarily validated by broad JIT/pri1 and NativeAOT CI coverage rather than by review of the diff alone. No blocking issues found in the changed lines. Verdict: LGTM pending green CI.

Detailed Findings

No actionable defects identified in the changed lines. Observations:

  • gtGetClassHandle (src/coreclr/jit/gentree.cpp): for a CLASS-flagged context, method remains the (canonical) gtCallMethHnd while exactClass is set from the context; for a METHOD-flagged context both method and exactClass are refined. This asymmetry is intentional and correct, but relies on eeGetMethodSig producing the exact return type from the approximate method + exact class in the CLASS case; worth confirming via CI on shared value-type instantiations.
  • The sig->retType != CORINFO_TYPE_BYREF exclusion in importercalls.cpp is a reasonable guard (byref-returning shared generics don't yield a usable return class), but is undocumented; a brief comment on why byref is excluded would aid future readers.
  • The NativeAOT getCallInfo change asserts !exactContextNeedsRuntimeLookup and no instantiations on the intrinsic-expansion swap path; these assumptions look sound for the ExpandIntrinsicForCallsite cases but are the most AOT-specific part of the change and should be exercised by the NativeAOT test legs.

Note

This review was generated by this repository's Holistic Review agentic workflow to complement the built-in Copilot review.

Generated by Holistic Review · 69.6 AIC · ⌖ 10.5 AIC · ⊞ 10K

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI community-contribution Indicates that the PR has been added by a community member

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.