[llvm] [NFCI] Move ProfOStream from InstrProfWriter.cpp to InstrProf.h/cpp (PR #136791)

Mingming Liu via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 22 17:30:16 PDT 2025


https://github.com/mingmingl-llvm created https://github.com/llvm/llvm-project/pull/136791

ProfOStream is a wrapper class for output stream, and used by InstrProfWriter.cpp to serialize various profiles, like PGO profiles and MemProf.

This change proposes to move it into InstrProf.h/cpp. After this is in, InstrProfWriter can dispatch serialization of various formats into `obj->serialize()`, and the serialization code could be move out of InstrProfWriter.cpp into individual classes (each in a smaller cpp file). One example is that we can gradually move writeMemprof [1] into llvm/*/ProfileData/MemProf.h/cpp, where a couple of classes already have `serialize/deserialize` methods. 


[1] https://github.com/llvm/llvm-project/blob/85b35a90770b6053f91d79ca685cdfa4bf6499a4/llvm/lib/ProfileData/InstrProfWriter.cpp#L774-L791

>From e1fc5cc8b8aaeb59a79a3ecedaffd2e4d699c65f Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Tue, 22 Apr 2025 17:12:47 -0700
Subject: [PATCH] Move PProfOStream from InstrProfWriter.cpp to InstrProf.h/cpp

---
 llvm/include/llvm/ProfileData/InstrProf.h | 32 ++++++++++++
 llvm/lib/ProfileData/InstrProf.cpp        | 41 ++++++++++++++++
 llvm/lib/ProfileData/InstrProfWriter.cpp  | 60 -----------------------
 3 files changed, 73 insertions(+), 60 deletions(-)

diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h
index 7133c0c6a302c..2d011c89f27cb 100644
--- a/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/llvm/include/llvm/ProfileData/InstrProf.h
@@ -28,6 +28,7 @@
 #include "llvm/Support/BalancedPartitioning.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Compiler.h"
+#include "llvm/Support/EndianStream.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/MD5.h"
@@ -57,6 +58,37 @@ class Instruction;
 class MDNode;
 class Module;
 
+// A struct to define how the data stream should be patched. For Indexed
+// profiling, only uint64_t data type is needed.
+struct PatchItem {
+  uint64_t Pos;         // Where to patch.
+  ArrayRef<uint64_t> D; // An array of source data.
+};
+
+// A wrapper class to abstract writer stream with support of bytes
+// back patching.
+class ProfOStream {
+public:
+  ProfOStream(raw_fd_ostream &FD);
+  ProfOStream(raw_string_ostream &STR);
+
+  [[nodiscard]] uint64_t tell() const;
+  void write(uint64_t V);
+  void write32(uint32_t V);
+  void writeByte(uint8_t V);
+
+  // \c patch can only be called when all data is written and flushed.
+  // For raw_string_ostream, the patch is done on the target string
+  // directly and it won't be reflected in the stream's internal buffer.
+  void patch(ArrayRef<PatchItem> P);
+
+  // If \c OS is an instance of \c raw_fd_ostream, this field will be
+  // true. Otherwise, \c OS will be an raw_string_ostream.
+  bool IsFDOStream;
+  raw_ostream &OS;
+  support::endian::Writer LE;
+};
+
 enum InstrProfSectKind {
 #define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Kind,
 #include "llvm/ProfileData/InstrProfData.inc"
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 1e427ca63c5cf..88621787c1dd9 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -42,6 +42,7 @@
 #include "llvm/Support/Path.h"
 #include "llvm/Support/SwapByteOrder.h"
 #include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/Support/raw_ostream.h"
 #include "llvm/TargetParser/Triple.h"
 #include <algorithm>
 #include <cassert>
@@ -258,6 +259,46 @@ std::string InstrProfError::message() const {
 
 char InstrProfError::ID = 0;
 
+ProfOStream::ProfOStream(raw_fd_ostream &FD)
+    : IsFDOStream(true), OS(FD), LE(FD, llvm::endianness::little) {}
+
+ProfOStream::ProfOStream(raw_string_ostream &STR)
+    : IsFDOStream(false), OS(STR), LE(STR, llvm::endianness::little) {}
+
+uint64_t ProfOStream::tell() const { return OS.tell(); }
+void ProfOStream::write(uint64_t V) { LE.write<uint64_t>(V); }
+void ProfOStream::write32(uint32_t V) { LE.write<uint32_t>(V); }
+void ProfOStream::writeByte(uint8_t V) { LE.write<uint8_t>(V); }
+
+void ProfOStream::patch(ArrayRef<PatchItem> P) {
+  using namespace support;
+
+  if (IsFDOStream) {
+    raw_fd_ostream &FDOStream = static_cast<raw_fd_ostream &>(OS);
+    const uint64_t LastPos = FDOStream.tell();
+    for (const auto &K : P) {
+      FDOStream.seek(K.Pos);
+      for (uint64_t Elem : K.D)
+        write(Elem);
+    }
+    // Reset the stream to the last position after patching so that users
+    // don't accidentally overwrite data. This makes it consistent with
+    // the string stream below which replaces the data directly.
+    FDOStream.seek(LastPos);
+  } else {
+    raw_string_ostream &SOStream = static_cast<raw_string_ostream &>(OS);
+    std::string &Data = SOStream.str(); // with flush
+    for (const auto &K : P) {
+      for (int I = 0, E = K.D.size(); I != E; I++) {
+        uint64_t Bytes =
+            endian::byte_swap<uint64_t, llvm::endianness::little>(K.D[I]);
+        Data.replace(K.Pos + I * sizeof(uint64_t), sizeof(uint64_t),
+                     (const char *)&Bytes, sizeof(uint64_t));
+      }
+    }
+  }
+}
+
 std::string getPGOFuncName(StringRef Name, GlobalValue::LinkageTypes Linkage,
                            StringRef FileName,
                            uint64_t Version LLVM_ATTRIBUTE_UNUSED) {
diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp
index 18aa76c865bc8..f1882dc3628cc 100644
--- a/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -37,68 +37,8 @@
 
 using namespace llvm;
 
-// A struct to define how the data stream should be patched. For Indexed
-// profiling, only uint64_t data type is needed.
-struct PatchItem {
-  uint64_t Pos;         // Where to patch.
-  ArrayRef<uint64_t> D; // An array of source data.
-};
-
 namespace llvm {
 
-// A wrapper class to abstract writer stream with support of bytes
-// back patching.
-class ProfOStream {
-public:
-  ProfOStream(raw_fd_ostream &FD)
-      : IsFDOStream(true), OS(FD), LE(FD, llvm::endianness::little) {}
-  ProfOStream(raw_string_ostream &STR)
-      : IsFDOStream(false), OS(STR), LE(STR, llvm::endianness::little) {}
-
-  [[nodiscard]] uint64_t tell() const { return OS.tell(); }
-  void write(uint64_t V) { LE.write<uint64_t>(V); }
-  void write32(uint32_t V) { LE.write<uint32_t>(V); }
-  void writeByte(uint8_t V) { LE.write<uint8_t>(V); }
-
-  // \c patch can only be called when all data is written and flushed.
-  // For raw_string_ostream, the patch is done on the target string
-  // directly and it won't be reflected in the stream's internal buffer.
-  void patch(ArrayRef<PatchItem> P) {
-    using namespace support;
-
-    if (IsFDOStream) {
-      raw_fd_ostream &FDOStream = static_cast<raw_fd_ostream &>(OS);
-      const uint64_t LastPos = FDOStream.tell();
-      for (const auto &K : P) {
-        FDOStream.seek(K.Pos);
-        for (uint64_t Elem : K.D)
-          write(Elem);
-      }
-      // Reset the stream to the last position after patching so that users
-      // don't accidentally overwrite data. This makes it consistent with
-      // the string stream below which replaces the data directly.
-      FDOStream.seek(LastPos);
-    } else {
-      raw_string_ostream &SOStream = static_cast<raw_string_ostream &>(OS);
-      std::string &Data = SOStream.str(); // with flush
-      for (const auto &K : P) {
-        for (int I = 0, E = K.D.size(); I != E; I++) {
-          uint64_t Bytes =
-              endian::byte_swap<uint64_t, llvm::endianness::little>(K.D[I]);
-          Data.replace(K.Pos + I * sizeof(uint64_t), sizeof(uint64_t),
-                       (const char *)&Bytes, sizeof(uint64_t));
-        }
-      }
-    }
-  }
-
-  // If \c OS is an instance of \c raw_fd_ostream, this field will be
-  // true. Otherwise, \c OS will be an raw_string_ostream.
-  bool IsFDOStream;
-  raw_ostream &OS;
-  support::endian::Writer LE;
-};
-
 class InstrProfRecordWriterTrait {
 public:
   using key_type = StringRef;



More information about the llvm-commits mailing list