Skip to content

JIT: Forward sub candidate-set multi-statement lookahead#124843

Draft
AndyAyersMS wants to merge 2 commits intodotnet:mainfrom
AndyAyersMS:ForwardSubEnhancements
Draft

JIT: Forward sub candidate-set multi-statement lookahead#124843
AndyAyersMS wants to merge 2 commits intodotnet:mainfrom
AndyAyersMS:ForwardSubEnhancements

Conversation

@AndyAyersMS
Copy link
Member

Refactor forward substitution to walk blocks first-to-last, maintaining a set of candidate def statements. For each statement, check for last uses of candidate locals and attempt substitution. This naturally handles arbitrary lookahead distance and subsumes the old backtracking logic.

Key changes:

  • ForwardSubCandidate struct tracks def, local, cached flags, and accumulated intermediate effects
  • Extracted fgForwardSubIsDefCandidate for def-side validation
  • Added fgForwardSubCanReorderPast for bidirectional effect checking
  • Added fgForwardSubHasStoreInterferenceWithCandidate for intermediate store conflict detection (includes struct field/parent checks)
  • Refactored fgForwardSubStatement to accept candidate + use statement
  • Added backward-compat wrapper for promotion.cpp caller
  • Capped candidate set at 16 to bound O(N*M) work

Refactor forward substitution to walk blocks first-to-last, maintaining
a set of candidate def statements. For each statement, check for last
uses of candidate locals and attempt substitution. This naturally handles
arbitrary lookahead distance and subsumes the old backtracking logic.

Key changes:
- ForwardSubCandidate struct tracks def, local, cached flags, and
  accumulated intermediate effects
- Extracted fgForwardSubIsDefCandidate for def-side validation
- Added fgForwardSubCanReorderPast for bidirectional effect checking
- Added fgForwardSubHasStoreInterferenceWithCandidate for intermediate
  store conflict detection (includes struct field/parent checks)
- Refactored fgForwardSubStatement to accept candidate + use statement
- Added backward-compat wrapper for promotion.cpp caller
- Capped candidate set at 16 to bound O(N*M) work

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings February 25, 2026 02:54
@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 Feb 25, 2026
@AndyAyersMS
Copy link
Member Author

@jakobbotsch this is more like what you were suggesting. I haven't deeply reviewed or edited any of it.

@dotnet-policy-service
Copy link
Contributor

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

Copy link
Contributor

Copilot AI left a 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 refactors the forward substitution optimization to support multi-statement lookahead. Instead of only checking the immediately following statement, the new implementation maintains a candidate set of def statements and processes each statement to find last uses of candidate locals across arbitrary distances.

Changes:

  • Introduced ForwardSubCandidate struct to track def statements with accumulated intermediate effects
  • Extracted helper functions for modularity: fgForwardSubIsDefCandidate (def-side validation), fgForwardSubCanReorderPast (bidirectional effect checking), and fgForwardSubHasStoreInterferenceWithCandidate (store conflict detection)
  • Refactored fgForwardSubBlock to walk statements first-to-last with candidate set tracking and interference removal
  • Added backward-compatibility wrapper for existing promotion.cpp caller
  • Capped candidate set at 16 to bound O(N*M) complexity

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/coreclr/jit/forwardsub.cpp Complete refactoring of forward substitution logic to support multi-statement lookahead with candidate set tracking, extraction of helper functions, and improved effect accumulation across intermediate statements
src/coreclr/jit/compiler.h Added ForwardSubCandidate forward declaration and new helper function signatures

candidate->intermediateFlags |= stmtFlags;
if ((stmtFlags & GTF_EXCEPT) != 0)
{
candidate->intermediateExcepts = ExceptionSetFlags::UnknownException;
Copy link

Copilot AI Feb 25, 2026

Choose a reason for hiding this comment

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

The exception tracking logic unconditionally sets intermediateExcepts = ExceptionSetFlags::UnknownException using assignment rather than bitwise OR. While this works correctly since the field starts as None and stays UnknownException once set, using |= would be more consistent with how intermediateFlags is accumulated on line 1275 and would make the intent clearer. Consider changing line 1278 to: candidate->intermediateExcepts |= ExceptionSetFlags::UnknownException;

Suggested change
candidate->intermediateExcepts = ExceptionSetFlags::UnknownException;
candidate->intermediateExcepts |= ExceptionSetFlags::UnknownException;

Copilot uses AI. Check for mistakes.
// forward sub candidate. Cap the candidate set size to bound
// the O(N*M) work in the main loop.
//
unsigned const maxCandidates = 16;
Copy link
Member Author

Choose a reason for hiding this comment

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

We should make this a jit config option, and also when we hit capacity we might be better off replacing the "oldest" candidate.

{
return false;
}
if (((fwdFlags & GTF_EXCEPT) != 0) && ((stmtFlags & GTF_EXCEPT) != 0))
Copy link
Member Author

Choose a reason for hiding this comment

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

I think we may want to allow similar exceptions to be re-ordered.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants