Skip to content

Commit 37f3023

Browse files
[memprof] Use uint32_t for linear call stack IDs (#93924)
This patch switches to uint32_t for linear call stack IDs as uint32_t is sufficient to index into the call stack array.
1 parent 41ddf12 commit 37f3023

File tree

2 files changed

+70
-5
lines changed

2 files changed

+70
-5
lines changed

llvm/include/llvm/ProfileData/MemProf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,9 @@ struct Frame {
307307
// A type representing the index into the table of call stacks.
308308
using CallStackId = uint64_t;
309309

310+
// A type representing the index into the call stack array.
311+
using LinearCallStackId = uint32_t;
312+
310313
// Holds allocation information in a space efficient format where frames are
311314
// represented using unique identifiers.
312315
struct IndexedAllocationInfo {

llvm/lib/ProfileData/MemProf.cpp

Lines changed: 67 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,15 +45,26 @@ static size_t serializedSizeV2(const IndexedAllocationInfo &IAI,
4545
return Size;
4646
}
4747

48+
static size_t serializedSizeV3(const IndexedAllocationInfo &IAI,
49+
const MemProfSchema &Schema) {
50+
size_t Size = 0;
51+
// The linear call stack ID.
52+
Size += sizeof(LinearCallStackId);
53+
// The size of the payload.
54+
Size += PortableMemInfoBlock::serializedSize(Schema);
55+
return Size;
56+
}
57+
4858
size_t IndexedAllocationInfo::serializedSize(const MemProfSchema &Schema,
4959
IndexedVersion Version) const {
5060
switch (Version) {
5161
case Version0:
5262
case Version1:
5363
return serializedSizeV0(*this, Schema);
5464
case Version2:
55-
case Version3:
5665
return serializedSizeV2(*this, Schema);
66+
case Version3:
67+
return serializedSizeV3(*this, Schema);
5768
}
5869
llvm_unreachable("unsupported MemProf version");
5970
}
@@ -89,15 +100,30 @@ static size_t serializedSizeV2(const IndexedMemProfRecord &Record,
89100
return Result;
90101
}
91102

103+
static size_t serializedSizeV3(const IndexedMemProfRecord &Record,
104+
const MemProfSchema &Schema) {
105+
// The number of alloc sites to serialize.
106+
size_t Result = sizeof(uint64_t);
107+
for (const IndexedAllocationInfo &N : Record.AllocSites)
108+
Result += N.serializedSize(Schema, Version3);
109+
110+
// The number of callsites we have information for.
111+
Result += sizeof(uint64_t);
112+
// The linear call stack ID.
113+
Result += Record.CallSiteIds.size() * sizeof(LinearCallStackId);
114+
return Result;
115+
}
116+
92117
size_t IndexedMemProfRecord::serializedSize(const MemProfSchema &Schema,
93118
IndexedVersion Version) const {
94119
switch (Version) {
95120
case Version0:
96121
case Version1:
97122
return serializedSizeV0(*this, Schema);
98123
case Version2:
99-
case Version3:
100124
return serializedSizeV2(*this, Schema);
125+
case Version3:
126+
return serializedSizeV3(*this, Schema);
101127
}
102128
llvm_unreachable("unsupported MemProf version");
103129
}
@@ -154,15 +180,15 @@ serializeV3(const IndexedMemProfRecord &Record, const MemProfSchema &Schema,
154180
LE.write<uint64_t>(Record.AllocSites.size());
155181
for (const IndexedAllocationInfo &N : Record.AllocSites) {
156182
assert(MemProfCallStackIndexes.contains(N.CSId));
157-
LE.write<uint64_t>(MemProfCallStackIndexes[N.CSId]);
183+
LE.write<uint32_t>(MemProfCallStackIndexes[N.CSId]);
158184
N.Info.serialize(Schema, OS);
159185
}
160186

161187
// Related contexts.
162188
LE.write<uint64_t>(Record.CallSiteIds.size());
163189
for (const auto &CSId : Record.CallSiteIds) {
164190
assert(MemProfCallStackIndexes.contains(CSId));
165-
LE.write<uint64_t>(MemProfCallStackIndexes[CSId]);
191+
LE.write<uint32_t>(MemProfCallStackIndexes[CSId]);
166192
}
167193
}
168194

@@ -259,6 +285,41 @@ static IndexedMemProfRecord deserializeV2(const MemProfSchema &Schema,
259285
return Record;
260286
}
261287

288+
static IndexedMemProfRecord deserializeV3(const MemProfSchema &Schema,
289+
const unsigned char *Ptr) {
290+
using namespace support;
291+
292+
IndexedMemProfRecord Record;
293+
294+
// Read the meminfo nodes.
295+
const uint64_t NumNodes =
296+
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
297+
Record.AllocSites.reserve(NumNodes);
298+
for (uint64_t I = 0; I < NumNodes; I++) {
299+
IndexedAllocationInfo Node;
300+
Node.CSId = endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
301+
Node.Info.deserialize(Schema, Ptr);
302+
Ptr += PortableMemInfoBlock::serializedSize(Schema);
303+
Record.AllocSites.push_back(Node);
304+
}
305+
306+
// Read the callsite information.
307+
const uint64_t NumCtxs =
308+
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
309+
Record.CallSiteIds.reserve(NumCtxs);
310+
for (uint64_t J = 0; J < NumCtxs; J++) {
311+
// We are storing LinearCallStackId in CallSiteIds, which is a vector of
312+
// CallStackId. Assert that CallStackId is no smaller than
313+
// LinearCallStackId.
314+
static_assert(sizeof(LinearCallStackId) <= sizeof(CallStackId));
315+
LinearCallStackId CSId =
316+
endian::readNext<LinearCallStackId, llvm::endianness::little>(Ptr);
317+
Record.CallSiteIds.push_back(CSId);
318+
}
319+
320+
return Record;
321+
}
322+
262323
IndexedMemProfRecord
263324
IndexedMemProfRecord::deserialize(const MemProfSchema &Schema,
264325
const unsigned char *Ptr,
@@ -268,8 +329,9 @@ IndexedMemProfRecord::deserialize(const MemProfSchema &Schema,
268329
case Version1:
269330
return deserializeV0(Schema, Ptr);
270331
case Version2:
271-
case Version3:
272332
return deserializeV2(Schema, Ptr);
333+
case Version3:
334+
return deserializeV3(Schema, Ptr);
273335
}
274336
llvm_unreachable("unsupported MemProf version");
275337
}

0 commit comments

Comments
 (0)