Skip to content

Commit

Permalink
JIT: Allow experimenting with different CSE subsets
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
AndyAyersMS committed Oct 3, 2023
1 parent 8d2ada7 commit dde0538
Show file tree
Hide file tree
Showing 7 changed files with 54 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2008,6 +2008,11 @@ void CodeGen::genEmitMachineCode()
codeSize, prologSize, compiler->info.compPerfScore, instrCount,
GetEmitter()->emitTotalHotCodeSize + GetEmitter()->emitTotalColdCodeSize);

if (JitConfig.JitMetrics() > 0)
{
printf(", num cse %d", compiler->optCSEcount);
}

#if TRACK_LSRA_STATS
if (JitConfig.DisplayLsraStats() == 3)
{
Expand Down
10 changes: 8 additions & 2 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5221,10 +5221,16 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
char debugPart[128] = {0};
INDEBUG(sprintf_s(debugPart, 128, ", hash=0x%08x%s", info.compMethodHash(), compGetStressMessage()));

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

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,
compGetTieringName(), osrBuffer, hasProf ? " with " : "", hasProf ? compGetPgoSourceName() : "",
info.compILCodeSize, *methodCodeSize, debugPart);
info.compILCodeSize, *methodCodeSize, debugPart, metricPart);
}

compFunctionTraceEnd(*methodCodePtr, *methodCodeSize, false);
Expand Down
7 changes: 5 additions & 2 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -639,6 +639,8 @@ class LclVarDsc

#ifdef DEBUG
unsigned char lvClassInfoUpdated : 1; // true if this var has updated class handle or exactness
unsigned char lvIsHoist : 1; // CSE temp for a hoisted tree
unsigned char lvIsMultiDefCSE : 1; // CSE temp for a multi-def CSE
#endif

unsigned char lvImplicitlyReferenced : 1; // true if there are non-IR references to this local (prolog, epilog, gc,
Expand Down Expand Up @@ -6978,9 +6980,10 @@ class Compiler

bool optDoCSE; // True when we have found a duplicate CSE tree
bool optValnumCSE_phase; // True when we are executing the optOptimizeValnumCSEs() phase
unsigned optCSECandidateCount; // Count of CSE's candidates
unsigned optCSECandidateCount; // Count of CSE candidates
unsigned optCSEstart; // The first local variable number that is a CSE
unsigned optCSEcount; // The total count of CSE's introduced.
unsigned optCSEattempt; // The number of CSEs attempted so far.
unsigned optCSEcount; // The total count of CSEs introduced.
weight_t optCSEweight; // The weight of the current block when we are doing PerformCSE

bool optIsCSEcandidate(GenTree* tree);
Expand Down
7 changes: 7 additions & 0 deletions src/coreclr/jit/jitconfigvalues.h
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,13 @@ CONFIG_INTEGER(JitConstCSE, W("JitConstCSE"), 0)
#define CONST_CSE_ENABLE_ALL 3
#define CONST_CSE_ENABLE_ALL_NO_SHARING 4

// 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)

///
/// JIT
///
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7570,6 +7570,14 @@ void Compiler::lvaDumpEntry(unsigned lclNum, FrameLayoutState curState, size_t r
{
printf(" tier0-frame");
}
if (varDsc->lvIsHoist)
{
printf(" hoist");
}
if (varDsc->lvIsMultiDefCSE)
{
printf(" multi-def");
}

#ifndef TARGET_64BIT
if (varDsc->lvStructDoubleAlign)
Expand Down
20 changes: 20 additions & 0 deletions src/coreclr/jit/optcse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2808,6 +2808,10 @@ class CSE_Heuristic
cseSsaNum = lclDsc->lvPerSsaData.AllocSsaNum(allocator);
ssaVarDsc = lclDsc->GetPerSsaData(cseSsaNum);
}
else
{
INDEBUG(lclDsc->lvIsMultiDefCSE = 1);
}

// Verify that all of the ValueNumbers in this list are correct as
// Morph will change them when it performs a mutating operation.
Expand Down Expand Up @@ -2888,6 +2892,7 @@ class CSE_Heuristic
if (isDef)
{
lclDsc->incRefCnts(curWeight, m_pCompiler);
INDEBUG(lclDsc->lvIsHoist |= ((lst->tslTree->gtFlags & GTF_MAKE_CSE) != 0));
}
}
lst = lst->tslNext;
Expand Down Expand Up @@ -3318,6 +3323,21 @@ class CSE_Heuristic
bool doCSE = PromotionCheck(&candidate);

#ifdef DEBUG

if (doCSE)
{
const int attempt = m_pCompiler->optCSEattempt++;

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

JITDUMP("CSE " FMT_CSE " attempt %u %s by hash 0x%x mask 0x%0x: %s\n", candidate.CseIndex(),
attempt, doCSE ? "allowed" : "disabled", JitConfig.JitCSEHash(), JitConfig.JitCSEMask(),
m_pCompiler->info.compFullName);
}
}

if (m_pCompiler->verbose)
{
if (doCSE)
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/optimizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ void Compiler::optInit()
optAssertionDep = nullptr;
optCSEstart = BAD_VAR_NUM;
optCSEcount = 0;
optCSEattempt = 0;
}

DataFlow::DataFlow(Compiler* pCompiler) : m_pCompiler(pCompiler)
Expand Down

0 comments on commit dde0538

Please sign in to comment.