Skip to content

Commit e0e8078

Browse files
authored
JIT: treat synthesized profile data as pgo data, fix finally weights (#83185)
Once synthesis arrives on the scene, we're not going to want phases in the JIT to arbitrarily modifying block weights. There is already a guard of this sort for regular profile data, so it makes sense to extend that to synthesized data as well. When synthesizing counts, propagate counts to finallies from the associated trys. This needs to be done carefully as we have make sure not to visit the finally until the count in the try is set. We rely on some of the properties of DFS pre and post number bracketing to do this efficiently, without needing to track extra state. Contributes to #82964.
1 parent 434d664 commit e0e8078

File tree

8 files changed

+172
-118
lines changed

8 files changed

+172
-118
lines changed

src/coreclr/inc/corjit.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,8 @@ class ICorJitInfo : public ICorDynamicInfo
419419
Blend = 3, // PGO data comes from blend of prior runs and current run
420420
Text = 4, // PGO data comes from text file
421421
IBC = 5, // PGO data from classic IBC
422-
Sampling= 6, // PGO data derived from sampling
422+
Sampling = 6, // PGO data derived from sampling
423+
Synthesis = 7, // PGO data derived from synthesis
423424
};
424425

425426
#define DEFAULT_UNKNOWN_HANDLE 1

src/coreclr/jit/codegencommon.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,9 +1835,9 @@ void CodeGen::genGenerateMachineCode()
18351835
{
18361836
printf("; instrumented for collecting profile data\n");
18371837
}
1838-
else if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT) && compiler->fgHaveProfileData())
1838+
else if (compiler->opts.jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT) && compiler->fgHaveProfileWeights())
18391839
{
1840-
printf("; optimized using profile data\n");
1840+
printf("; optimized using %s\n", compiler->compGetPgoSourceName());
18411841
}
18421842

18431843
#if DOUBLE_ALIGN
@@ -1856,7 +1856,7 @@ void CodeGen::genGenerateMachineCode()
18561856
printf("; partially interruptible\n");
18571857
}
18581858

1859-
if (compiler->fgHaveProfileData())
1859+
if (compiler->fgHaveProfileWeights())
18601860
{
18611861
printf("; with %s: edge weights are %s, and fgCalledCount is " FMT_WT "\n",
18621862
compiler->compGetPgoSourceName(), compiler->fgHaveValidEdgeWeights ? "valid" : "invalid",

src/coreclr/jit/compiler.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3343,14 +3343,9 @@ void Compiler::compInitOptions(JitFlags* jitFlags)
33433343
printf("OPTIONS: compProcedureSplitting = %s\n", dspBool(opts.compProcedureSplitting));
33443344
printf("OPTIONS: compProcedureSplittingEH = %s\n", dspBool(opts.compProcedureSplittingEH));
33453345

3346-
if (jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT) && fgHaveProfileData())
3346+
if (jitFlags->IsSet(JitFlags::JIT_FLAG_BBOPT))
33473347
{
3348-
printf("OPTIONS: optimized using %s profile data\n", pgoSourceToString(fgPgoSource));
3349-
}
3350-
3351-
if (fgPgoFailReason != nullptr)
3352-
{
3353-
printf("OPTIONS: %s\n", fgPgoFailReason);
3348+
printf("OPTIONS: optimizer should use profile data\n");
33543349
}
33553350

33563351
if (jitFlags->IsSet(JitFlags::JIT_FLAG_PREJIT))
@@ -4266,13 +4261,17 @@ const char* Compiler::compGetPgoSourceName() const
42664261
case ICorJitInfo::PgoSource::Dynamic:
42674262
return "Dynamic PGO";
42684263
case ICorJitInfo::PgoSource::Blend:
4269-
return "Blend PGO";
4264+
return "Blended PGO";
42704265
case ICorJitInfo::PgoSource::Text:
42714266
return "Textual PGO";
42724267
case ICorJitInfo::PgoSource::Sampling:
42734268
return "Sample-based PGO";
4269+
case ICorJitInfo::PgoSource::IBC:
4270+
return "Classic IBC";
4271+
case ICorJitInfo::PgoSource::Synthesis:
4272+
return "Synthesized PGO";
42744273
default:
4275-
return "";
4274+
return "Unknown PGO";
42764275
}
42774276
}
42784277

src/coreclr/jit/compiler.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9745,7 +9745,6 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
97459745
}
97469746
}
97479747

9748-
const char* pgoSourceToString(ICorJitInfo::PgoSource p);
97499748
const char* devirtualizationDetailToString(CORINFO_DEVIRTUALIZATION_DETAIL detail);
97509749

97519750
#endif // DEBUG

src/coreclr/jit/fgbasic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3925,7 +3925,7 @@ void Compiler::fgCheckForLoopsInHandlers()
39253925
return;
39263926
}
39273927

3928-
// Walk blocks in handlers and filters, looing for a backedge target.
3928+
// Walk blocks in handlers and filters, looking for a backedge target.
39293929
//
39303930
assert(!compHasBackwardJumpInHandler);
39313931
for (BasicBlock* const blk : Blocks())

src/coreclr/jit/fgprofile.cpp

Lines changed: 43 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,6 @@ bool Compiler::fgHaveProfileData()
5454
//
5555
bool Compiler::fgHaveProfileWeights()
5656
{
57-
if (!fgHaveProfileData())
58-
{
59-
return false;
60-
}
61-
6257
return fgPgoHaveWeights;
6358
}
6459

@@ -79,12 +74,29 @@ bool Compiler::fgHaveSufficientProfileWeights()
7974
return false;
8075
}
8176

82-
if ((fgFirstBB != nullptr) && (fgPgoSource == ICorJitInfo::PgoSource::Static))
77+
switch (fgPgoSource)
8378
{
84-
const weight_t sufficientSamples = 1000;
85-
return fgFirstBB->bbWeight > sufficientSamples;
79+
case ICorJitInfo::PgoSource::Dynamic:
80+
case ICorJitInfo::PgoSource::Text:
81+
return true;
82+
83+
case ICorJitInfo::PgoSource::Static:
84+
case ICorJitInfo::PgoSource::Blend:
85+
{
86+
// We sometimes call this very early, eg evaluating the prejit root.
87+
//
88+
if (fgFirstBB != nullptr)
89+
{
90+
const weight_t sufficientSamples = 1000;
91+
return fgFirstBB->bbWeight > sufficientSamples;
92+
}
93+
94+
return true;
95+
}
96+
97+
default:
98+
return false;
8699
}
87-
return true;
88100
}
89101

90102
//------------------------------------------------------------------------
@@ -2493,7 +2505,6 @@ PhaseStatus Compiler::fgIncorporateProfileData()
24932505
{
24942506
JITDUMP("Synthesizing profile data and writing it out as the actual profile data\n");
24952507
ProfileSynthesis::Run(this, ProfileSynthesisOption::AssignLikelihoods);
2496-
fgPgoHaveWeights = false;
24972508
return PhaseStatus::MODIFIED_EVERYTHING;
24982509
}
24992510
#endif
@@ -2522,8 +2533,8 @@ PhaseStatus Compiler::fgIncorporateProfileData()
25222533

25232534
// Summarize profile data
25242535
//
2525-
JITDUMP("Have %s profile data: %d schema records (schema at %p, data at %p)\n", pgoSourceToString(fgPgoSource),
2526-
fgPgoSchemaCount, dspPtr(fgPgoSchema), dspPtr(fgPgoData));
2536+
JITDUMP("Have %s: %d schema records (schema at %p, data at %p)\n", compGetPgoSourceName(), fgPgoSchemaCount,
2537+
dspPtr(fgPgoSchema), dspPtr(fgPgoData));
25272538

25282539
fgNumProfileRuns = 0;
25292540
unsigned otherRecords = 0;
@@ -3431,15 +3442,29 @@ void EfficientEdgeCountReconstructor::Propagate()
34313442
//
34323443
if (m_badcode || m_mismatch || m_failedToConverge || m_allWeightsZero)
34333444
{
3434-
JITDUMP("... discarding profile data because of %s\n",
3435-
m_badcode ? "badcode" : m_mismatch ? "mismatch" : m_allWeightsZero ? "zero counts"
3436-
: "failed to converge");
3437-
34383445
// Make sure nothing else in the jit looks at the profile data.
34393446
//
3440-
m_comp->fgPgoSchema = nullptr;
3441-
m_comp->fgPgoFailReason = "PGO data available, but there was a reconstruction problem";
3447+
m_comp->fgPgoHaveWeights = false;
3448+
m_comp->fgPgoSchema = nullptr;
3449+
3450+
if (m_badcode)
3451+
{
3452+
m_comp->fgPgoFailReason = "PGO data available, but IL was malformed";
3453+
}
3454+
else if (m_mismatch)
3455+
{
3456+
m_comp->fgPgoFailReason = "PGO data available, but IL did not match";
3457+
}
3458+
else if (m_failedToConverge)
3459+
{
3460+
m_comp->fgPgoFailReason = "PGO data available, but solver did not converge";
3461+
}
3462+
else
3463+
{
3464+
m_comp->fgPgoFailReason = "PGO data available, profile data was all zero";
3465+
}
34423466

3467+
JITDUMP("... discarding profile data: %s\n", m_comp->fgPgoFailReason);
34433468
return;
34443469
}
34453470

@@ -5333,43 +5358,4 @@ bool Compiler::fgDebugCheckOutgoingProfileData(BasicBlock* block, ProfileChecks
53335358
return classicWeightsValid && likelyWeightsValid;
53345359
}
53355360

5336-
//------------------------------------------------------------------------------
5337-
// pgoSourceToString: describe source of pgo data
5338-
//
5339-
// Arguments:
5340-
// r - source enum to describe
5341-
//
5342-
// Returns:
5343-
// descriptive string
5344-
//
5345-
const char* Compiler::pgoSourceToString(ICorJitInfo::PgoSource p)
5346-
{
5347-
const char* pgoSource = "unknown";
5348-
switch (fgPgoSource)
5349-
{
5350-
case ICorJitInfo::PgoSource::Dynamic:
5351-
pgoSource = "dynamic";
5352-
break;
5353-
case ICorJitInfo::PgoSource::Static:
5354-
pgoSource = "static";
5355-
break;
5356-
case ICorJitInfo::PgoSource::Text:
5357-
pgoSource = "text";
5358-
break;
5359-
case ICorJitInfo::PgoSource::Blend:
5360-
pgoSource = "static+dynamic";
5361-
break;
5362-
case ICorJitInfo::PgoSource::IBC:
5363-
pgoSource = "IBC";
5364-
break;
5365-
case ICorJitInfo::PgoSource::Sampling:
5366-
pgoSource = "Sampling";
5367-
break;
5368-
default:
5369-
break;
5370-
}
5371-
5372-
return pgoSource;
5373-
}
5374-
53755361
#endif // DEBUG

0 commit comments

Comments
 (0)