Skip to content

Commit

Permalink
JIT: Add a uniform mechanism to track metadata/metrics about the comp…
Browse files Browse the repository at this point in the history
…ilation (#98653)

Adds a JIT-EE API to report metadata back to the EE side about the JIT
compilation, and adds support for saving these metrics as part of SPMI runs.
Switches a number of adhoc metrics to use this scheme, and also adds a few new
ones.

The metadata is currently only reported with checked JITs.

Also adds support for fast perfscore diffs, and adds perfscore into the reports
generated by `superpmi.py asmdiffs`.

Fix #52877
  • Loading branch information
jakobbotsch authored Feb 21, 2024
1 parent 8fb9f4b commit 80084aa
Show file tree
Hide file tree
Showing 41 changed files with 674 additions and 163 deletions.
7 changes: 7 additions & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -2916,6 +2916,13 @@ class ICorStaticInfo
uint32_t numMappings // [IN] Number of rich mappings
) = 0;

// Report back some metadata about the compilation to the EE -- for
// example, metrics about the compilation.
virtual void reportMetadata(
const char* key,
const void* value,
size_t length) = 0;

/*-------------------------- Misc ---------------------------------------*/

// Used to allocate memory that needs to handed to the EE.
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/inc/icorjitinfoimpl_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,11 @@ void reportRichMappings(
ICorDebugInfo::RichOffsetMapping* mappings,
uint32_t numMappings) override;

void reportMetadata(
const char* key,
const void* value,
size_t length) override;

void* allocateArray(
size_t cBytes) override;

Expand Down
10 changes: 5 additions & 5 deletions src/coreclr/inc/jiteeversionguid.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ typedef const GUID *LPCGUID;
#define GUID_DEFINED
#endif // !GUID_DEFINED

constexpr GUID JITEEVersionIdentifier = { /* 0fb71692-0ee6-4914-88a8-6446e45f23e8 */
0x0fb71692,
0x0ee6,
0x4914,
{0x88, 0xa8, 0x64, 0x46, 0xe4, 0x5f, 0x23, 0xe8}
constexpr GUID JITEEVersionIdentifier = { /* 1f30d12b-38f1-4f1e-a08a-831def882aa4 */
0x1f30d12b,
0x38f1,
0x4f1e,
{0xa0, 0x8a, 0x83, 0x1d, 0xef, 0x88, 0x2a, 0xa4}
};

//////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
3 changes: 3 additions & 0 deletions src/coreclr/jit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ set( JIT_SOURCES
jitconfig.cpp
jiteh.cpp
jithashtable.cpp
jitmetadata.cpp
lclmorph.cpp
lclvars.cpp
likelyclass.cpp
Expand Down Expand Up @@ -334,6 +335,8 @@ set( JIT_HEADERS
jitexpandarray.h
jitgcinfo.h
jithashtable.h
jitmetadata.h
jitmetadatalist.h
jitpch.h
jitstd.h
lir.h
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/jit/ICorJitInfo_names_generated.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ DEF_CLR_API(setBoundaries)
DEF_CLR_API(getVars)
DEF_CLR_API(setVars)
DEF_CLR_API(reportRichMappings)
DEF_CLR_API(reportMetadata)
DEF_CLR_API(allocateArray)
DEF_CLR_API(freeArray)
DEF_CLR_API(getArgNext)
Expand Down
10 changes: 10 additions & 0 deletions src/coreclr/jit/ICorJitInfo_wrapper_generated.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,16 @@ void WrapICorJitInfo::reportRichMappings(
API_LEAVE(reportRichMappings);
}

void WrapICorJitInfo::reportMetadata(
const char* key,
const void* value,
size_t length)
{
API_ENTER(reportMetadata);
wrapHnd->reportMetadata(key, value, length);
API_LEAVE(reportMetadata);
}

void* WrapICorJitInfo::allocateArray(
size_t cBytes)
{
Expand Down
8 changes: 3 additions & 5 deletions src/coreclr/jit/codegencommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,8 @@ void CodeGen::genPrepForCompiler()
}
}
VarSetOps::AssignNoCopy(compiler, genLastLiveSet, VarSetOps::MakeEmpty(compiler));
genLastLiveMask = RBM_NONE;
#ifdef DEBUG
compiler->fgBBcountAtCodegen = compiler->fgBBcount;
#endif
genLastLiveMask = RBM_NONE;
compiler->Metrics.BasicBlocksAtCodegen = compiler->fgBBcount;
}

//------------------------------------------------------------------------
Expand Down Expand Up @@ -2042,7 +2040,7 @@ void CodeGen::genEmitMachineCode()

printf("; Total bytes of code %d, prolog size %d, PerfScore %.2f, instruction count %d, allocated bytes for "
"code %d",
codeSize, prologSize, compiler->info.compPerfScore, instrCount,
codeSize, prologSize, compiler->Metrics.PerfScore, instrCount,
GetEmitter()->emitTotalHotCodeSize + GetEmitter()->emitTotalColdCodeSize);

if (dspMetrics)
Expand Down
49 changes: 33 additions & 16 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1793,9 +1793,13 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
info.compMethodName = eeGetMethodName(methodHnd);
info.compClassName = eeGetClassName(info.compClassHnd);
info.compFullName = eeGetMethodFullName(methodHnd);
info.compPerfScore = 0.0;

info.compMethodSuperPMIIndex = g_jitHost->getIntConfigValue(W("SuperPMIMethodContextNumber"), -1);

if (!compIsForInlining())
{
JitMetadata::report(this, JitMetadata::MethodFullName, info.compFullName, strlen(info.compFullName));
}
#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_FLOWGRAPHS

#if defined(DEBUG)
Expand Down Expand Up @@ -1863,9 +1867,7 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
//
// Initialize all the per-method statistics gathering data structures.
//

optLoopsCloned = 0;

CLANG_FORMAT_COMMENT_ANCHOR;
#if LOOP_HOIST_STATS
m_loopsConsidered = 0;
m_curLoopHasHoistedExpression = false;
Expand Down Expand Up @@ -1965,6 +1967,8 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
compUsesThrowHelper = false;

m_preferredInitCctor = CORINFO_HELP_UNDEF;

new (&Metrics, jitstd::placement_t()) JitMetrics();
}

/*****************************************************************************
Expand Down Expand Up @@ -5215,7 +5219,7 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
#ifdef DEBUG
if (JitConfig.JitMetrics() > 0)
{
sprintf_s(metricPart, 128, ", perfScore=%.2f, numCse=%u", info.compPerfScore, optCSEcount);
sprintf_s(metricPart, 128, ", perfScore=%.2f, numCse=%u", Metrics.PerfScore, optCSEcount);
}
#endif

Expand Down Expand Up @@ -5419,7 +5423,7 @@ PhaseStatus Compiler::placeLoopAlignInstructions()
{
block->SetFlags(BBF_LOOP_ALIGN);
BitVecOps::AddElemD(&loopTraits, alignedLoops, loop->GetIndex());
INDEBUG(loopAlignCandidates++);
Metrics.LoopAlignmentCandidates++;

BasicBlock* prev = block->Prev();
// shouldAlignLoop should have guaranteed these properties.
Expand Down Expand Up @@ -5468,7 +5472,7 @@ PhaseStatus Compiler::placeLoopAlignInstructions()
}
}

JITDUMP("Found %u candidates for loop alignment\n", loopAlignCandidates);
JITDUMP("Found %d candidates for loop alignment\n", Metrics.LoopAlignmentCandidates);

return madeChanges ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING;
}
Expand Down Expand Up @@ -6441,6 +6445,8 @@ void Compiler::compCompileFinish()
compArenaAllocator->finishMemStats();
memAllocHist.record((unsigned)((compArenaAllocator->getTotalBytesAllocated() + 1023) / 1024));
memUsedHist.record((unsigned)((compArenaAllocator->getTotalBytesUsed() + 1023) / 1024));

Metrics.BytesAllocated = (int64_t)compArenaAllocator->getTotalBytesUsed();
}

#ifdef DEBUG
Expand Down Expand Up @@ -6624,7 +6630,7 @@ void Compiler::compCompileFinish()

printf(" %3d |", optCallCount);
printf(" %3d |", optIndirectCallCount);
printf(" %3d |", fgBBcountAtCodegen);
printf(" %3d |", Metrics.BasicBlocksAtCodegen);
printf(" %3d |", lvaCount);

if (opts.MinOpts())
Expand All @@ -6637,13 +6643,13 @@ void Compiler::compCompileFinish()
printf(" %3d |", optCSEcount);
}

if (info.compPerfScore < 9999.995)
if (Metrics.PerfScore < 9999.995)
{
printf(" %7.2f |", info.compPerfScore);
printf(" %7.2f |", Metrics.PerfScore);
}
else
{
printf(" %7.0f |", info.compPerfScore);
printf(" %7.0f |", Metrics.PerfScore);
}

printf(" %4d |", info.compMethodInfo->ILCodeSize);
Expand All @@ -6654,9 +6660,13 @@ void Compiler::compCompileFinish()
printf(""); // in our logic this causes a flush
}

JITDUMP("Final metrics:\n");
Metrics.report(this);
DBEXEC(verbose, Metrics.dump());

if (verbose)
{
printf("****** DONE compiling %s\n", info.compFullName);
printf("\n****** DONE compiling %s\n", info.compFullName);
printf(""); // in our logic this causes a flush
}

Expand Down Expand Up @@ -7149,6 +7159,13 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
opts.disAsm = false;
}

#ifdef DEBUG
{
const char* tieringName = compGetTieringName(true);
JitMetadata::report(this, JitMetadata::TieringName, tieringName, strlen(tieringName));
}
#endif

#if COUNT_BASIC_BLOCKS
bbCntTable.record(fgBBcount);

Expand Down Expand Up @@ -9077,12 +9094,12 @@ void JitTimer::PrintCsvMethodStats(Compiler* comp)
fprintf(s_csvFile, "%u,", comp->info.compILCodeSize);
fprintf(s_csvFile, "%u,", comp->fgBBcount);
fprintf(s_csvFile, "%u,", comp->opts.MinOpts());
fprintf(s_csvFile, "%u,", comp->optNumNaturalLoopsFound);
fprintf(s_csvFile, "%u,", comp->optLoopsCloned);
fprintf(s_csvFile, "%d,", comp->Metrics.LoopsFoundDuringOpts);
fprintf(s_csvFile, "%d,", comp->Metrics.LoopsCloned);
#if FEATURE_LOOP_ALIGN
#ifdef DEBUG
fprintf(s_csvFile, "%u,", comp->loopAlignCandidates);
fprintf(s_csvFile, "%u,", comp->loopsAligned);
fprintf(s_csvFile, "%d,", comp->Metrics.LoopAlignmentCandidates);
fprintf(s_csvFile, "%d,", comp->Metrics.LoopsAligned);
#endif // DEBUG
#endif // FEATURE_LOOP_ALIGN
unsigned __int64 totCycles = 0;
Expand Down
12 changes: 4 additions & 8 deletions src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ inline var_types genActualType(T value);
#include "simd.h"
#include "simdashwintrinsic.h"

#include "jitmetadata.h"

/*****************************************************************************
* Forward declarations
*/
Expand Down Expand Up @@ -4968,7 +4970,6 @@ class Compiler
unsigned fgEdgeCount; // # of control flow edges between the BBs
unsigned fgBBcount; // # of BBs in the method (in the linked list that starts with fgFirstBB)
#ifdef DEBUG
unsigned fgBBcountAtCodegen; // # of BBs in the method at the start of codegen
jitstd::vector<BasicBlock*>* fgBBOrder; // ordered vector of BBs
#endif
// Used as a quick check for whether loop alignment should look for natural loops.
Expand Down Expand Up @@ -4997,7 +4998,6 @@ class Compiler
// 2. All loop exits where bbIsHandlerBeg(exit) is false have only loop predecessors.
//
bool optLoopsCanonical;
unsigned optNumNaturalLoopsFound; // Number of natural loops found in the loop finding phase

bool fgBBVarSetsInited;

Expand Down Expand Up @@ -6841,16 +6841,11 @@ class Compiler

public:
bool fgHasLoops;
#ifdef DEBUG
unsigned loopAlignCandidates; // number of candidates identified by placeLoopAlignInstructions
unsigned loopsAligned; // number of loops actually aligned
#endif // DEBUG

protected:
unsigned optCallCount; // number of calls made in the method
unsigned optIndirectCallCount; // number of virtual, interface and indirect calls made in the method
unsigned optNativeCallCount; // number of Pinvoke/Native calls made in the method
unsigned optLoopsCloned; // number of loops cloned in the current method.

#ifdef DEBUG
void optCheckPreds();
Expand Down Expand Up @@ -10155,7 +10150,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
const char* compMethodName;
const char* compClassName;
const char* compFullName;
double compPerfScore;
int compMethodSuperPMIIndex; // useful when debugging under SuperPMI

#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_FLOWGRAPHS
Expand Down Expand Up @@ -10616,6 +10610,8 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
static EnregisterStats s_enregisterStats;
#endif // TRACK_ENREG_STATS

JitMetrics Metrics;

bool compIsForInlining() const;
bool compDonotInline();

Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4393,7 +4393,7 @@ size_t emitter::emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp)
float insExeCost = insEvaluateExecutionCost(id);
// All compPerfScore calculations must be performed using doubles
double insPerfScore = (double)(ig->igWeight / (double)BB_UNITY_WEIGHT) * insExeCost;
emitComp->info.compPerfScore += insPerfScore;
emitComp->Metrics.PerfScore += insPerfScore;
ig->igPerfScore += insPerfScore;
#endif // defined(DEBUG) || defined(LATE_DISASM)

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/emitxarch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12475,10 +12475,10 @@ BYTE* emitter::emitOutputAlign(insGroup* ig, instrDesc* id, BYTE* dst)
assert(paddingToAdd == paddingNeeded);
}
}

emitComp->loopsAligned++;
#endif

emitComp->Metrics.LoopsAligned++;

#ifdef DEBUG
// Under STRESS_EMITTER, if this is the 'align' before the 'jmp' instruction,
// then add "int3" instruction. Since int3 takes 1 byte, we would only add
Expand Down
3 changes: 1 addition & 2 deletions src/coreclr/jit/fgbasic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@ void Compiler::fgInit()
fgBBcount = 0;

#ifdef DEBUG
fgBBcountAtCodegen = 0;
fgBBOrder = nullptr;
fgBBOrder = nullptr;
#endif // DEBUG

fgMightHaveNaturalLoops = false;
Expand Down
Loading

0 comments on commit 80084aa

Please sign in to comment.