[BOLT] Filter perf samples by PID

Summary: `perf2bolt` accepts executable name, and the tool will find all the PIDs associated with that executable. When different versions of an executable are running at the same time, name alone may not be sufficient as we will get samples from different versions of the binary aggregated together. The resulting fdata may look stale to BOLT, which makes BOLT bailout optimization for functions. This change adds a `-pid` switch that lets user specify process ID in addition to executable name so BOLT can target a specific process.

(cherry picked from FBD17178898)
This commit is contained in:
Wenlei He 2019-09-03 22:24:06 -07:00 committed by Maksim Panchenko
parent 8cd1ba599b
commit 615a318b60
3 changed files with 37 additions and 2 deletions

View File

@ -117,6 +117,13 @@ IgnoreInterruptLBR("ignore-interrupt-lbr",
cl::ZeroOrMore,
cl::cat(AggregatorCategory));
static cl::opt<unsigned long long>
FilterPID("pid",
cl::desc("Only use samples from process with specified PID"),
cl::init(0),
cl::Optional,
cl::cat(AggregatorCategory));
}
namespace {
@ -450,6 +457,30 @@ std::error_code DataAggregator::writeAutoFDOData() {
return std::error_code();
}
void DataAggregator::filterBinaryMMapInfo() {
if (opts::FilterPID) {
auto MMapInfoIter = BinaryMMapInfo.find(opts::FilterPID);
if (MMapInfoIter != BinaryMMapInfo.end()) {
auto MMap = MMapInfoIter->second;
BinaryMMapInfo.clear();
BinaryMMapInfo.insert(std::make_pair(MMap.PID, MMap));
} else {
if (errs().has_colors())
errs().changeColor(raw_ostream::RED);
errs() << "PERF2BOLT-ERROR: could not find a profile matching PID \""
<< opts::FilterPID << "\"" << " for binary \"" << BinaryName <<"\".";
assert(!BinaryMMapInfo.empty() && "No memory map for matching binary");
errs() << " Profile for the following process is available:\n";
for (auto &MMI : BinaryMMapInfo)
outs() << " " << MMI.second.PID << (MMI.second.Forked ? " (forked)\n" : "\n");
if (errs().has_colors())
errs().resetColor();
exit(1);
}
}
}
void DataAggregator::parseProfile(BinaryContext &BC) {
this->BC = &BC;
@ -506,6 +537,7 @@ void DataAggregator::parseProfile(BinaryContext &BC) {
errs() << "PERF2BOLT: failed to parse task events\n";
}
filterBinaryMMapInfo();
prepareToParse("events", MainEventsPPI);
if (opts::HeatmapMode) {

View File

@ -427,6 +427,9 @@ public:
/// Dump data structures into a file readable by llvm-bolt
std::error_code writeAggregatedFile() const;
/// Filter out binaries based on PID
void filterBinaryMMapInfo();
/// Parse profile and mark functions/objects with profile.
/// Don't assign profile to functions yet.
void parseProfile(BinaryContext &BC);

View File

@ -5005,9 +5005,9 @@ void RewriteInstance::rewriteFile() {
<< " functions were overwritten.\n";
if (BC->TotalScore != 0) {
double Coverage = OverwrittenScore / (double) BC->TotalScore * 100.0;
outs() << format("BOLT: Rewritten functions cover %.2lf", Coverage)
outs() << format("BOLT-INFO: rewritten functions cover %.2lf", Coverage)
<< "% of the execution count of simple functions of "
"this binary.\n";
"this binary\n";
}
}