LLVM 19.0.0git
MemProf.h
Go to the documentation of this file.
1#ifndef LLVM_PROFILEDATA_MEMPROF_H_
2#define LLVM_PROFILEDATA_MEMPROF_H_
3
12
13#include <cstdint>
14#include <optional>
15
16namespace llvm {
17namespace memprof {
18
19enum class Meta : uint64_t {
20 Start = 0,
21#define MIBEntryDef(NameTag, Name, Type) NameTag,
23#undef MIBEntryDef
24 Size
25};
26
28
29// Holds the actual MemInfoBlock data with all fields. Contents may be read or
30// written partially by providing an appropriate schema to the serialize and
31// deserialize methods.
34 explicit PortableMemInfoBlock(const MemInfoBlock &Block) {
35#define MIBEntryDef(NameTag, Name, Type) Name = Block.Name;
37#undef MIBEntryDef
38 }
39
40 PortableMemInfoBlock(const MemProfSchema &Schema, const unsigned char *Ptr) {
41 deserialize(Schema, Ptr);
42 }
43
44 // Read the contents of \p Ptr based on the \p Schema to populate the
45 // MemInfoBlock member.
46 void deserialize(const MemProfSchema &Schema, const unsigned char *Ptr) {
47 using namespace support;
48
49 for (const Meta Id : Schema) {
50 switch (Id) {
51#define MIBEntryDef(NameTag, Name, Type) \
52 case Meta::Name: { \
53 Name = endian::readNext<Type, llvm::endianness::little, unaligned>(Ptr); \
54 } break;
56#undef MIBEntryDef
57 default:
58 llvm_unreachable("Unknown meta type id, is the profile collected from "
59 "a newer version of the runtime?");
60 }
61 }
62 }
63
64 // Write the contents of the MemInfoBlock based on the \p Schema provided to
65 // the raw_ostream \p OS.
66 void serialize(const MemProfSchema &Schema, raw_ostream &OS) const {
67 using namespace support;
68
70 for (const Meta Id : Schema) {
71 switch (Id) {
72#define MIBEntryDef(NameTag, Name, Type) \
73 case Meta::Name: { \
74 LE.write<Type>(Name); \
75 } break;
77#undef MIBEntryDef
78 default:
79 llvm_unreachable("Unknown meta type id, invalid input?");
80 }
81 }
82 }
83
84 // Print out the contents of the MemInfoBlock in YAML format.
85 void printYAML(raw_ostream &OS) const {
86 OS << " MemInfoBlock:\n";
87#define MIBEntryDef(NameTag, Name, Type) \
88 OS << " " << #Name << ": " << Name << "\n";
90#undef MIBEntryDef
91 }
92
93 // Define getters for each type which can be called by analyses.
94#define MIBEntryDef(NameTag, Name, Type) \
95 Type get##Name() const { return Name; }
97#undef MIBEntryDef
98
99 void clear() { *this = PortableMemInfoBlock(); }
100
101 // Returns the full schema currently in use.
104#define MIBEntryDef(NameTag, Name, Type) List.push_back(Meta::Name);
106#undef MIBEntryDef
107 return List;
108 }
109
111#define MIBEntryDef(NameTag, Name, Type) \
112 if (Other.get##Name() != get##Name()) \
113 return false;
115#undef MIBEntryDef
116 return true;
117 }
118
120 return !operator==(Other);
121 }
122
123 static constexpr size_t serializedSize() {
124 size_t Result = 0;
125#define MIBEntryDef(NameTag, Name, Type) Result += sizeof(Type);
127#undef MIBEntryDef
128 return Result;
129 }
130
131private:
132#define MIBEntryDef(NameTag, Name, Type) Type Name = Type();
134#undef MIBEntryDef
135};
136
137// A type representing the id generated by hashing the contents of the Frame.
139// Describes a call frame for a dynamic allocation context. The contents of
140// the frame are populated by symbolizing the stack depot call frame from the
141// compiler runtime.
142struct Frame {
143 // A uuid (uint64_t) identifying the function. It is obtained by
144 // llvm::md5(FunctionName) which returns the lower 64 bits.
146 // The symbol name for the function. Only populated in the Frame by the reader
147 // if requested during initialization. This field should not be serialized.
148 std::optional<std::string> SymbolName;
149 // The source line offset of the call from the beginning of parent function.
151 // The source column number of the call to help distinguish multiple calls
152 // on the same line.
154 // Whether the current frame is inlined.
156
157 Frame(const Frame &Other) {
158 Function = Other.Function;
159 SymbolName = Other.SymbolName;
160 LineOffset = Other.LineOffset;
161 Column = Other.Column;
162 IsInlineFrame = Other.IsInlineFrame;
163 }
164
165 Frame(uint64_t Hash, uint32_t Off, uint32_t Col, bool Inline)
166 : Function(Hash), LineOffset(Off), Column(Col), IsInlineFrame(Inline) {}
167
168 bool operator==(const Frame &Other) const {
169 // Ignore the SymbolName field to avoid a string compare. Comparing the
170 // function hash serves the same purpose.
171 return Other.Function == Function && Other.LineOffset == LineOffset &&
172 Other.Column == Column && Other.IsInlineFrame == IsInlineFrame;
173 }
174
176 Function = Other.Function;
177 SymbolName = Other.SymbolName;
178 LineOffset = Other.LineOffset;
179 Column = Other.Column;
180 IsInlineFrame = Other.IsInlineFrame;
181 return *this;
182 }
183
184 bool operator!=(const Frame &Other) const { return !operator==(Other); }
185
186 // Write the contents of the frame to the ostream \p OS.
187 void serialize(raw_ostream &OS) const {
188 using namespace support;
189
191
192 // If the type of the GlobalValue::GUID changes, then we need to update
193 // the reader and the writer.
194 static_assert(std::is_same<GlobalValue::GUID, uint64_t>::value,
195 "Expect GUID to be uint64_t.");
196 LE.write<uint64_t>(Function);
197
198 LE.write<uint32_t>(LineOffset);
199 LE.write<uint32_t>(Column);
200 LE.write<bool>(IsInlineFrame);
201 }
202
203 // Read a frame from char data which has been serialized as little endian.
204 static Frame deserialize(const unsigned char *Ptr) {
205 using namespace support;
206
207 const uint64_t F =
208 endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Ptr);
209 const uint32_t L =
210 endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Ptr);
211 const uint32_t C =
212 endian::readNext<uint32_t, llvm::endianness::little, unaligned>(Ptr);
213 const bool I =
214 endian::readNext<bool, llvm::endianness::little, unaligned>(Ptr);
215 return Frame(/*Function=*/F, /*LineOffset=*/L, /*Column=*/C,
216 /*IsInlineFrame=*/I);
217 }
218
219 // Returns the size of the frame information.
220 static constexpr size_t serializedSize() {
221 return sizeof(Frame::Function) + sizeof(Frame::LineOffset) +
222 sizeof(Frame::Column) + sizeof(Frame::IsInlineFrame);
223 }
224
225 // Print the frame information in YAML format.
226 void printYAML(raw_ostream &OS) const {
227 OS << " -\n"
228 << " Function: " << Function << "\n"
229 << " SymbolName: " << SymbolName.value_or("<None>") << "\n"
230 << " LineOffset: " << LineOffset << "\n"
231 << " Column: " << Column << "\n"
232 << " Inline: " << IsInlineFrame << "\n";
233 }
234
235 // Return a hash value based on the contents of the frame. Here we don't use
236 // hashing from llvm ADT since we are going to persist the hash id, the hash
237 // combine algorithm in ADT uses a new randomized seed each time.
238 inline FrameId hash() const {
239 auto HashCombine = [](auto Value, size_t Seed) {
240 std::hash<decltype(Value)> Hasher;
241 // The constant used below is the 64 bit representation of the fractional
242 // part of the golden ratio. Used here for the randomness in their bit
243 // pattern.
244 return Hasher(Value) + 0x9e3779b97f4a7c15 + (Seed << 6) + (Seed >> 2);
245 };
246
247 size_t Result = 0;
248 Result ^= HashCombine(Function, Result);
249 Result ^= HashCombine(LineOffset, Result);
250 Result ^= HashCombine(Column, Result);
251 Result ^= HashCombine(IsInlineFrame, Result);
252 return static_cast<FrameId>(Result);
253 }
254};
255
256// A type representing the index into the table of call stacks.
258
259// Holds allocation information in a space efficient format where frames are
260// represented using unique identifiers.
262 // The dynamic calling context for the allocation in bottom-up (leaf-to-root)
263 // order. Frame contents are stored out-of-line.
264 // TODO: Remove once we fully transition to CSId.
266 // Conceptually the same as above. We are going to keep both CallStack and
267 // CallStackId while we are transitioning from CallStack to CallStackId.
269 // The statistics obtained from the runtime for the allocation.
271
274 const MemInfoBlock &MB)
275 : CallStack(CS.begin(), CS.end()), CSId(CSId), Info(MB) {}
276
277 // Returns the size in bytes when this allocation info struct is serialized.
278 size_t serializedSize() const {
279 return sizeof(uint64_t) + // The number of frames to serialize.
280 sizeof(FrameId) * CallStack.size() + // The callstack frame ids.
281 PortableMemInfoBlock::serializedSize(); // The size of the payload.
282 }
283
285 if (Other.Info != Info)
286 return false;
287
288 if (Other.CallStack.size() != CallStack.size())
289 return false;
290
291 for (size_t J = 0; J < Other.CallStack.size(); J++) {
292 if (Other.CallStack[J] != CallStack[J])
293 return false;
294 }
295 return true;
296 }
297
299 return !operator==(Other);
300 }
301};
302
303// Holds allocation information with frame contents inline. The type should
304// be used for temporary in-memory instances.
306 // Same as IndexedAllocationInfo::CallStack with the frame contents inline.
308 // Same as IndexedAllocationInfo::Info;
310
311 AllocationInfo() = default;
313 const IndexedAllocationInfo &IndexedAI,
314 llvm::function_ref<const Frame(const FrameId)> IdToFrameCallback) {
315 for (const FrameId &Id : IndexedAI.CallStack) {
316 CallStack.push_back(IdToFrameCallback(Id));
317 }
318 Info = IndexedAI.Info;
319 }
320
321 void printYAML(raw_ostream &OS) const {
322 OS << " -\n";
323 OS << " Callstack:\n";
324 // TODO: Print out the frame on one line with to make it easier for deep
325 // callstacks once we have a test to check valid YAML is generated.
326 for (const Frame &F : CallStack) {
327 F.printYAML(OS);
328 }
330 }
331};
332
333// Holds the memprof profile information for a function. The internal
334// representation stores frame ids for efficiency. This representation should
335// be used in the profile conversion and manipulation tools.
337 // Memory allocation sites in this function for which we have memory
338 // profiling data.
340 // Holds call sites in this function which are part of some memory
341 // allocation context. We store this as a list of locations, each with its
342 // list of inline locations in bottom-up order i.e. from leaf to root. The
343 // inline location list may include additional entries, users should pick
344 // the last entry in the list with the same function GUID.
346
347 void clear() {
348 AllocSites.clear();
349 CallSites.clear();
350 }
351
353 // TODO: Filter out duplicates which may occur if multiple memprof
354 // profiles are merged together using llvm-profdata.
355 AllocSites.append(Other.AllocSites);
356 CallSites.append(Other.CallSites);
357 }
358
359 size_t serializedSize() const {
360 size_t Result = sizeof(GlobalValue::GUID);
361 for (const IndexedAllocationInfo &N : AllocSites)
362 Result += N.serializedSize();
363
364 // The number of callsites we have information for.
365 Result += sizeof(uint64_t);
366 for (const auto &Frames : CallSites) {
367 // The number of frame ids to serialize.
368 Result += sizeof(uint64_t);
369 Result += Frames.size() * sizeof(FrameId);
370 }
371 return Result;
372 }
373
375 if (Other.AllocSites.size() != AllocSites.size())
376 return false;
377
378 if (Other.CallSites.size() != CallSites.size())
379 return false;
380
381 for (size_t I = 0; I < AllocSites.size(); I++) {
382 if (AllocSites[I] != Other.AllocSites[I])
383 return false;
384 }
385
386 for (size_t I = 0; I < CallSites.size(); I++) {
387 if (CallSites[I] != Other.CallSites[I])
388 return false;
389 }
390 return true;
391 }
392
393 // Serializes the memprof records in \p Records to the ostream \p OS based
394 // on the schema provided in \p Schema.
395 void serialize(const MemProfSchema &Schema, raw_ostream &OS);
396
397 // Deserializes memprof records from the Buffer.
399 const unsigned char *Buffer);
400
401 // Returns the GUID for the function name after canonicalization. For
402 // memprof, we remove any .llvm suffix added by LTO. MemProfRecords are
403 // mapped to functions using this GUID.
404 static GlobalValue::GUID getGUID(const StringRef FunctionName);
405};
406
407// Holds the memprof profile information for a function. The internal
408// representation stores frame contents inline. This representation should
409// be used for small amount of temporary, in memory instances.
411 // Same as IndexedMemProfRecord::AllocSites with frame contents inline.
413 // Same as IndexedMemProfRecord::CallSites with frame contents inline.
415
416 MemProfRecord() = default;
419 llvm::function_ref<const Frame(const FrameId Id)> IdToFrameCallback) {
420 for (const IndexedAllocationInfo &IndexedAI : Record.AllocSites) {
421 AllocSites.emplace_back(IndexedAI, IdToFrameCallback);
422 }
423 for (const ArrayRef<FrameId> Site : Record.CallSites) {
425 for (const FrameId Id : Site) {
426 Frames.push_back(IdToFrameCallback(Id));
427 }
428 CallSites.push_back(Frames);
429 }
430 }
431
432 // Prints out the contents of the memprof record in YAML.
434 if (!AllocSites.empty()) {
435 OS << " AllocSites:\n";
436 for (const AllocationInfo &N : AllocSites)
437 N.printYAML(OS);
438 }
439
440 if (!CallSites.empty()) {
441 OS << " CallSites:\n";
442 for (const llvm::SmallVector<Frame> &Frames : CallSites) {
443 for (const Frame &F : Frames) {
444 OS << " -\n";
445 F.printYAML(OS);
446 }
447 }
448 }
449 }
450};
451
452// Reads a memprof schema from a buffer. All entries in the buffer are
453// interpreted as uint64_t. The first entry in the buffer denotes the number of
454// ids in the schema. Subsequent entries are integers which map to memprof::Meta
455// enum class entries. After successfully reading the schema, the pointer is one
456// byte past the schema contents.
457Expected<MemProfSchema> readMemProfSchema(const unsigned char *&Buffer);
458
459// Trait for reading IndexedMemProfRecord data from the on-disk hash table.
461public:
467
469 RecordLookupTrait(const MemProfSchema &S) : Schema(S) {}
470
471 static bool EqualKey(uint64_t A, uint64_t B) { return A == B; }
472 static uint64_t GetInternalKey(uint64_t K) { return K; }
473 static uint64_t GetExternalKey(uint64_t K) { return K; }
474
476
477 static std::pair<offset_type, offset_type>
478 ReadKeyDataLength(const unsigned char *&D) {
479 using namespace support;
480
481 offset_type KeyLen =
482 endian::readNext<offset_type, llvm::endianness::little, unaligned>(D);
483 offset_type DataLen =
484 endian::readNext<offset_type, llvm::endianness::little, unaligned>(D);
485 return std::make_pair(KeyLen, DataLen);
486 }
487
488 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
489 using namespace support;
491 unaligned>(D);
492 }
493
494 data_type ReadData(uint64_t K, const unsigned char *D,
495 offset_type /*Unused*/) {
497 return Record;
498 }
499
500private:
501 // Holds the memprof schema used to deserialize records.
502 MemProfSchema Schema;
503 // Holds the records from one function deserialized from the indexed format.
505};
506
507// Trait for writing IndexedMemProfRecord data to the on-disk hash table.
509public:
512
515
518
519 // Pointer to the memprof schema to use for the generator. Unlike the reader
520 // we must use a default constructor with no params for the writer trait so we
521 // have a public member which must be initialized by the user.
523
524 RecordWriterTrait() = default;
525
527
528 static std::pair<offset_type, offset_type>
530 using namespace support;
531
533 offset_type N = sizeof(K);
534 LE.write<offset_type>(N);
535 offset_type M = V.serializedSize();
536 LE.write<offset_type>(M);
537 return std::make_pair(N, M);
538 }
539
540 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
541 using namespace support;
543 LE.write<uint64_t>(K);
544 }
545
547 offset_type /*Unused*/) {
548 assert(Schema != nullptr && "MemProf schema is not initialized!");
549 V.serialize(*Schema, Out);
550 // Clear the IndexedMemProfRecord which results in clearing/freeing its
551 // vectors of allocs and callsites. This is owned by the associated on-disk
552 // hash table, but unused after this point. See also the comment added to
553 // the client which constructs the on-disk hash table for this trait.
554 V.clear();
555 }
556};
557
558// Trait for writing frame mappings to the on-disk hash table.
560public:
563
566
569
571
572 static std::pair<offset_type, offset_type>
574 using namespace support;
576 offset_type N = sizeof(K);
577 LE.write<offset_type>(N);
578 offset_type M = V.serializedSize();
579 LE.write<offset_type>(M);
580 return std::make_pair(N, M);
581 }
582
583 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
584 using namespace support;
586 LE.write<key_type>(K);
587 }
588
590 offset_type /*Unused*/) {
591 V.serialize(Out);
592 }
593};
594
595// Trait for reading frame mappings from the on-disk hash table.
597public:
598 using data_type = const Frame;
603
605 return A == B;
606 }
609
611
612 static std::pair<offset_type, offset_type>
613 ReadKeyDataLength(const unsigned char *&D) {
614 using namespace support;
615
616 offset_type KeyLen =
617 endian::readNext<offset_type, llvm::endianness::little, unaligned>(D);
618 offset_type DataLen =
619 endian::readNext<offset_type, llvm::endianness::little, unaligned>(D);
620 return std::make_pair(KeyLen, DataLen);
621 }
622
623 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
624 using namespace support;
626 unaligned>(D);
627 }
628
629 data_type ReadData(uint64_t K, const unsigned char *D,
630 offset_type /*Unused*/) {
631 return Frame::deserialize(D);
632 }
633};
634
635// Compute a CallStackId for a given call stack.
637
638// Verify that each CallStackId is computed with hashCallStack. This function
639// is intended to help transition from CallStack to CSId in
640// IndexedAllocationInfo.
641void verifyIndexedMemProfRecord(const IndexedMemProfRecord &Record);
642
643// Verify that each CallStackId is computed with hashCallStack. This function
644// is intended to help transition from CallStack to CSId in
645// IndexedAllocationInfo.
648 &FunctionProfileData);
649} // namespace memprof
650} // namespace llvm
651
652#endif // LLVM_PROFILEDATA_MEMPROF_H_
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file implements a map that provides insertion order iteration.
static ManagedStatic< cl::opt< uint64_t >, CreateSeed > Seed
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Tagged union holding either a T or a Error.
Definition: Error.h:474
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
Definition: GlobalValue.h:586
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
void push_back(const T &Elt)
Definition: SmallVector.h:426
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
LLVM Value Representation.
Definition: Value.h:74
An efficient, type-erasing, non-owning reference to a callable.
Helper class to iterate through stack ids in both metadata (memprof MIB and callsite) and the corresp...
data_type ReadData(uint64_t K, const unsigned char *D, offset_type)
Definition: MemProf.h:629
static uint64_t GetExternalKey(external_key_type K)
Definition: MemProf.h:608
static bool EqualKey(internal_key_type A, internal_key_type B)
Definition: MemProf.h:604
static uint64_t GetInternalKey(internal_key_type K)
Definition: MemProf.h:607
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:613
hash_value_type ComputeHash(internal_key_type K)
Definition: MemProf.h:610
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:623
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:570
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:583
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:589
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:573
static bool EqualKey(uint64_t A, uint64_t B)
Definition: MemProf.h:471
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:488
data_type ReadData(uint64_t K, const unsigned char *D, offset_type)
Definition: MemProf.h:494
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:478
static uint64_t GetInternalKey(uint64_t K)
Definition: MemProf.h:472
hash_value_type ComputeHash(uint64_t K)
Definition: MemProf.h:475
static uint64_t GetExternalKey(uint64_t K)
Definition: MemProf.h:473
RecordLookupTrait(const MemProfSchema &S)
Definition: MemProf.h:469
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:529
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:526
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:540
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:546
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
void verifyIndexedMemProfRecord(const IndexedMemProfRecord &Record)
Definition: MemProf.cpp:134
CallStackId hashCallStack(ArrayRef< FrameId > CS)
Definition: MemProf.cpp:123
uint64_t FrameId
Definition: MemProf.h:138
uint64_t CallStackId
Definition: MemProf.h:257
Expected< MemProfSchema > readMemProfSchema(const unsigned char *&Buffer)
Definition: MemProf.cpp:97
void verifyFunctionProfileData(const llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord > &FunctionProfileData)
Definition: MemProf.cpp:141
value_type readNext(const CharT *&memory, endianness endian)
Read a value of a particular endianness from a buffer, and increment the buffer past that value.
Definition: Endian.h:76
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Other
Any other memory.
#define N
AllocationInfo(const IndexedAllocationInfo &IndexedAI, llvm::function_ref< const Frame(const FrameId)> IdToFrameCallback)
Definition: MemProf.h:312
PortableMemInfoBlock Info
Definition: MemProf.h:309
llvm::SmallVector< Frame > CallStack
Definition: MemProf.h:307
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:321
Frame & operator=(const Frame &Other)
Definition: MemProf.h:175
Frame(const Frame &Other)
Definition: MemProf.h:157
static constexpr size_t serializedSize()
Definition: MemProf.h:220
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:226
GlobalValue::GUID Function
Definition: MemProf.h:145
void serialize(raw_ostream &OS) const
Definition: MemProf.h:187
std::optional< std::string > SymbolName
Definition: MemProf.h:148
Frame(uint64_t Hash, uint32_t Off, uint32_t Col, bool Inline)
Definition: MemProf.h:165
bool operator==(const Frame &Other) const
Definition: MemProf.h:168
bool operator!=(const Frame &Other) const
Definition: MemProf.h:184
static Frame deserialize(const unsigned char *Ptr)
Definition: MemProf.h:204
FrameId hash() const
Definition: MemProf.h:238
uint32_t LineOffset
Definition: MemProf.h:150
bool operator==(const IndexedAllocationInfo &Other) const
Definition: MemProf.h:284
bool operator!=(const IndexedAllocationInfo &Other) const
Definition: MemProf.h:298
PortableMemInfoBlock Info
Definition: MemProf.h:270
llvm::SmallVector< FrameId > CallStack
Definition: MemProf.h:265
IndexedAllocationInfo(ArrayRef< FrameId > CS, CallStackId CSId, const MemInfoBlock &MB)
Definition: MemProf.h:273
llvm::SmallVector< IndexedAllocationInfo > AllocSites
Definition: MemProf.h:339
void serialize(const MemProfSchema &Schema, raw_ostream &OS)
Definition: MemProf.cpp:14
llvm::SmallVector< llvm::SmallVector< FrameId > > CallSites
Definition: MemProf.h:345
bool operator==(const IndexedMemProfRecord &Other) const
Definition: MemProf.h:374
static GlobalValue::GUID getGUID(const StringRef FunctionName)
Definition: MemProf.cpp:81
static IndexedMemProfRecord deserialize(const MemProfSchema &Schema, const unsigned char *Buffer)
Definition: MemProf.cpp:38
void merge(const IndexedMemProfRecord &Other)
Definition: MemProf.h:352
llvm::SmallVector< AllocationInfo > AllocSites
Definition: MemProf.h:412
void print(llvm::raw_ostream &OS) const
Definition: MemProf.h:433
MemProfRecord(const IndexedMemProfRecord &Record, llvm::function_ref< const Frame(const FrameId Id)> IdToFrameCallback)
Definition: MemProf.h:417
llvm::SmallVector< llvm::SmallVector< Frame > > CallSites
Definition: MemProf.h:414
bool operator!=(const PortableMemInfoBlock &Other) const
Definition: MemProf.h:119
PortableMemInfoBlock(const MemInfoBlock &Block)
Definition: MemProf.h:34
PortableMemInfoBlock(const MemProfSchema &Schema, const unsigned char *Ptr)
Definition: MemProf.h:40
static MemProfSchema getSchema()
Definition: MemProf.h:102
void deserialize(const MemProfSchema &Schema, const unsigned char *Ptr)
Definition: MemProf.h:46
static constexpr size_t serializedSize()
Definition: MemProf.h:123
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:85
void serialize(const MemProfSchema &Schema, raw_ostream &OS) const
Definition: MemProf.h:66
bool operator==(const PortableMemInfoBlock &Other) const
Definition: MemProf.h:110
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:67