Skip to content
30 changes: 2 additions & 28 deletions src/coreclr/jit/fgprofile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4787,20 +4787,12 @@ bool Compiler::fgDebugCheckIncomingProfileData(BasicBlock* block, ProfileChecks
weight_t incomingLikelyWeight = 0;
unsigned missingLikelyWeight = 0;
bool foundPreds = false;
bool foundEHPreds = false;

for (FlowEdge* const predEdge : block->PredEdges())
{
if (predEdge->hasLikelihood())
{
if (BasicBlock::sameHndRegion(block, predEdge->getSourceBlock()))
{
incomingLikelyWeight += predEdge->getLikelyWeight();
}
else
{
foundEHPreds = true;
}
incomingLikelyWeight += predEdge->getLikelyWeight();
}
else
{
Expand All @@ -4812,29 +4804,11 @@ bool Compiler::fgDebugCheckIncomingProfileData(BasicBlock* block, ProfileChecks
foundPreds = true;
}

// We almost certainly won't get the likelihoods on a BBJ_EHFINALLYRET right,
// so special-case BBJ_CALLFINALLYRET incoming flow.
//
if (block->isBBCallFinallyPairTail())
{
incomingLikelyWeight = block->Prev()->bbWeight;
foundEHPreds = false;
}

// We almost certainly won't get the likelihoods on a BBJ_EHFINALLYRET right,
// so special-case BBJ_CALLFINALLYRET incoming flow.
//
if (block->isBBCallFinallyPairTail())
{
incomingLikelyWeight = block->Prev()->bbWeight;
foundEHPreds = false;
}

bool likelyWeightsValid = true;

// If we have EH preds we may not have consistent incoming flow.
//
if (foundPreds && !foundEHPreds)
if (foundPreds)
{
if (verifyLikelyWeights)
{
Expand Down
47 changes: 20 additions & 27 deletions src/coreclr/jit/fgprofilesynthesis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
assert(m_loops != nullptr);
}

if (m_loops->NumLoops() > 0)
{
m_cyclicProbabilities = new (m_comp, CMK_Pgo) weight_t[m_loops->NumLoops()];
}

// Profile synthesis can be run before or after morph, so tolerate (non-)canonical method entries
//
m_entryBlock = (m_comp->opts.IsOSR() && (m_comp->fgEntryBB != nullptr)) ? m_comp->fgEntryBB : m_comp->fgFirstBB;
Expand Down Expand Up @@ -168,7 +173,10 @@ void ProfileSynthesis::Run(ProfileSynthesisOption option)
if (m_approximate)
{
JITDUMP("Profile is inconsistent. Bypassing post-phase consistency checks.\n");
m_comp->Metrics.ProfileInconsistentInitially++;
if (!m_comp->fgImportDone)
{
m_comp->Metrics.ProfileInconsistentInitially++;
}
}

// Derive the method's call count from the entry block's weight
Expand Down Expand Up @@ -745,13 +753,6 @@ void ProfileSynthesis::RandomizeLikelihoods()
//
void ProfileSynthesis::ComputeCyclicProbabilities()
{
m_cyclicProbabilities = nullptr;
if (m_loops->NumLoops() == 0)
{
return;
}

m_cyclicProbabilities = new (m_comp, CMK_Pgo) weight_t[m_loops->NumLoops()];
// Walk loops in post order to visit inner loops before outer loops.
for (FlowGraphNaturalLoop* loop : m_loops->InPostOrder())
{
Expand Down Expand Up @@ -828,10 +829,7 @@ void ProfileSynthesis::ComputeCyclicProbabilities(FlowGraphNaturalLoop* loop)

for (FlowEdge* const edge : nestedLoop->EntryEdges())
{
if (BasicBlock::sameHndRegion(block, edge->getSourceBlock()))
{
newWeight += edge->getLikelyWeight();
}
newWeight += edge->getLikelyWeight();
}

newWeight *= m_cyclicProbabilities[nestedLoop->GetIndex()];
Expand All @@ -847,10 +845,10 @@ void ProfileSynthesis::ComputeCyclicProbabilities(FlowGraphNaturalLoop* loop)
{
BasicBlock* const sourceBlock = edge->getSourceBlock();

// Ignore flow across EH, or from preds not in the loop.
// Latter can happen if there are unreachable blocks that flow into the loop.
// Ignore flow from preds not in the loop.
// This can happen if there are unreachable blocks that flow into the loop.
//
if (BasicBlock::sameHndRegion(block, sourceBlock) && loop->ContainsBlock(sourceBlock))
if (loop->ContainsBlock(sourceBlock))
{
newWeight += edge->getLikelyWeight();
}
Expand Down Expand Up @@ -1214,7 +1212,8 @@ void ProfileSynthesis::GaussSeidelSolver()
const FlowGraphDfsTree* const dfs = m_loops->GetDfsTree();
unsigned const blockCount = dfs->GetPostOrderCount();
bool checkEntryExitWeight = true;
bool showDetails = false;
bool const showDetails = false;
bool const callFinalliesCreated = m_comp->fgImportDone;

JITDUMP("Synthesis solver: flow graph has %u improper loop headers\n", m_improperLoopHeaders);

Expand Down Expand Up @@ -1290,9 +1289,10 @@ void ProfileSynthesis::GaussSeidelSolver()
{
newWeight = block->bbWeight;

// Finallies also add in the weight of their try.
// If we haven't added flow edges into/out of finallies yet,
// add in the weight of their corresponding try regions.
//
if (ehDsc->HasFinallyHandler())
if (!callFinalliesCreated && ehDsc->HasFinallyHandler())
{
newWeight += countVector[ehDsc->ebdTryBeg->bbNum];
}
Expand All @@ -1318,11 +1318,7 @@ void ProfileSynthesis::GaussSeidelSolver()
for (FlowEdge* const edge : loop->EntryEdges())
{
BasicBlock* const predBlock = edge->getSourceBlock();

if (BasicBlock::sameHndRegion(block, predBlock))
{
newWeight += edge->getLikelihood() * countVector[predBlock->bbNum];
}
newWeight += edge->getLikelihood() * countVector[predBlock->bbNum];
}

// Scale by cyclic probability
Expand Down Expand Up @@ -1354,10 +1350,7 @@ void ProfileSynthesis::GaussSeidelSolver()
continue;
}

if (BasicBlock::sameHndRegion(block, predBlock))
{
newWeight += edge->getLikelihood() * countVector[predBlock->bbNum];
}
newWeight += edge->getLikelihood() * countVector[predBlock->bbNum];
}

if (selfEdge != nullptr)
Expand Down
20 changes: 20 additions & 0 deletions src/coreclr/jit/importer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12656,6 +12656,26 @@ void Compiler::impFixPredLists()
}

finallyBlock->SetEhfTargets(jumpEhf);

if (finallyBlock->hasProfileWeight())
{
bool profileConsistent = false;
for (BasicBlock* const succBlock : finallyBlock->Succs())
{
const weight_t oldWeight = succBlock->bbWeight;
const weight_t newWeight = succBlock->computeIncomingWeight();
succBlock->setBBProfileWeight(newWeight);
profileConsistent &= fgProfileWeightsEqual(oldWeight, newWeight);
}

if (!profileConsistent)
{
JITDUMP("Flow propagation out of " FMT_BB
" might have introduced inconsistency. Data %s inconsistent.\n",
finallyBlock->bbNum, fgPgoConsistent ? "is now" : "was already");
fgPgoConsistent = false;
}
}
}
}
}
Expand Down
Loading