summaryrefslogtreecommitdiff
path: root/bolt
diff options
context:
space:
mode:
authorAmir Ayupov <aaupov@fb.com>2023-03-15 12:54:41 -0700
committerAmir Ayupov <aaupov@fb.com>2023-03-15 12:56:06 -0700
commitc7af4f383df644efa3de28d8fdb751d4d2c3747e (patch)
tree1ea8c49a1d3031db01e847e89108481ab95113f2 /bolt
parentb60de1dfcc15d9505de958fe160b45bea11286f2 (diff)
downloadllvm-c7af4f383df644efa3de28d8fdb751d4d2c3747e.tar.gz
[BOLT][NFC] Simplify preprocessProfile
Move out prepareToParse lambda, generalize it to handle mem events perf process. Reviewed By: #bolt, rafauler Differential Revision: https://reviews.llvm.org/D146002
Diffstat (limited to 'bolt')
-rw-r--r--bolt/include/bolt/Profile/DataAggregator.h6
-rw-r--r--bolt/lib/Profile/DataAggregator.cpp120
2 files changed, 58 insertions, 68 deletions
diff --git a/bolt/include/bolt/Profile/DataAggregator.h b/bolt/include/bolt/Profile/DataAggregator.h
index 7f96f4fa732a..45b652c8a370 100644
--- a/bolt/include/bolt/Profile/DataAggregator.h
+++ b/bolt/include/bolt/Profile/DataAggregator.h
@@ -315,6 +315,12 @@ private:
/// consume it (peek only).
bool checkNewLine();
+ using PerfProcessErrorCallbackTy = std::function<void(int, StringRef)>;
+ /// Prepare to parse data from a given perf script invocation.
+ /// Returns an invocation exit code.
+ int prepareToParse(StringRef Name, PerfProcessInfo &Process,
+ PerfProcessErrorCallbackTy Callback);
+
/// Parse a single LBR entry as output by perf script -Fbrstack
ErrorOr<LBREntry> parseLBREntry();
diff --git a/bolt/lib/Profile/DataAggregator.cpp b/bolt/lib/Profile/DataAggregator.cpp
index c0f4ce258079..7d72c3b0e372 100644
--- a/bolt/lib/Profile/DataAggregator.cpp
+++ b/bolt/lib/Profile/DataAggregator.cpp
@@ -467,6 +467,45 @@ void DataAggregator::filterBinaryMMapInfo() {
}
}
+int DataAggregator::prepareToParse(StringRef Name, PerfProcessInfo &Process,
+ PerfProcessErrorCallbackTy Callback) {
+ std::string Error;
+ outs() << "PERF2BOLT: waiting for perf " << Name
+ << " collection to finish...\n";
+ sys::ProcessInfo PI = sys::Wait(Process.PI, std::nullopt, &Error);
+
+ if (!Error.empty()) {
+ errs() << "PERF-ERROR: " << PerfPath << ": " << Error << "\n";
+ deleteTempFiles();
+ exit(1);
+ }
+
+ if (PI.ReturnCode != 0) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorMB =
+ MemoryBuffer::getFileOrSTDIN(Process.StderrPath.data());
+ StringRef ErrBuf = (*ErrorMB)->getBuffer();
+
+ deleteTempFiles();
+ Callback(PI.ReturnCode, ErrBuf);
+ return PI.ReturnCode;
+ }
+
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
+ MemoryBuffer::getFileOrSTDIN(Process.StdoutPath.data());
+ if (std::error_code EC = MB.getError()) {
+ errs() << "Cannot open " << Process.StdoutPath.data() << ": "
+ << EC.message() << "\n";
+ deleteTempFiles();
+ exit(1);
+ }
+
+ FileBuf = std::move(*MB);
+ ParsingBuf = FileBuf->getBuffer();
+ Col = 0;
+ Line = 1;
+ return PI.ReturnCode;
+}
+
Error DataAggregator::preprocessProfile(BinaryContext &BC) {
this->BC = &BC;
@@ -483,42 +522,16 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
"not read one from input binary\n";
}
- auto prepareToParse = [&](StringRef Name, PerfProcessInfo &Process) {
- std::string Error;
- outs() << "PERF2BOLT: waiting for perf " << Name
- << " collection to finish...\n";
- sys::ProcessInfo PI = sys::Wait(Process.PI, std::nullopt, &Error);
-
- if (!Error.empty()) {
- errs() << "PERF-ERROR: " << PerfPath << ": " << Error << "\n";
- deleteTempFiles();
- exit(1);
- }
-
- if (PI.ReturnCode != 0) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> ErrorMB =
- MemoryBuffer::getFileOrSTDIN(Process.StderrPath.data());
- StringRef ErrBuf = (*ErrorMB)->getBuffer();
-
- errs() << "PERF-ERROR: return code " << PI.ReturnCode << "\n";
- errs() << ErrBuf;
- deleteTempFiles();
- exit(1);
- }
-
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
- MemoryBuffer::getFileOrSTDIN(Process.StdoutPath.data());
- if (std::error_code EC = MB.getError()) {
- errs() << "Cannot open " << Process.StdoutPath.data() << ": "
- << EC.message() << "\n";
- deleteTempFiles();
- exit(1);
- }
+ auto ErrorCallback = [](int ReturnCode, StringRef ErrBuf) {
+ errs() << "PERF-ERROR: return code " << ReturnCode << "\n" << ErrBuf;
+ exit(1);
+ };
- FileBuf = std::move(*MB);
- ParsingBuf = FileBuf->getBuffer();
- Col = 0;
- Line = 1;
+ auto MemEventsErrorCallback = [&](int ReturnCode, StringRef ErrBuf) {
+ Regex NoData("Samples for '.*' event do not have ADDR attribute set. "
+ "Cannot print 'addr' field.");
+ if (!NoData.match(ErrBuf))
+ ErrorCallback(ReturnCode, ErrBuf);
};
if (opts::LinuxKernelMode) {
@@ -537,17 +550,17 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
// in Linux kernel mode.
opts::IgnoreInterruptLBR = false;
} else {
- prepareToParse("mmap events", MMapEventsPPI);
+ prepareToParse("mmap events", MMapEventsPPI, ErrorCallback);
if (parseMMapEvents())
errs() << "PERF2BOLT: failed to parse mmap events\n";
}
- prepareToParse("task events", TaskEventsPPI);
+ prepareToParse("task events", TaskEventsPPI, ErrorCallback);
if (parseTaskEvents())
errs() << "PERF2BOLT: failed to parse task events\n";
filterBinaryMMapInfo();
- prepareToParse("events", MainEventsPPI);
+ prepareToParse("events", MainEventsPPI, ErrorCallback);
if (opts::HeatmapMode) {
if (std::error_code EC = printLBRHeatMap()) {
@@ -571,38 +584,9 @@ Error DataAggregator::preprocessProfile(BinaryContext &BC) {
}
// Special handling for memory events
- std::string Error;
- sys::ProcessInfo PI = sys::Wait(MemEventsPPI.PI, std::nullopt, &Error);
- if (PI.ReturnCode != 0) {
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
- MemoryBuffer::getFileOrSTDIN(MemEventsPPI.StderrPath.data());
- StringRef ErrBuf = (*MB)->getBuffer();
-
- deleteTempFiles();
-
- Regex NoData("Samples for '.*' event do not have ADDR attribute set. "
- "Cannot print 'addr' field.");
- if (!NoData.match(ErrBuf)) {
- errs() << "PERF-ERROR: return code " << PI.ReturnCode << "\n";
- errs() << ErrBuf;
- exit(1);
- }
+ if (prepareToParse("mem events", MemEventsPPI, MemEventsErrorCallback))
return Error::success();
- }
- ErrorOr<std::unique_ptr<MemoryBuffer>> MB =
- MemoryBuffer::getFileOrSTDIN(MemEventsPPI.StdoutPath.data());
- if (std::error_code EC = MB.getError()) {
- errs() << "Cannot open " << MemEventsPPI.StdoutPath.data() << ": "
- << EC.message() << "\n";
- deleteTempFiles();
- exit(1);
- }
-
- FileBuf = std::move(*MB);
- ParsingBuf = FileBuf->getBuffer();
- Col = 0;
- Line = 1;
if (const std::error_code EC = parseMemEvents())
errs() << "PERF2BOLT: failed to parse memory events: " << EC.message()
<< '\n';