[llvm] [BOLT] Add pre-parsed perf script support (PR #163785)

Ádám Kallai via llvm-commits llvm-commits at lists.llvm.org
Wed May 13 05:42:33 PDT 2026


================
@@ -392,23 +392,109 @@ void DataAggregator::parsePreAggregated() {
   ParsingBuf = FileBuf->getBuffer();
   Col = 0;
   Line = 1;
+  if (parsePreAggregatedLBRSamples()) {
+    errs() << "PERF2BOLT: failed to parse samples\n";
+    exit(1);
+  }
+}
 
-  // When processing a shared object, filter pre-aggregated entries by buildid.
-  if (BC && !BC->HasFixedLoadAddress && BC->getFilename().ends_with(".so")) {
-    if (auto FileBID = BC->getFileBuildID()) {
-      FilterBuildID = *FileBID;
-      outs() << "PERF2BOLT: filtering pre-aggregated data for buildid "
-             << *FileBID << "\n";
-    } else {
-      errs() << "PERF2BOLT-WARNING: cannot read buildid from input binary, "
-                "won't filter pre-aggregated data\n";
+std::error_code DataAggregator::parsePerfTextFileHeader() {
+  size_t LineEnd = ParsingBuf.find_first_of("\n");
+  if (LineEnd == StringRef::npos) {
+    reportError("expected rest of line");
+    Diag << "Found: " << ParsingBuf << "\n";
+    return make_error_code(llvm::errc::io_error);
+  }
+  StringRef HeaderLine = ParsingBuf.substr(0, LineEnd);
+  size_t HeaderLineSize = HeaderLine.size() + 1;
+
+  if (!HeaderLine.consume_front(PerfTextMagicStr)) {
+    reportError("expected 'PERFTEXT' magic string");
+    Diag << "Found: " << HeaderLine << "\n";
+    return make_error_code(llvm::errc::io_error);
+  }
+  Col += PerfTextMagicStr.size();
+
+  SmallVector<StringRef, 5> Events;
+  HeaderLine.trim().split(Events, ";", -1, false);
+
+  if (Events.empty()) {
+    reportError("missing events=sizes content");
+    Diag << "Found: " << HeaderLine << "\n";
+    return make_error_code(llvm::errc::io_error);
+  }
+
+  uint64_t Offset = HeaderLineSize;
+  uint64_t Length = 0;
+  for (StringRef EV : Events) {
+    StringRef EventStr, LengthStr;
+    std::tie(EventStr, LengthStr) = EV.split("=");
+
+    PerfProcessInfo *PPI =
+        StringSwitch<PerfProcessInfo *>(EventStr)
+            .Case(PerfProcessInfo::EventNamesStr[PerfProcessType::BUILDIDS],
+                  &BuildIDProcessInfo)
+            .Case(PerfProcessInfo::EventNamesStr[PerfProcessType::MAIN_EVENTS],
+                  &MainEventsPPI)
+            .Case(PerfProcessInfo::EventNamesStr[PerfProcessType::MEM_EVENTS],
+                  &MemEventsPPI)
+            .Case(PerfProcessInfo::EventNamesStr[PerfProcessType::MMAP_EVENTS],
+                  &MMapEventsPPI)
+            .Case(PerfProcessInfo::EventNamesStr[PerfProcessType::TASK_EVENTS],
+                  &TaskEventsPPI)
+            .Default(nullptr);
+
+    if (!PPI) {
+      reportError("malformed text profile");
+      Diag << "Found: " << EventStr << " in " << HeaderLine << "\n";
+      return make_error_code(llvm::errc::io_error);
+    }
+
+    if (LengthStr.getAsInteger(16, Length)) {
+      reportError("expected hexadecimal number");
+      Diag << "Found: " << LengthStr << " in " << HeaderLine << "\n";
+      return make_error_code(llvm::errc::io_error);
     }
+    PPI->Offset = Offset;
+    PPI->Length = Length;
+    Offset = Offset + Length;
+    Col += EV.size();
   }
 
-  if (parsePreAggregatedLBRSamples()) {
-    errs() << "PERF2BOLT: failed to parse samples\n";
-    exit(1);
+  ErrorOr<uint64_t> FsRes = getFileSize(Filename);
+  if (std::error_code EC = FsRes.getError())
+    return EC;
+  if (*FsRes != Offset) {
+    reportError("corrupted perf text profile");
+    Diag << "Found: " << *FsRes << " != " << Offset << "\n";
+    return make_error_code(llvm::errc::io_error);
+  }
+  return std::error_code();
+}
+
+void DataAggregator::parsePerfTextData(BinaryContext &BC) {
+  outs() << "PERF2BOLT: parsing a hybrid perf-script events...\n";
----------------
kaadam wrote:

Updated.

https://github.com/llvm/llvm-project/pull/163785


More information about the llvm-commits mailing list