forked from OSchip/llvm-project
Report stale sample count and percentage
Summary: This diff adds extra reporting of total number of stale branch samples for the binary. (cherry picked from FBD22304965)
This commit is contained in:
parent
3e795c8a5f
commit
f40ffa0dc8
|
@ -340,6 +340,9 @@ private:
|
|||
/// Profile match ratio.
|
||||
float ProfileMatchRatio{0.0f};
|
||||
|
||||
/// Raw branch count for this function in the profile
|
||||
uint64_t RawBranchCount{0};
|
||||
|
||||
/// Indicates the type of profile the function is using.
|
||||
uint16_t ProfileFlags{PF_NONE};
|
||||
|
||||
|
@ -1956,6 +1959,10 @@ public:
|
|||
return ExecutionCount;
|
||||
}
|
||||
|
||||
/// Return the raw profile information about the number of branch
|
||||
/// executions corresponding to this function.
|
||||
uint64_t getRawBranchCount() const { return RawBranchCount; }
|
||||
|
||||
/// Return the execution count for functions with known profile.
|
||||
/// Return 0 if the function has no profile.
|
||||
uint64_t getKnownExecutionCount() const {
|
||||
|
|
|
@ -119,6 +119,16 @@ void FuncBranchData::appendFrom(const FuncBranchData &FBD, uint64_t Offset) {
|
|||
}
|
||||
}
|
||||
|
||||
uint64_t FuncBranchData::getNumExecutedBranches() const {
|
||||
uint64_t ExecutedBranches{0};
|
||||
for (const auto &BI : Data) {
|
||||
auto BranchCount = BI.Branches;
|
||||
assert(BranchCount >= 0 && "branch execution count should not be negative");
|
||||
ExecutedBranches += BranchCount;
|
||||
}
|
||||
return ExecutedBranches;
|
||||
}
|
||||
|
||||
void SampleInfo::mergeWith(const SampleInfo &SI) {
|
||||
Hits += SI.Hits;
|
||||
}
|
||||
|
@ -437,10 +447,12 @@ void DataReader::matchProfileData(BinaryFunction &BF) {
|
|||
FuncBranchData *FBD = getBranchData(BF);
|
||||
if (FBD) {
|
||||
BF.ProfileMatchRatio = evaluateProfileData(BF, *FBD);
|
||||
BF.RawBranchCount = FBD->getNumExecutedBranches();
|
||||
if (BF.ProfileMatchRatio == 1.0f) {
|
||||
if (fetchProfileForOtherEntryPoints(BF)) {
|
||||
BF.ProfileMatchRatio = evaluateProfileData(BF, *FBD);
|
||||
BF.ExecutionCount = FBD->ExecutionCount;
|
||||
BF.RawBranchCount = FBD->getNumExecutedBranches();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -147,6 +147,10 @@ struct FuncBranchData {
|
|||
/// from the entry of this function.
|
||||
void appendFrom(const FuncBranchData &FBD, uint64_t Offset);
|
||||
|
||||
/// Returns the total number of executed branches in this function
|
||||
/// by counting the number of executed branches for each BranchInfo
|
||||
uint64_t getNumExecutedBranches() const;
|
||||
|
||||
/// Aggregation helpers
|
||||
DenseMap<uint64_t, DenseMap<uint64_t, size_t>> IntraIndex;
|
||||
DenseMap<uint64_t, DenseMap<Location, size_t>> InterIndex;
|
||||
|
|
|
@ -1259,6 +1259,8 @@ PrintProgramStats::runOnFunctions(BinaryContext &BC) {
|
|||
uint64_t NumStaleProfileFunctions{0};
|
||||
uint64_t NumNonSimpleProfiledFunctions{0};
|
||||
uint64_t NumUnknownControlFlowFunctions{0};
|
||||
uint64_t TotalSampleCount{0};
|
||||
uint64_t StaleSampleCount{0};
|
||||
std::vector<BinaryFunction *> ProfiledFunctions;
|
||||
const char *StaleFuncsHeader = "BOLT-INFO: Functions with stale profile:\n";
|
||||
for (auto &BFI : BC.getBinaryFunctions()) {
|
||||
|
@ -1289,6 +1291,9 @@ PrintProgramStats::runOnFunctions(BinaryContext &BC) {
|
|||
if (!Function.hasProfile())
|
||||
continue;
|
||||
|
||||
auto SampleCount = Function.getRawBranchCount();
|
||||
TotalSampleCount += SampleCount;
|
||||
|
||||
if (Function.hasValidProfile()) {
|
||||
ProfiledFunctions.push_back(&Function);
|
||||
} else {
|
||||
|
@ -1298,6 +1303,7 @@ PrintProgramStats::runOnFunctions(BinaryContext &BC) {
|
|||
outs() << " " << Function << '\n';
|
||||
}
|
||||
++NumStaleProfileFunctions;
|
||||
StaleSampleCount += SampleCount;
|
||||
}
|
||||
}
|
||||
BC.NumProfiledFuncs = ProfiledFunctions.size();
|
||||
|
@ -1317,16 +1323,27 @@ PrintProgramStats::runOnFunctions(BinaryContext &BC) {
|
|||
if (NumStaleProfileFunctions) {
|
||||
const float PctStale =
|
||||
NumStaleProfileFunctions / (float) NumAllProfiledFunctions * 100.0f;
|
||||
if (PctStale > opts::StaleThreshold) {
|
||||
errs() << "BOLT-ERROR: ";
|
||||
} else {
|
||||
errs() << "BOLT-WARNING: ";
|
||||
}
|
||||
auto printErrorOrWarning = [&]() {
|
||||
if (PctStale > opts::StaleThreshold) {
|
||||
errs() << "BOLT-ERROR: ";
|
||||
} else {
|
||||
errs() << "BOLT-WARNING: ";
|
||||
}
|
||||
};
|
||||
printErrorOrWarning();
|
||||
errs() << NumStaleProfileFunctions
|
||||
<< format(" (%.1f%% of all profiled)", PctStale)
|
||||
<< " function" << (NumStaleProfileFunctions == 1 ? "" : "s")
|
||||
<< " have invalid (possibly stale) profile."
|
||||
" Use -report-stale to see the list.\n";
|
||||
if (TotalSampleCount > 0) {
|
||||
printErrorOrWarning();
|
||||
errs() << StaleSampleCount << " out of " << TotalSampleCount
|
||||
<< " samples in the binary ("
|
||||
<< format("%.1f", ((100.0f * StaleSampleCount) / TotalSampleCount))
|
||||
<< "%) belong to functions with invalid"
|
||||
" (possibly stale) profile.\n";
|
||||
}
|
||||
if (PctStale > opts::StaleThreshold) {
|
||||
errs() << "BOLT-ERROR: stale functions exceed specified threshold of "
|
||||
<< opts::StaleThreshold << "%. Exiting.\n";
|
||||
|
|
Loading…
Reference in New Issue