[llvm] [memprof] Use std::unique_ptr instead of std::optional (PR #94655)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 6 11:24:17 PDT 2024


https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/94655

Changing the type of Frame::SymbolName from std::optional<std::string>
to std::unique<std::string> reduces sizeof(Frame) from 64 to 32.

The smaller type reduces the cycle and instruction counts by 23% and
4.4%, respectively, with "llvm-profdata show" modified to deserialize
all MemProfRecords in a MemProf V2 profile.  The peak memory usage is
cut down nearly by half.

>From e623260042db9ca3a766326d4024074f80acee24 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Mon, 27 May 2024 11:07:56 -0700
Subject: [PATCH] [memprof] Use std::unique_ptr instead of std::optional

Changing the type of Frame::SymbolName from std::optional<std::string>
to std::unique<std::string> reduces sizeof(Frame) from 64 to 32.

The smaller type reduces the cycle and instruction counts by 23% and
4.4%, respectively, with "llvm-profdata show" modified to deserialize
all MemProfRecords in a MemProf V2 profile.  The peak memory usage is
cut down nearly by half.
---
 llvm/include/llvm/ProfileData/MemProf.h | 14 +++++++++-----
 llvm/lib/ProfileData/MemProfReader.cpp  |  2 +-
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h
index 406144d9db1e8..528abe1ad3d45 100644
--- a/llvm/include/llvm/ProfileData/MemProf.h
+++ b/llvm/include/llvm/ProfileData/MemProf.h
@@ -199,7 +199,7 @@ struct Frame {
   GlobalValue::GUID Function;
   // The symbol name for the function. Only populated in the Frame by the reader
   // if requested during initialization. This field should not be serialized.
-  std::optional<std::string> SymbolName;
+  std::unique_ptr<std::string> SymbolName;
   // The source line offset of the call from the beginning of parent function.
   uint32_t LineOffset;
   // The source column number of the call to help distinguish multiple calls
@@ -210,7 +210,9 @@ struct Frame {
 
   Frame(const Frame &Other) {
     Function = Other.Function;
-    SymbolName = Other.SymbolName;
+    SymbolName = Other.SymbolName
+                     ? std::make_unique<std::string>(*Other.SymbolName)
+                     : nullptr;
     LineOffset = Other.LineOffset;
     Column = Other.Column;
     IsInlineFrame = Other.IsInlineFrame;
@@ -228,7 +230,9 @@ struct Frame {
 
   Frame &operator=(const Frame &Other) {
     Function = Other.Function;
-    SymbolName = Other.SymbolName;
+    SymbolName = Other.SymbolName
+                     ? std::make_unique<std::string>(*Other.SymbolName)
+                     : nullptr;
     LineOffset = Other.LineOffset;
     Column = Other.Column;
     IsInlineFrame = Other.IsInlineFrame;
@@ -237,10 +241,10 @@ struct Frame {
 
   bool operator!=(const Frame &Other) const { return !operator==(Other); }
 
-  bool hasSymbolName() const { return SymbolName.has_value(); }
+  bool hasSymbolName() const { return !!SymbolName; }
 
   StringRef getSymbolName() const {
-    assert(SymbolName.has_value());
+    assert(hasSymbolName());
     return *SymbolName;
   }
 
diff --git a/llvm/lib/ProfileData/MemProfReader.cpp b/llvm/lib/ProfileData/MemProfReader.cpp
index fc3be716087eb..693897f874a29 100644
--- a/llvm/lib/ProfileData/MemProfReader.cpp
+++ b/llvm/lib/ProfileData/MemProfReader.cpp
@@ -690,7 +690,7 @@ Error RawMemProfReader::readNextRecord(
       return F;
     auto Iter = this->GuidToSymbolName.find(F.Function);
     assert(Iter != this->GuidToSymbolName.end());
-    F.SymbolName = Iter->getSecond();
+    F.SymbolName = std::make_unique<std::string>(Iter->getSecond());
     return F;
   };
   return MemProfReader::readNextRecord(GuidRecord, IdToFrameCallback);



More information about the llvm-commits mailing list