Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
17 changes: 12 additions & 5 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4657,11 +4657,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
//
DoPhase(this, PHASE_CLONE_FINALLY, &Compiler::fgCloneFinally);

// Drop back to just checking profile likelihoods.
//
activePhaseChecks &= ~PhaseChecks::CHECK_PROFILE;
activePhaseChecks |= PhaseChecks::CHECK_LIKELIHOODS;

// Do some flow-related optimizations
//
if (opts.OptimizationEnabled())
Expand All @@ -4672,6 +4667,11 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
return fgHeadTailMerge(true);
});

// Drop back to just checking profile likelihoods.
//
activePhaseChecks &= ~PhaseChecks::CHECK_PROFILE;
activePhaseChecks |= PhaseChecks::CHECK_LIKELIHOODS;

// Merge common throw blocks
//
DoPhase(this, PHASE_MERGE_THROWS, &Compiler::fgTailMergeThrows);
Expand All @@ -4680,6 +4680,13 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
//
DoPhase(this, PHASE_EARLY_UPDATE_FLOW_GRAPH, &Compiler::fgUpdateFlowGraphPhase);
}
else
{
// Drop back to just checking profile likelihoods.
//
activePhaseChecks &= ~PhaseChecks::CHECK_PROFILE;
activePhaseChecks |= PhaseChecks::CHECK_LIKELIHOODS;
}

// Promote struct locals
//
Expand Down
12 changes: 12 additions & 0 deletions src/coreclr/jit/fgehopt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2437,7 +2437,19 @@ PhaseStatus Compiler::fgTailMergeThrows()
case BBJ_SWITCH:
{
JITDUMP("*** " FMT_BB " now branching to " FMT_BB "\n", predBlock->bbNum, canonicalBlock->bbNum);
FlowEdge* prevEdge = fgGetPredForBlock(nonCanonicalBlock, predBlock);
weight_t removedWeight = predBlock->bbWeight * prevEdge->getLikelihood();
fgReplaceJumpTarget(predBlock, nonCanonicalBlock, canonicalBlock);

// In practice, when we have true profile data, we can repair it locally here, since the no-return
// call means that there is no contribution from nonCanonicalBlock to any of its successors.
// Note that this might not be the case if we have profile data from e.g. synthesis, so this
// repair is best-effort only.
canonicalBlock->bbWeight += removedWeight;
Copy link
Contributor

Choose a reason for hiding this comment

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

I should probably add a helper for this, but the pattern we've been following for propagating profile data is like so:

if (canonicalBlock->hasProfileWeight())
{
    canonicalBlock->setBBProfileWeight(canonicalBlock->bbWeight + removedWeight);
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Updated to follow this pattern. Hopefully at some point hasProfileWeight will be always true and we can get rid of those checks.

Copy link
Contributor

Choose a reason for hiding this comment

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

The block weight solver @AndyAyersMS implemented propagates the BBF_PROF_WEIGHT flag to all blocks reachable via normal flow here, so if we start using it relatively early on -- such as a replacement for the current fgComputeBlockWeights and optSetBlockWeights phases -- I imagine we can begin requiring blocks to have profile-derived weights at most flow modification sites.

if (canonicalBlock->bbWeight > BB_ZERO_WEIGHT)
{
canonicalBlock->RemoveFlags(BBF_RUN_RARELY);
}
updated = true;
}
break;
Expand Down
8 changes: 8 additions & 0 deletions src/coreclr/jit/fgopt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6576,6 +6576,14 @@ PhaseStatus Compiler::fgHeadTailMerge(bool early)
FlowEdge* const newEdge = fgAddRefPred(crossJumpTarget, predBlock);
predBlock->SetKindAndTargetEdge(BBJ_ALWAYS, newEdge);
}

// For tail merge we have a common successor of predBlock and
// crossJumpTarget, so the profile update can be done locally.
crossJumpTarget->bbWeight += predBlock->bbWeight;
if (crossJumpTarget->bbWeight > BB_ZERO_WEIGHT)
{
crossJumpTarget->RemoveFlags(BBF_RUN_RARELY);
}
}

// We changed things
Expand Down
Loading