[llvm] 4eb20a1 - [llvm-profdata][StaticDataLayout] Print summary of data access profiles in llvm-profdata (#173087)

via llvm-commits llvm-commits at lists.llvm.org
Fri Dec 19 14:07:56 PST 2025


Author: Mingming Liu
Date: 2025-12-19T22:07:51Z
New Revision: 4eb20a12be29472d545acf708d494acd8112b79c

URL: https://github.com/llvm/llvm-project/commit/4eb20a12be29472d545acf708d494acd8112b79c
DIFF: https://github.com/llvm/llvm-project/commit/4eb20a12be29472d545acf708d494acd8112b79c.diff

LOG: [llvm-profdata][StaticDataLayout] Print summary of data access profiles in llvm-profdata (#173087)

This gives some aggregated information about the data access profiles.
The summaries are computed on the fly to save a profile version update.

Implementation-wise
* `MemProfSummary::printSummaryYaml` is updated to print data access
summaries for v4, the profile version that started to support data
access profiles.
* MemProfSummary.cpp has a FIXME comment to serialize the summary into
profile data, ideally batching with more substantial profile format
change.
* MemProfSummaryBuilder is not updated for now. This class is used to
serialize memprof summaries for v4 and above by memprof writer, and to
construct memprof summaries for v3 and prior versions by llvm-profdata.

Added: 
    

Modified: 
    llvm/include/llvm/ProfileData/MemProfSummary.h
    llvm/lib/ProfileData/IndexedMemProfData.cpp
    llvm/lib/ProfileData/MemProfSummary.cpp
    llvm/test/tools/llvm-profdata/memprof-yaml.test

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ProfileData/MemProfSummary.h b/llvm/include/llvm/ProfileData/MemProfSummary.h
index 8bf6155bd43e5..2d77c85c2d1ca 100644
--- a/llvm/include/llvm/ProfileData/MemProfSummary.h
+++ b/llvm/include/llvm/ProfileData/MemProfSummary.h
@@ -13,6 +13,7 @@
 #ifndef LLVM_PROFILEDATA_MEMPROFSUMMARY_H
 #define LLVM_PROFILEDATA_MEMPROFSUMMARY_H
 
+#include "llvm/ProfileData/DataAccessProf.h"
 #include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/Compiler.h"
 
@@ -32,13 +33,21 @@ class MemProfSummary {
   const uint64_t NumContexts, NumColdContexts, NumHotContexts;
   const uint64_t MaxColdTotalSize, MaxWarmTotalSize, MaxHotTotalSize;
 
+  // MemProf v3 and prior versions don't have data access profile,
+  // so record the data access profile state.
+  bool HasDataAccessProfile = false;
+  size_t NumHotSymbolsAndStringLiterals = 0;
+  size_t NumKnownColdSymbols = 0;
+  size_t NumKnownColdStringLiterals = 0;
+
 public:
   MemProfSummary(uint64_t NumContexts, uint64_t NumColdContexts,
                  uint64_t NumHotContexts, uint64_t MaxColdTotalSize,
                  uint64_t MaxWarmTotalSize, uint64_t MaxHotTotalSize)
       : NumContexts(NumContexts), NumColdContexts(NumColdContexts),
         NumHotContexts(NumHotContexts), MaxColdTotalSize(MaxColdTotalSize),
-        MaxWarmTotalSize(MaxWarmTotalSize), MaxHotTotalSize(MaxHotTotalSize) {}
+        MaxWarmTotalSize(MaxWarmTotalSize), MaxHotTotalSize(MaxHotTotalSize),
+        HasDataAccessProfile(false) {}
 
   static constexpr unsigned getNumSummaryFields() { return NumSummaryFields; }
   uint64_t getNumContexts() const { return NumContexts; }
@@ -53,6 +62,12 @@ class MemProfSummary {
   /// Read from indexed MemProf profile.
   LLVM_ABI static std::unique_ptr<MemProfSummary>
   deserialize(const unsigned char *&);
+  /// Build data access profile summary from \p DataAccessProfile.
+  /// The pointer is not owned.
+  /// TODO: Remove this function after the data access profile summary is
+  /// serialized.
+  LLVM_ABI void
+  buildDataAccessSummary(const DataAccessProfData &DataAccessProfile);
 };
 
 } // namespace memprof

diff  --git a/llvm/lib/ProfileData/IndexedMemProfData.cpp b/llvm/lib/ProfileData/IndexedMemProfData.cpp
index 04ddae357ddd7..18b25eadc296a 100644
--- a/llvm/lib/ProfileData/IndexedMemProfData.cpp
+++ b/llvm/lib/ProfileData/IndexedMemProfData.cpp
@@ -407,8 +407,19 @@ Error IndexedMemProfReader::deserializeRadixTreeBased(
     DataAccessProfOffset =
         support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
     MemProfSum = memprof::MemProfSummary::deserialize(Ptr);
+
+    if (DataAccessProfOffset > RecordTableOffset) {
+      DataAccessProfileData = std::make_unique<memprof::DataAccessProfData>();
+      const unsigned char *DAPPtr = Start + DataAccessProfOffset;
+      if (Error E = DataAccessProfileData->deserialize(DAPPtr))
+        return E;
+      MemProfSum->buildDataAccessSummary(*DataAccessProfileData);
+    }
   }
 
+  assert((!DataAccessProfOffset || DataAccessProfOffset > RecordTableOffset) &&
+         "Data access profile is either empty or after the record table");
+
   // Read the schema.
   auto SchemaOr = memprof::readMemProfSchema(Ptr);
   if (!SchemaOr)
@@ -430,15 +441,6 @@ Error IndexedMemProfReader::deserializeRadixTreeBased(
       /*Payload=*/Start + RecordPayloadOffset,
       /*Base=*/Start, memprof::RecordLookupTrait(Version, Schema)));
 
-  assert((!DataAccessProfOffset || DataAccessProfOffset > RecordTableOffset) &&
-         "Data access profile is either empty or after the record table");
-  if (DataAccessProfOffset > RecordTableOffset) {
-    DataAccessProfileData = std::make_unique<memprof::DataAccessProfData>();
-    const unsigned char *DAPPtr = Start + DataAccessProfOffset;
-    if (Error E = DataAccessProfileData->deserialize(DAPPtr))
-      return E;
-  }
-
   return Error::success();
 }
 

diff  --git a/llvm/lib/ProfileData/MemProfSummary.cpp b/llvm/lib/ProfileData/MemProfSummary.cpp
index f620b7a74b244..1690745debf54 100644
--- a/llvm/lib/ProfileData/MemProfSummary.cpp
+++ b/llvm/lib/ProfileData/MemProfSummary.cpp
@@ -25,6 +25,13 @@ void MemProfSummary::printSummaryYaml(raw_ostream &OS) const {
   OS << "#   Maximum cold context total size: " << MaxColdTotalSize << "\n";
   OS << "#   Maximum warm context total size: " << MaxWarmTotalSize << "\n";
   OS << "#   Maximum hot context total size: " << MaxHotTotalSize << "\n";
+  if (HasDataAccessProfile) {
+    OS << "# Num hot symbols and string literals: "
+       << NumHotSymbolsAndStringLiterals << "\n";
+    OS << "# Num known cold symbols: " << NumKnownColdSymbols << "\n";
+    OS << "# Num known cold string literals: " << NumKnownColdStringLiterals
+       << "\n";
+  }
 }
 
 void MemProfSummary::write(ProfOStream &OS) const {
@@ -72,3 +79,14 @@ MemProfSummary::deserialize(const unsigned char *&Ptr) {
 
   return MemProfSum;
 }
+
+// FIXME: Consider to serialize the data access summary fields, ideally
+// batch this together with more substantial profile format change
+// and bump version once.
+void MemProfSummary::buildDataAccessSummary(
+    const DataAccessProfData &DataAccessProfile) {
+  HasDataAccessProfile = true;
+  NumHotSymbolsAndStringLiterals = DataAccessProfile.getRecords().size();
+  NumKnownColdSymbols = DataAccessProfile.getKnownColdSymbols().size();
+  NumKnownColdStringLiterals = DataAccessProfile.getKnownColdHashes().size();
+}

diff  --git a/llvm/test/tools/llvm-profdata/memprof-yaml.test b/llvm/test/tools/llvm-profdata/memprof-yaml.test
index 30fa30385010f..69b3131a87f3d 100644
--- a/llvm/test/tools/llvm-profdata/memprof-yaml.test
+++ b/llvm/test/tools/llvm-profdata/memprof-yaml.test
@@ -44,6 +44,9 @@
 #   Maximum cold context total size: 0
 #   Maximum warm context total size: 666
 #   Maximum hot context total size: 0
+#   Num hot symbols and string literals: 2
+#   Num known cold symbols: 2
+#   Num known cold string literals: 2
 ---
 HeapProfileRecords:
   - GUID:            0xdeadbeef12345678
@@ -229,6 +232,9 @@ HeapProfileRecords:
 #   Maximum cold context total size: 0
 #   Maximum warm context total size: 0
 #   Maximum hot context total size: 0
+#   Num hot symbols and string literals: 2
+#   Num known cold symbols: 2
+#   Num known cold string literals: 2
 ---
 DataAccessProfiles:
   SampledRecords:


        


More information about the llvm-commits mailing list