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:
Tanvir Ahmed Khan 2020-07-06 21:35:44 -07:00 committed by Maksim Panchenko
parent 3e795c8a5f
commit f40ffa0dc8
4 changed files with 45 additions and 5 deletions

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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";