Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/coreclr/jit/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -5561,7 +5561,7 @@ class Compiler
bool fgHaveProfileData();
void fgComputeProfileScale();
bool fgGetProfileWeightForBasicBlock(IL_OFFSET offset, BasicBlock::weight_t* weight);
void fgInstrumentMethod();
PhaseStatus fgInstrumentMethod();

public:
// fgIsUsingProfileWeights - returns true if we have real profile data for this method
Expand Down
57 changes: 33 additions & 24 deletions src/coreclr/jit/fgprofile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ class Instrumentor
}

public:
virtual bool ShouldProcess(BasicBlock* block)
{
return false;
}
virtual void Prepare()
{
}
Expand Down Expand Up @@ -267,14 +271,18 @@ class NonInstrumentor : public Instrumentor

//------------------------------------------------------------------------
// BlockCountInstrumentor: instrumentor that adds a counter to each
// basic block
// non-internal imported basic block
//
class BlockCountInstrumentor : public Instrumentor
{
public:
BlockCountInstrumentor(Compiler* comp) : Instrumentor(comp)
{
}
bool ShouldProcess(BasicBlock* block) override
{
return ((block->bbFlags & (BBF_INTERNAL | BBF_IMPORTED)) == BBF_IMPORTED);
}
void Prepare() override;
void BuildSchemaElements(BasicBlock* block, Schema& schema) override;
void Instrument(BasicBlock* block, Schema& schema, BYTE* profileMemory) override;
Expand Down Expand Up @@ -302,6 +310,7 @@ void BlockCountInstrumentor::Prepare()
//
// Arguments:
// block -- block to instrument
// schema -- schema that we're building
//
void BlockCountInstrumentor::BuildSchemaElements(BasicBlock* block, Schema& schema)
{
Expand Down Expand Up @@ -621,6 +630,10 @@ class ClassProbeInstrumentor : public Instrumentor
ClassProbeInstrumentor(Compiler* comp) : Instrumentor(comp)
{
}
bool ShouldProcess(BasicBlock* block) override
{
return ((block->bbFlags & (BBF_INTERNAL | BBF_IMPORTED)) == BBF_IMPORTED);
}
void Prepare() override;
void BuildSchemaElements(BasicBlock* block, Schema& schema) override;
void Instrument(BasicBlock* block, Schema& schema, BYTE* profileMemory) override;
Expand Down Expand Up @@ -648,6 +661,7 @@ void ClassProbeInstrumentor::Prepare()
//
// Arguments:
// block -- block to instrument
// schema -- schema that we're building
//
void ClassProbeInstrumentor::BuildSchemaElements(BasicBlock* block, Schema& schema)
{
Expand Down Expand Up @@ -707,7 +721,7 @@ void ClassProbeInstrumentor::Instrument(BasicBlock* block, Schema& schema, BYTE*
// ClassProbeInstrumentor::SuppressProbes: clean up if we're not instrumenting
//
// Notes:
// Currently we're hijacking the gtCallStubAddre of the call node to hold
// Currently we're hijacking the gtCallStubAddr of the call node to hold
// a pointer to the profile candidate info.
//
// We must undo this, if not instrumenting.
Expand Down Expand Up @@ -737,6 +751,9 @@ void ClassProbeInstrumentor::SuppressProbes()
//------------------------------------------------------------------------
// fgInstrumentMethod: add instrumentation probes to the method
//
// Returns:
// appropriate phase status
//
// Note:
//
// By default this instruments each non-internal block with
Expand All @@ -747,7 +764,7 @@ void ClassProbeInstrumentor::SuppressProbes()
// Probe structure is described by a schema array, which is created
// here based on flowgraph and IR structure.
//
void Compiler::fgInstrumentMethod()
PhaseStatus Compiler::fgInstrumentMethod()
{
noway_assert(!compIsForInlining());

Expand Down Expand Up @@ -775,20 +792,15 @@ void Compiler::fgInstrumentMethod()
Schema schema(getAllocator(CMK_Pgo));
for (BasicBlock* block = fgFirstBB; (block != nullptr); block = block->bbNext)
{
// Skip internal and un-imported blocks.
//
if ((block->bbFlags & BBF_IMPORTED) == 0)
if (countInst->ShouldProcess(block))
{
continue;
countInst->BuildSchemaElements(block, schema);
}

if ((block->bbFlags & BBF_INTERNAL) == BBF_INTERNAL)
if (classInst->ShouldProcess(block))
{
continue;
classInst->BuildSchemaElements(block, schema);
}

countInst->BuildSchemaElements(block, schema);
classInst->BuildSchemaElements(block, schema);
}

// Verify we created schema for the calls needing class probes.
Expand All @@ -802,7 +814,7 @@ void Compiler::fgInstrumentMethod()
if ((JitConfig.JitMinimalProfiling() > 0) && (countInst->SchemaCount() == 1) && (classInst->SchemaCount() == 0))
{
JITDUMP("Not instrumenting method: only one counter, and no class probes\n");
return;
return PhaseStatus::MODIFIED_NOTHING;
}

JITDUMP("Instrumenting method: %d count probes and %d class probes\n", countInst->SchemaCount(),
Expand All @@ -826,34 +838,29 @@ void Compiler::fgInstrumentMethod()
if (res != E_NOTIMPL)
{
noway_assert(!"Error: unexpected hresult from allocPgoInstrumentationBySchema");
return;
return PhaseStatus::MODIFIED_NOTHING;
}

// Do any cleanup we might need to do...
//
countInst->SuppressProbes();
classInst->SuppressProbes();
return;
return PhaseStatus::MODIFIED_NOTHING;
}

// Add the instrumentation code
//
for (BasicBlock* block = fgFirstBB; (block != nullptr); block = block->bbNext)
{
// Skip internal and un-imported blocks.
//
if ((block->bbFlags & BBF_IMPORTED) == 0)
if (countInst->ShouldProcess(block))
{
continue;
countInst->Instrument(block, schema, profileMemory);
}

if ((block->bbFlags & BBF_INTERNAL) == BBF_INTERNAL)
if (classInst->ShouldProcess(block))
{
continue;
classInst->Instrument(block, schema, profileMemory);
}

countInst->Instrument(block, schema, profileMemory);
classInst->Instrument(block, schema, profileMemory);
}

// Verify we instrumented everthing we created schemas for.
Expand All @@ -866,6 +873,8 @@ void Compiler::fgInstrumentMethod()
//
countInst->InstrumentMethodEntry(schema, profileMemory);
classInst->InstrumentMethodEntry(schema, profileMemory);

return PhaseStatus::MODIFIED_EVERYTHING;
}

bool flowList::setEdgeWeightMinChecked(BasicBlock::weight_t newWeight, BasicBlock::weight_t slop, bool* wbUsedSlop)
Expand Down
20 changes: 7 additions & 13 deletions src/coreclr/jit/phase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,13 @@ void Phase::PostPhase(PhaseStatus status)
// well as the new-style phases that have been updated to return
// PhaseStatus from their DoPhase methods.
//
static Phases s_allowlist[] = {PHASE_IMPORTATION,
PHASE_INDXCALL,
PHASE_MORPH_INLINE,
PHASE_ALLOCATE_OBJECTS,
PHASE_EMPTY_TRY,
PHASE_EMPTY_FINALLY,
PHASE_MERGE_FINALLY_CHAINS,
PHASE_CLONE_FINALLY,
PHASE_MERGE_THROWS,
PHASE_MORPH_GLOBAL,
PHASE_BUILD_SSA,
PHASE_RATIONALIZE,
PHASE_LOWERING,
static Phases s_allowlist[] = {PHASE_IMPORTATION, PHASE_IBCINSTR,
PHASE_INDXCALL, PHASE_MORPH_INLINE,
PHASE_ALLOCATE_OBJECTS, PHASE_EMPTY_TRY,
PHASE_EMPTY_FINALLY, PHASE_MERGE_FINALLY_CHAINS,
PHASE_CLONE_FINALLY, PHASE_MERGE_THROWS,
PHASE_MORPH_GLOBAL, PHASE_BUILD_SSA,
PHASE_RATIONALIZE, PHASE_LOWERING,
PHASE_STACK_LEVEL_SETTER};

if (madeChanges)
Expand Down