[llvm] [ProfData] Improve efficiency of reader (PR #169730)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 26 13:13:42 PST 2025


https://github.com/mxms0 updated https://github.com/llvm/llvm-project/pull/169730

>From 592a87b371844731bac6469e8efb6731f102f461 Mon Sep 17 00:00:00 2001
From: mxms <mxms at google.com>
Date: Wed, 26 Nov 2025 20:55:18 +0000
Subject: [PATCH 1/3] [ProfData] Improve efficiency of reader

Pre-reserve space in the map before inserting. In release builds, 9.4%
of all CPU time is spent in llvm::sampleprof::ProfileSymbolList::add. Of
that 9.4%, roughly half is in llvm::DenseMapBase::grow.
---
 llvm/include/llvm/ProfileData/SampleProf.h |  1 +
 llvm/lib/ProfileData/SampleProf.cpp        | 25 +++++++++++++++++-----
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h
index 3dd34aba2d716..6bce5c718e598 100644
--- a/llvm/include/llvm/ProfileData/SampleProf.h
+++ b/llvm/include/llvm/ProfileData/SampleProf.h
@@ -1658,6 +1658,7 @@ class ProfileSymbolList {
   }
 
   unsigned size() { return Syms.size(); }
+  void reserve(size_t Size) { Syms.reserve(Size); }
 
   void setToCompress(bool TC) { ToCompress = TC; }
   bool toCompress() { return ToCompress; }
diff --git a/llvm/lib/ProfileData/SampleProf.cpp b/llvm/lib/ProfileData/SampleProf.cpp
index ac7513ef2cb49..5f0af79ef33df 100644
--- a/llvm/lib/ProfileData/SampleProf.cpp
+++ b/llvm/lib/ProfileData/SampleProf.cpp
@@ -399,15 +399,30 @@ LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); }
 std::error_code ProfileSymbolList::read(const uint8_t *Data,
                                         uint64_t ListSize) {
   const char *ListStart = reinterpret_cast<const char *>(Data);
-  uint64_t Size = 0;
+  uint64_t Offset = 0;
   uint64_t StrNum = 0;
-  while (Size < ListSize && StrNum < ProfileSymbolListCutOff) {
-    StringRef Str(ListStart + Size);
+  uint64_t ExpectedCount = 0;
+
+  Scan forward to see how many elements we expect.
+  while (Offset < ListSize) {
+    if (ListStart[Offset] == '\0') ExpectedCount++;
+    Offset++;
+  }
+
+  reserve(ExpectedCount);
+
+  Offset = 0;
+
+  while (Offset < ListSize && StrNum < ProfileSymbolListCutOff) {
+    StringRef Str(ListStart + Offset);
     add(Str);
-    Size += Str.size() + 1;
+    Offset += Str.size() + 1;
     StrNum++;
   }
-  if (Size != ListSize && StrNum != ProfileSymbolListCutOff)
+
+  assert(ExpectedCount == StrNum);
+
+  if (Offset != ListSize && StrNum != ProfileSymbolListCutOff)
     return sampleprof_error::malformed;
   return sampleprof_error::success;
 }

>From 264d4dda5b2b08838b09d72713008bcb9dff1e29 Mon Sep 17 00:00:00 2001
From: mxms <mxms at google.com>
Date: Wed, 26 Nov 2025 20:55:18 +0000
Subject: [PATCH 2/3] [ProfData] Improve efficiency of reader

Pre-reserve space in the map before inserting. In release builds, 9.4%
of all CPU time is spent in llvm::sampleprof::ProfileSymbolList::add. Of
that 9.4%, roughly half is in llvm::DenseMapBase::grow.
---
 llvm/lib/ProfileData/SampleProf.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/lib/ProfileData/SampleProf.cpp b/llvm/lib/ProfileData/SampleProf.cpp
index 5f0af79ef33df..14f319b3cc28e 100644
--- a/llvm/lib/ProfileData/SampleProf.cpp
+++ b/llvm/lib/ProfileData/SampleProf.cpp
@@ -403,7 +403,7 @@ std::error_code ProfileSymbolList::read(const uint8_t *Data,
   uint64_t StrNum = 0;
   uint64_t ExpectedCount = 0;
 
-  Scan forward to see how many elements we expect.
+  // Scan forward to see how many elements we expect.
   while (Offset < ListSize) {
     if (ListStart[Offset] == '\0') ExpectedCount++;
     Offset++;

>From 3c994a3b67f631fc9de4194ee573d11d3b1ca904 Mon Sep 17 00:00:00 2001
From: mxms <mxms at google.com>
Date: Wed, 26 Nov 2025 20:55:18 +0000
Subject: [PATCH 3/3] [ProfData] Improve efficiency of reader

Pre-reserve space in the map before inserting. In release builds, 9.4%
of all CPU time is spent in llvm::sampleprof::ProfileSymbolList::add. Of
that 9.4%, roughly half is in llvm::DenseMapBase::grow.
---
 llvm/lib/ProfileData/SampleProf.cpp | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/llvm/lib/ProfileData/SampleProf.cpp b/llvm/lib/ProfileData/SampleProf.cpp
index 14f319b3cc28e..17a0e5ba52156 100644
--- a/llvm/lib/ProfileData/SampleProf.cpp
+++ b/llvm/lib/ProfileData/SampleProf.cpp
@@ -399,7 +399,7 @@ LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); }
 std::error_code ProfileSymbolList::read(const uint8_t *Data,
                                         uint64_t ListSize) {
   const char *ListStart = reinterpret_cast<const char *>(Data);
-  uint64_t Offset = 0;
+  uint64_t Size = 0;
   uint64_t StrNum = 0;
   uint64_t ExpectedCount = 0;
 
@@ -407,22 +407,21 @@ std::error_code ProfileSymbolList::read(const uint8_t *Data,
   while (Offset < ListSize) {
     if (ListStart[Offset] == '\0') ExpectedCount++;
     Offset++;
-  }
 
   reserve(ExpectedCount);
 
-  Offset = 0;
+  Size = 0;
 
-  while (Offset < ListSize && StrNum < ProfileSymbolListCutOff) {
-    StringRef Str(ListStart + Offset);
+  while (Size < ListSize && StrNum < ProfileSymbolListCutOff) {
+    StringRef Str(ListStart + Size);
     add(Str);
-    Offset += Str.size() + 1;
+    Size += Str.size() + 1;
     StrNum++;
   }
 
   assert(ExpectedCount == StrNum);
 
-  if (Offset != ListSize && StrNum != ProfileSymbolListCutOff)
+  if (Size != ListSize && StrNum != ProfileSymbolListCutOff)
     return sampleprof_error::malformed;
   return sampleprof_error::success;
 }



More information about the llvm-commits mailing list