[llvm] [memprof] Use uint32_t for linear call stack IDs (PR #93924)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Fri May 31 09:32:42 PDT 2024
https://github.com/kazutakahirata updated https://github.com/llvm/llvm-project/pull/93924
>From 3752c5ed203e1605e74c1b39b1583899ad16067e Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Thu, 30 May 2024 21:44:55 -0700
Subject: [PATCH 1/2] [memprof] Use uint32_t for linear call stack IDs
This patch switches to uint32_t for linear call stack IDs as uint32_t
is sufficient to index into the call stack array.
---
llvm/lib/ProfileData/MemProf.cpp | 68 +++++++++++++++++++++++++++++---
1 file changed, 63 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/ProfileData/MemProf.cpp b/llvm/lib/ProfileData/MemProf.cpp
index 854b35b6924e1..65eacb136d720 100644
--- a/llvm/lib/ProfileData/MemProf.cpp
+++ b/llvm/lib/ProfileData/MemProf.cpp
@@ -45,6 +45,16 @@ static size_t serializedSizeV2(const IndexedAllocationInfo &IAI,
return Size;
}
+static size_t serializedSizeV3(const IndexedAllocationInfo &IAI,
+ const MemProfSchema &Schema) {
+ size_t Size = 0;
+ // The linear call stack ID.
+ Size += sizeof(uint32_t);
+ // The size of the payload.
+ Size += PortableMemInfoBlock::serializedSize(Schema);
+ return Size;
+}
+
size_t IndexedAllocationInfo::serializedSize(const MemProfSchema &Schema,
IndexedVersion Version) const {
switch (Version) {
@@ -52,8 +62,9 @@ size_t IndexedAllocationInfo::serializedSize(const MemProfSchema &Schema,
case Version1:
return serializedSizeV0(*this, Schema);
case Version2:
- case Version3:
return serializedSizeV2(*this, Schema);
+ case Version3:
+ return serializedSizeV3(*this, Schema);
}
llvm_unreachable("unsupported MemProf version");
}
@@ -89,6 +100,20 @@ static size_t serializedSizeV2(const IndexedMemProfRecord &Record,
return Result;
}
+static size_t serializedSizeV3(const IndexedMemProfRecord &Record,
+ const MemProfSchema &Schema) {
+ // The number of alloc sites to serialize.
+ size_t Result = sizeof(uint64_t);
+ for (const IndexedAllocationInfo &N : Record.AllocSites)
+ Result += N.serializedSize(Schema, Version3);
+
+ // The number of callsites we have information for.
+ Result += sizeof(uint64_t);
+ // The linear call stack ID.
+ Result += Record.CallSiteIds.size() * sizeof(uint32_t);
+ return Result;
+}
+
size_t IndexedMemProfRecord::serializedSize(const MemProfSchema &Schema,
IndexedVersion Version) const {
switch (Version) {
@@ -96,8 +121,9 @@ size_t IndexedMemProfRecord::serializedSize(const MemProfSchema &Schema,
case Version1:
return serializedSizeV0(*this, Schema);
case Version2:
- case Version3:
return serializedSizeV2(*this, Schema);
+ case Version3:
+ return serializedSizeV3(*this, Schema);
}
llvm_unreachable("unsupported MemProf version");
}
@@ -154,7 +180,7 @@ serializeV3(const IndexedMemProfRecord &Record, const MemProfSchema &Schema,
LE.write<uint64_t>(Record.AllocSites.size());
for (const IndexedAllocationInfo &N : Record.AllocSites) {
assert(MemProfCallStackIndexes.contains(N.CSId));
- LE.write<uint64_t>(MemProfCallStackIndexes[N.CSId]);
+ LE.write<uint32_t>(MemProfCallStackIndexes[N.CSId]);
N.Info.serialize(Schema, OS);
}
@@ -162,7 +188,7 @@ serializeV3(const IndexedMemProfRecord &Record, const MemProfSchema &Schema,
LE.write<uint64_t>(Record.CallSiteIds.size());
for (const auto &CSId : Record.CallSiteIds) {
assert(MemProfCallStackIndexes.contains(CSId));
- LE.write<uint64_t>(MemProfCallStackIndexes[CSId]);
+ LE.write<uint32_t>(MemProfCallStackIndexes[CSId]);
}
}
@@ -259,6 +285,37 @@ static IndexedMemProfRecord deserializeV2(const MemProfSchema &Schema,
return Record;
}
+static IndexedMemProfRecord deserializeV3(const MemProfSchema &Schema,
+ const unsigned char *Ptr) {
+ using namespace support;
+
+ IndexedMemProfRecord Record;
+
+ // Read the meminfo nodes.
+ const uint64_t NumNodes =
+ endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
+ Record.AllocSites.reserve(NumNodes);
+ for (uint64_t I = 0; I < NumNodes; I++) {
+ IndexedAllocationInfo Node;
+ Node.CSId = endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
+ Node.Info.deserialize(Schema, Ptr);
+ Ptr += PortableMemInfoBlock::serializedSize(Schema);
+ Record.AllocSites.push_back(Node);
+ }
+
+ // Read the callsite information.
+ const uint64_t NumCtxs =
+ endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
+ Record.CallSiteIds.reserve(NumCtxs);
+ for (uint64_t J = 0; J < NumCtxs; J++) {
+ CallStackId CSId =
+ endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
+ Record.CallSiteIds.push_back(CSId);
+ }
+
+ return Record;
+}
+
IndexedMemProfRecord
IndexedMemProfRecord::deserialize(const MemProfSchema &Schema,
const unsigned char *Ptr,
@@ -268,8 +325,9 @@ IndexedMemProfRecord::deserialize(const MemProfSchema &Schema,
case Version1:
return deserializeV0(Schema, Ptr);
case Version2:
- case Version3:
return deserializeV2(Schema, Ptr);
+ case Version3:
+ return deserializeV3(Schema, Ptr);
}
llvm_unreachable("unsupported MemProf version");
}
>From a510e1f58a5eb6f532f3f17c1b61f4e50d58abf6 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Fri, 31 May 2024 09:32:23 -0700
Subject: [PATCH 2/2] Add LinearCallStackId.
---
llvm/include/llvm/ProfileData/MemProf.h | 3 +++
llvm/lib/ProfileData/MemProf.cpp | 12 ++++++++----
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/llvm/include/llvm/ProfileData/MemProf.h b/llvm/include/llvm/ProfileData/MemProf.h
index 34b295f792a22..b19c1b9a051d1 100644
--- a/llvm/include/llvm/ProfileData/MemProf.h
+++ b/llvm/include/llvm/ProfileData/MemProf.h
@@ -307,6 +307,9 @@ struct Frame {
// A type representing the index into the table of call stacks.
using CallStackId = uint64_t;
+// A type representing the index into the call stack array.
+using LinearCallStackId = uint32_t;
+
// Holds allocation information in a space efficient format where frames are
// represented using unique identifiers.
struct IndexedAllocationInfo {
diff --git a/llvm/lib/ProfileData/MemProf.cpp b/llvm/lib/ProfileData/MemProf.cpp
index 65eacb136d720..1c2d760cfeaf2 100644
--- a/llvm/lib/ProfileData/MemProf.cpp
+++ b/llvm/lib/ProfileData/MemProf.cpp
@@ -49,7 +49,7 @@ static size_t serializedSizeV3(const IndexedAllocationInfo &IAI,
const MemProfSchema &Schema) {
size_t Size = 0;
// The linear call stack ID.
- Size += sizeof(uint32_t);
+ Size += sizeof(LinearCallStackId);
// The size of the payload.
Size += PortableMemInfoBlock::serializedSize(Schema);
return Size;
@@ -110,7 +110,7 @@ static size_t serializedSizeV3(const IndexedMemProfRecord &Record,
// The number of callsites we have information for.
Result += sizeof(uint64_t);
// The linear call stack ID.
- Result += Record.CallSiteIds.size() * sizeof(uint32_t);
+ Result += Record.CallSiteIds.size() * sizeof(LinearCallStackId);
return Result;
}
@@ -308,8 +308,12 @@ static IndexedMemProfRecord deserializeV3(const MemProfSchema &Schema,
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
Record.CallSiteIds.reserve(NumCtxs);
for (uint64_t J = 0; J < NumCtxs; J++) {
- CallStackId CSId =
- endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
+ // We are storing LinearCallStackId in CallSiteIds, which is a vector of
+ // CallStackId. Assert that CallStackId is no smaller than
+ // LinearCallStackId.
+ static_assert(sizeof(LinearCallStackId) <= sizeof(CallStackId));
+ LinearCallStackId CSId =
+ endian::readNext<LinearCallStackId, llvm::endianness::little>(Ptr);
Record.CallSiteIds.push_back(CSId);
}
More information about the llvm-commits
mailing list