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: Try to retain entry weight during profile synthesis #111971

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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/fgprofile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2942,7 +2942,7 @@ PhaseStatus Compiler::fgIncorporateProfileData()

// We now always run repair, to get consistent initial counts
//
JITDUMP("\n%sRepairing profile...\n", opts.IsOSR() ? "blending" : "repairing");
JITDUMP("\nRepairing profile...\n");
ProfileSynthesis::Run(this, ProfileSynthesisOption::RepairLikelihoods);
}

Expand Down
79 changes: 29 additions & 50 deletions src/coreclr/jit/fgprofilesynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
m_dfsTree = m_comp->fgComputeDfs();
m_loops = FlowGraphNaturalLoops::Find(m_dfsTree);
m_improperLoopHeaders = m_loops->ImproperLoopHeaders();
m_entryBlock = m_comp->opts.IsOSR() ? m_comp->fgEntryBB : m_comp->fgFirstBB;

// Retain or compute edge likelihood information
//
Expand Down Expand Up @@ -71,13 +72,18 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
break;
}

// Save entry block's weight.
// If the entry block is a loop header, its weight will be overwritten by ComputeCyclicProbabilities.
//
weight_t entryBlockWeight = m_entryBlock->bbWeight;

// Determine cyclic probabilities
//
ComputeCyclicProbabilities();

// Assign weights to entry points in the flow graph
//
AssignInputWeights(option);
AssignInputWeights(entryBlockWeight);

// Compute the block weights given the inputs and edge likelihoods
//
Expand Down Expand Up @@ -108,12 +114,13 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
m_approximate = false;
m_overflow = false;
m_cappedCyclicProbabilities = 0;
entryBlockWeight = m_entryBlock->bbWeight;

// Regularize the edge likelihoods...
//
BlendLikelihoods();
ComputeCyclicProbabilities();
AssignInputWeights(option);
AssignInputWeights(entryBlockWeight);
ComputeBlockWeights();

// Increase blend factor and decrease synthetic loop likelihoods
Expand Down Expand Up @@ -975,7 +982,7 @@ void ProfileSynthesis::ComputeCyclicProbabilities(FlowGraphNaturalLoop* loop)
// fgAssignInputWeights: provide initial profile weights for all blocks
//
// Arguments:
// option - profile synthesis option
// entryBlockWeight - total flow (including method call count) into the entry block
//
// Notes:
// For finallys we will pick up new entry weights when we process
Expand All @@ -986,51 +993,26 @@ void ProfileSynthesis::ComputeCyclicProbabilities(FlowGraphNaturalLoop* loop)
//
// Some parts of the jit are sensitive to the absolute weights.
//
void ProfileSynthesis::AssignInputWeights(ProfileSynthesisOption option)
void ProfileSynthesis::AssignInputWeights(weight_t entryBlockWeight)
{
// Determine input weight for method entry
// Determine input weight for method entry.
// Ideally, we'd use fgCalledCount, but it may not be available yet.
//
BasicBlock* const entryBlock = m_comp->opts.IsOSR() ? m_comp->fgEntryBB : m_comp->fgFirstBB;
weight_t entryWeight = BB_UNITY_WEIGHT;
weight_t entryWeight = entryBlockWeight;
FlowGraphNaturalLoop* const loop = m_loops->GetLoopByHeader(m_entryBlock);

switch (option)
if (loop != nullptr)
{
case ProfileSynthesisOption::BlendLikelihoods:
case ProfileSynthesisOption::RepairLikelihoods:
{
// Try and retain entryBlock's weight.
// Easiest to do when the block has no preds.
//
if (entryBlock->hasProfileWeight())
{
weight_t currentEntryWeight = entryBlock->bbWeight;

if (!Compiler::fgProfileWeightsEqual(currentEntryWeight, 0.0, epsilon))
{
if (entryBlock->bbPreds == nullptr)
{
entryWeight = currentEntryWeight;
}
else
{
// TODO: something similar to how we compute fgCalledCount;
// try and sum return weights?
}
}
else
{
// Entry weight was zero or nearly zero, just use default
}
}
else
{
// Entry was unprofiled, just use default
}
break;
}
const weight_t cyclicProbability = m_cyclicProbabilities[loop->GetIndex()];
assert(cyclicProbability != BB_ZERO_WEIGHT);
entryWeight /= cyclicProbability;
}

default:
break;
// Fall back to BB_UNITY_WEIGHT if we have zero entry weight
//
if (Compiler::fgProfileWeightsEqual(entryWeight, BB_ZERO_WEIGHT, epsilon))
{
entryWeight = BB_UNITY_WEIGHT;
}

// Reset existing weights
Expand All @@ -1042,8 +1024,8 @@ void ProfileSynthesis::AssignInputWeights(ProfileSynthesisOption option)

// Set entry weight
//
JITDUMP("Synthesis: entry " FMT_BB " has input weight " FMT_WT "\n", entryBlock->bbNum, entryWeight);
entryBlock->setBBProfileWeight(entryWeight);
JITDUMP("Synthesis: entry " FMT_BB " has input weight " FMT_WT "\n", m_entryBlock->bbNum, entryWeight);
m_entryBlock->setBBProfileWeight(entryWeight);

// Determine input weight for EH regions, if any.
//
Expand Down Expand Up @@ -1210,9 +1192,6 @@ void ProfileSynthesis::GaussSeidelSolver()
bool checkEntryExitWeight = true;
bool showDetails = false;

// Remember the entry block
//
BasicBlock* const entryBlock = m_comp->opts.IsOSR() ? m_comp->fgEntryBB : m_comp->fgFirstBB;
JITDUMP("Synthesis solver: flow graph has %u improper loop headers\n", m_improperLoopHeaders);

// This is an iterative solver, and it may require a lot of iterations
Expand Down Expand Up @@ -1268,7 +1247,7 @@ void ProfileSynthesis::GaussSeidelSolver()

// Some blocks have additional profile weights that don't come from flow edges.
//
if (block == entryBlock)
if (block == m_entryBlock)
{
newWeight = block->bbWeight;
entryWeight = newWeight;
Expand Down Expand Up @@ -1459,7 +1438,7 @@ void ProfileSynthesis::GaussSeidelSolver()
if (entryExitRelResidual > relResidual)
{
relResidual = entryExitRelResidual;
relResidualBlock = entryBlock;
relResidualBlock = m_entryBlock;
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/coreclr/jit/fgprofilesynthesis.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class ProfileSynthesis
void ComputeCyclicProbabilities();
void ComputeCyclicProbabilities(FlowGraphNaturalLoop* loop);

void AssignInputWeights(ProfileSynthesisOption option);
void AssignInputWeights(weight_t entryBlockWeight);

void ComputeBlockWeights();
void ComputeBlockWeight(BasicBlock* block);
Expand All @@ -86,6 +86,7 @@ class ProfileSynthesis
Compiler* const m_comp;
FlowGraphDfsTree* m_dfsTree = nullptr;
FlowGraphNaturalLoops* m_loops = nullptr;
BasicBlock* m_entryBlock = nullptr;
weight_t* m_cyclicProbabilities = nullptr;
weight_t m_blendFactor = initialBlendFactor;
weight_t m_loopExitLikelihood = loopExitLikelihood;
Expand Down
Loading