Skip to content
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: Allow experimenting with different CSE subsets #92918

Merged
merged 5 commits into from
Oct 6, 2023

Conversation

AndyAyersMS
Copy link
Member

Introduce two config vars for experimenting with CSEs:

  • JitCSEHash: identifies a method for CSE experimentatin
  • JitCSEMask: specifies a bitmask of allowed CSEs (by "attempt")

When the hash is nonzero, any method whose hash matches will perform only the subset of CSEs specified by the mask (up to 32 CSEs).

Also introduce a config var to dump the total number of CSEs to either the assemby listing footer or the one-liner from the disassembly summary.

  • JitMetrics

This can perhaps be generalized eventually to report more metrics and perhaps to report them back to SPMI when it is the jit host.

Finally, note CSE lcl vars that represent hoisted trees and or are "multiple-def" CSEs in the local var table.

Contributes to #92915.

Introduce two config vars for experimenting with CSEs:
* `JitCSEHash`: identifies a method for CSE experimentatin
* `JitCSEMask`: specifies a bitmask of allowed CSEs (by "attempt")

When the hash is nonzero, any method whose hash matches will perform
only the subset of CSEs specified by the mask (up to 32 CSEs).

Also introduce a config var to dump the total number of CSEs to either
the assemby listing footer or the one-liner from the disassembly summary.
* `JitMetrics`

This can perhaps be generalized eventually to report more metrics
and perhaps to report them back to SPMI when it is the jit host.

Finally, note CSE lcl vars that represent hoisted trees and or are
"multiple-def" CSEs in the local var table.

Contributes to dotnet#92915.
@ghost ghost assigned AndyAyersMS Oct 3, 2023
@dotnet-issue-labeler dotnet-issue-labeler bot added the area-CodeGen-coreclr CLR JIT compiler in src/coreclr/src/jit and related components such as SuperPMI label Oct 3, 2023
@AndyAyersMS
Copy link
Member Author

cc @dotnet/jit-contrib

@ghost
Copy link

ghost commented Oct 3, 2023

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

Issue Details

Introduce two config vars for experimenting with CSEs:

  • JitCSEHash: identifies a method for CSE experimentatin
  • JitCSEMask: specifies a bitmask of allowed CSEs (by "attempt")

When the hash is nonzero, any method whose hash matches will perform only the subset of CSEs specified by the mask (up to 32 CSEs).

Also introduce a config var to dump the total number of CSEs to either the assemby listing footer or the one-liner from the disassembly summary.

  • JitMetrics

This can perhaps be generalized eventually to report more metrics and perhaps to report them back to SPMI when it is the jit host.

Finally, note CSE lcl vars that represent hoisted trees and or are "multiple-def" CSEs in the local var table.

Contributes to #92915.

Author: AndyAyersMS
Assignees: AndyAyersMS
Labels:

area-CodeGen-coreclr

Milestone: -

Comment on lines 379 to 385
// Allow fine-grained controls of CSEs done in a particular method
CONFIG_INTEGER(JitCSEHash, W("JitCSEHash"), 0)
CONFIG_INTEGER(JitCSEMask, W("JitCSEMask"), 0)

// Enable metric output in jit disasm & elsewhere
CONFIG_INTEGER(JitMetrics, W("JitMetrics"), 0)

Copy link
Member

Choose a reason for hiding this comment

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

These are available in Release. Makes sense for JitMetrics, but do you want that for the JitCSE* variables?

I suggest documenting the JitCSE* variables in more detail (how do you set JitCSEMask?)

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, will do.

Copy link
Member

Choose a reason for hiding this comment

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

It doesn't look like JitMetrics actually works in release (even though it is made available there).

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, let me move it under debug for now too.

const bool hasProf = fgHaveProfileData();
printf("%4d: JIT compiled %s [%s%s%s%s, IL size=%u, code size=%u%s]\n", methodsCompiled, fullName,
printf("%4d: JIT compiled %s [%s%s%s%s, IL size=%u, code size=%u%s,%s]\n", methodsCompiled, fullName,
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
printf("%4d: JIT compiled %s [%s%s%s%s, IL size=%u, code size=%u%s,%s]\n", methodsCompiled, fullName,
printf("%4d: JIT compiled %s [%s%s%s%s, IL size=%u, code size=%u%s%s]\n", methodsCompiled, fullName,

char metricPart[128] = {0};
if (JitConfig.JitMetrics() > 0)
{
INDEBUG(sprintf_s(debugPart, 128, ", perfScore=%.2f, numCse=%u", info.compPerfScore, optCSEcount));
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
INDEBUG(sprintf_s(debugPart, 128, ", perfScore=%.2f, numCse=%u", info.compPerfScore, optCSEcount));
INDEBUG(sprintf_s(metricPart, 128, ", perfScore=%.2f, numCse=%u", info.compPerfScore, optCSEcount));

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, I added this but wasn't using it for anything, so didn't notice it was messed up.


if (m_pCompiler->info.compMethodHash() == (unsigned)JitConfig.JitCSEHash())
{
doCSE = ((1ULL << attempt) & ((unsigned long long)JitConfig.JitCSEMask())) != 0;
Copy link
Member

Choose a reason for hiding this comment

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

Should you check that attempt is in range? i.e.,

if (attempt >= 32) { // or `sizeof(unsigned int) * BITS_PER_BYTE`
  doCSE = false;
} else {
...
}

Presumably JitCSEMask is a 32-bit int.

@AndyAyersMS
Copy link
Member Author

@BruceForstall think I addressed your feedback, feel free to take another look.

Add option to suppress dumping of OSR methods.
// We can only mask the first 32 CSE attempts, so suppress anything beyond that.
// Note methods with > 32 CSEs are currently quite rare.
//
if (attempt > 32)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (attempt > 32)
if (attempt >= 32)

otherwise if attempt == 32 you do (int) 1 << 32 which is undefined?

@AndyAyersMS
Copy link
Member Author

SPMI failures are "no space on device". No diffs expected and no diffs in the runs that succeeded.

@AndyAyersMS AndyAyersMS removed the request for review from jakobbotsch October 6, 2023 16:49
@AndyAyersMS AndyAyersMS merged commit 96a35e0 into dotnet:main Oct 6, 2023
@ghost ghost locked as resolved and limited conversation to collaborators Nov 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
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.

3 participants