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: Add a unified mechanism to track metadata/metrics about the compilation #98653

Merged
merged 24 commits into from
Feb 21, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/coreclr/inc/corinfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -2916,6 +2916,12 @@ 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) = 0;

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

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

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

void* allocateArray(
size_t cBytes) override;

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
9 changes: 9 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,15 @@ void WrapICorJitInfo::reportRichMappings(
API_LEAVE(reportRichMappings);
}

void WrapICorJitInfo::reportMetadata(
const char* key,
const void* value)
{
API_ENTER(reportMetadata);
wrapHnd->reportMetadata(key, value);
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
37 changes: 22 additions & 15 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1793,9 +1793,10 @@ 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);

JitMetadata::report(this, JitMetadataName::MethodFullName, info.compFullName);
#endif // defined(DEBUG) || defined(LATE_DISASM) || DUMP_FLOWGRAPHS

#if defined(DEBUG)
Expand Down Expand Up @@ -1863,9 +1864,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 +1964,8 @@ void Compiler::compInit(ArenaAllocator* pAlloc,
compUsesThrowHelper = false;

m_preferredInitCctor = CORINFO_HELP_UNDEF;

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

/*****************************************************************************
Expand Down Expand Up @@ -5212,7 +5213,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 All @@ -5222,6 +5223,8 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
info.compILCodeSize, *methodCodeSize, debugPart, metricPart);
}

INDEBUG(Metrics.report(this));

compFunctionTraceEnd(*methodCodePtr, *methodCodeSize, false);
JITDUMP("Method code size: %d\n", (unsigned)(*methodCodeSize));

Expand Down Expand Up @@ -5416,7 +5419,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 @@ -5465,7 +5468,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 @@ -6438,6 +6441,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 @@ -6621,7 +6626,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 @@ -6634,13 +6639,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 Down Expand Up @@ -7146,6 +7151,8 @@ int Compiler::compCompileHelper(CORINFO_MODULE_HANDLE classPtr,
opts.disAsm = false;
}

INDEBUG(JitMetadata::report(this, JitMetadataName::TieringName, compGetTieringName(true)));

#if COUNT_BASIC_BLOCKS
bbCntTable.record(fgBBcount);

Expand Down Expand Up @@ -9074,12 +9081,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 @@ -4960,7 +4962,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 @@ -4989,7 +4990,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 @@ -6828,16 +6828,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 @@ -10142,7 +10137,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 @@ -10603,6 +10597,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
41 changes: 41 additions & 0 deletions src/coreclr/jit/jitmetadata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#include "jitpch.h"
#include "jitmetadata.h"

#ifdef DEBUG

const char* JitMetadata::getName(JitMetadataName name)
{
switch (name)
{
#define JITMETADATA(name, type, flags) \
case JitMetadataName::name: \
return #name;
#include "jitmetadatalist.h"

default:
unreached();
}
}

void JitMetadata::report(Compiler* comp, JitMetadataName name, const void* data)
{
comp->info.compCompHnd->reportMetadata(getName(name), data);
Copy link
Member

Choose a reason for hiding this comment

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

Should the report functions do nothing if RunningSuperPmiReplay() is false? (I guess the VM does nothing anyway)

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I figured that we should just let it be up to the EE. If the EE wants to do something with the information then that's up to them. (Also, we don't check for SPMI in release JITs)

}

template <typename T>
static void reportValue(Compiler* comp, const char* key, T value)
{
comp->info.compCompHnd->reportMetadata(key, &value);
}

void JitMetrics::report(Compiler* comp)
{
#define JITMETADATAINFO(name, type, flags)
#define JITMETADATAMETRIC(name, type, flags) reportValue(comp, #name, name);
#include "jitmetadatalist.h"
}

#endif
29 changes: 29 additions & 0 deletions src/coreclr/jit/jitmetadata.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#pragma once

class Compiler;

enum class JitMetadataName
{
#define JITMETADATA(name, type, flags) name,
#include "jitmetadatalist.h"
};

class JitMetadata
{
public:
static const char* getName(JitMetadataName name);
static void report(Compiler* comp, JitMetadataName name, const void* data);
};

class JitMetrics
{
public:
#define JITMETADATAINFO(name, type, flags)
#define JITMETADATAMETRIC(name, type, flags) type name = 0;
#include "jitmetadatalist.h"

void report(Compiler* comp);
};
Loading
Loading