forked from OSchip/llvm-project
[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:
parent
8cd1ba599b
commit
615a318b60
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue