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
19struct MemProfRecord;
20
21// The versions of the indexed MemProf format
23 // Version 0: This version didn't have a version field.
25 // Version 1: Added a version field to the header.
27 // Version 2: Added a call stack table. Under development.
29};
30
33
34// Verify that the minimum and maximum satisfy the obvious constraint.
36
37enum class Meta : uint64_t {
38 Start = 0,
39#define MIBEntryDef(NameTag, Name, Type) NameTag,
41#undef MIBEntryDef
42 Size
43};
44
46
47// Returns the full schema currently in use.
49
50// Returns the schema consisting of the fields used for hot cold memory hinting.
52
53// Holds the actual MemInfoBlock data with all fields. Contents may be read or
54// written partially by providing an appropriate schema to the serialize and
55// deserialize methods.
58 explicit PortableMemInfoBlock(const MemInfoBlock &Block) {
59#define MIBEntryDef(NameTag, Name, Type) Name = Block.Name;
61#undef MIBEntryDef
62 }
63
64 PortableMemInfoBlock(const MemProfSchema &Schema, const unsigned char *Ptr) {
65 deserialize(Schema, Ptr);
66 }
67
68 // Read the contents of \p Ptr based on the \p Schema to populate the
69 // MemInfoBlock member.
70 void deserialize(const MemProfSchema &Schema, const unsigned char *Ptr) {
71 using namespace support;
72
73 for (const Meta Id : Schema) {
74 switch (Id) {
75#define MIBEntryDef(NameTag, Name, Type) \
76 case Meta::Name: { \
77 Name = endian::readNext<Type, llvm::endianness::little>(Ptr); \
78 } break;
80#undef MIBEntryDef
81 default:
82 llvm_unreachable("Unknown meta type id, is the profile collected from "
83 "a newer version of the runtime?");
84 }
85 }
86 }
87
88 // Write the contents of the MemInfoBlock based on the \p Schema provided to
89 // the raw_ostream \p OS.
90 void serialize(const MemProfSchema &Schema, raw_ostream &OS) const {
91 using namespace support;
92
94 for (const Meta Id : Schema) {
95 switch (Id) {
96#define MIBEntryDef(NameTag, Name, Type) \
97 case Meta::Name: { \
98 LE.write<Type>(Name); \
99 } break;
101#undef MIBEntryDef
102 default:
103 llvm_unreachable("Unknown meta type id, invalid input?");
104 }
105 }
106 }
107
108 // Print out the contents of the MemInfoBlock in YAML format.
109 void printYAML(raw_ostream &OS) const {
110 OS << " MemInfoBlock:\n";
111#define MIBEntryDef(NameTag, Name, Type) \
112 OS << " " << #Name << ": " << Name << "\n";
114#undef MIBEntryDef
115 }
116
117 // Define getters for each type which can be called by analyses.
118#define MIBEntryDef(NameTag, Name, Type) \
119 Type get##Name() const { return Name; }
121#undef MIBEntryDef
122
123 void clear() { *this = PortableMemInfoBlock(); }
124
126#define MIBEntryDef(NameTag, Name, Type) \
127 if (Other.get##Name() != get##Name()) \
128 return false;
130#undef MIBEntryDef
131 return true;
132 }
133
135 return !operator==(Other);
136 }
137
138 static size_t serializedSize(const MemProfSchema &Schema) {
139 size_t Result = 0;
140
141 for (const Meta Id : Schema) {
142 switch (Id) {
143#define MIBEntryDef(NameTag, Name, Type) \
144 case Meta::Name: { \
145 Result += sizeof(Type); \
146 } break;
148#undef MIBEntryDef
149 default:
150 llvm_unreachable("Unknown meta type id, invalid input?");
151 }
152 }
153
154 return Result;
155 }
156
157private:
158#define MIBEntryDef(NameTag, Name, Type) Type Name = Type();
160#undef MIBEntryDef
161};
162
163// A type representing the id generated by hashing the contents of the Frame.
165// Describes a call frame for a dynamic allocation context. The contents of
166// the frame are populated by symbolizing the stack depot call frame from the
167// compiler runtime.
168struct Frame {
169 // A uuid (uint64_t) identifying the function. It is obtained by
170 // llvm::md5(FunctionName) which returns the lower 64 bits.
172 // The symbol name for the function. Only populated in the Frame by the reader
173 // if requested during initialization. This field should not be serialized.
174 std::optional<std::string> SymbolName;
175 // The source line offset of the call from the beginning of parent function.
177 // The source column number of the call to help distinguish multiple calls
178 // on the same line.
180 // Whether the current frame is inlined.
182
183 Frame(const Frame &Other) {
184 Function = Other.Function;
185 SymbolName = Other.SymbolName;
186 LineOffset = Other.LineOffset;
187 Column = Other.Column;
188 IsInlineFrame = Other.IsInlineFrame;
189 }
190
191 Frame(uint64_t Hash, uint32_t Off, uint32_t Col, bool Inline)
192 : Function(Hash), LineOffset(Off), Column(Col), IsInlineFrame(Inline) {}
193
194 bool operator==(const Frame &Other) const {
195 // Ignore the SymbolName field to avoid a string compare. Comparing the
196 // function hash serves the same purpose.
197 return Other.Function == Function && Other.LineOffset == LineOffset &&
198 Other.Column == Column && Other.IsInlineFrame == IsInlineFrame;
199 }
200
202 Function = Other.Function;
203 SymbolName = Other.SymbolName;
204 LineOffset = Other.LineOffset;
205 Column = Other.Column;
206 IsInlineFrame = Other.IsInlineFrame;
207 return *this;
208 }
209
210 bool operator!=(const Frame &Other) const { return !operator==(Other); }
211
212 // Write the contents of the frame to the ostream \p OS.
213 void serialize(raw_ostream &OS) const {
214 using namespace support;
215
217
218 // If the type of the GlobalValue::GUID changes, then we need to update
219 // the reader and the writer.
220 static_assert(std::is_same<GlobalValue::GUID, uint64_t>::value,
221 "Expect GUID to be uint64_t.");
222 LE.write<uint64_t>(Function);
223
224 LE.write<uint32_t>(LineOffset);
225 LE.write<uint32_t>(Column);
226 LE.write<bool>(IsInlineFrame);
227 }
228
229 // Read a frame from char data which has been serialized as little endian.
230 static Frame deserialize(const unsigned char *Ptr) {
231 using namespace support;
232
233 const uint64_t F =
234 endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
235 const uint32_t L =
236 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
237 const uint32_t C =
238 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
239 const bool I = endian::readNext<bool, llvm::endianness::little>(Ptr);
240 return Frame(/*Function=*/F, /*LineOffset=*/L, /*Column=*/C,
241 /*IsInlineFrame=*/I);
242 }
243
244 // Returns the size of the frame information.
245 static constexpr size_t serializedSize() {
246 return sizeof(Frame::Function) + sizeof(Frame::LineOffset) +
247 sizeof(Frame::Column) + sizeof(Frame::IsInlineFrame);
248 }
249
250 // Print the frame information in YAML format.
251 void printYAML(raw_ostream &OS) const {
252 OS << " -\n"
253 << " Function: " << Function << "\n"
254 << " SymbolName: " << SymbolName.value_or("<None>") << "\n"
255 << " LineOffset: " << LineOffset << "\n"
256 << " Column: " << Column << "\n"
257 << " Inline: " << IsInlineFrame << "\n";
258 }
259
260 // Return a hash value based on the contents of the frame. Here we don't use
261 // hashing from llvm ADT since we are going to persist the hash id, the hash
262 // combine algorithm in ADT uses a new randomized seed each time.
263 inline FrameId hash() const {
264 auto HashCombine = [](auto Value, size_t Seed) {
265 std::hash<decltype(Value)> Hasher;
266 // The constant used below is the 64 bit representation of the fractional
267 // part of the golden ratio. Used here for the randomness in their bit
268 // pattern.
269 return Hasher(Value) + 0x9e3779b97f4a7c15 + (Seed << 6) + (Seed >> 2);
270 };
271
272 size_t Result = 0;
273 Result ^= HashCombine(Function, Result);
274 Result ^= HashCombine(LineOffset, Result);
275 Result ^= HashCombine(Column, Result);
276 Result ^= HashCombine(IsInlineFrame, Result);
277 return static_cast<FrameId>(Result);
278 }
279};
280
281// A type representing the index into the table of call stacks.
283
284// Holds allocation information in a space efficient format where frames are
285// represented using unique identifiers.
287 // The dynamic calling context for the allocation in bottom-up (leaf-to-root)
288 // order. Frame contents are stored out-of-line.
289 // TODO: Remove once we fully transition to CSId.
291 // Conceptually the same as above. We are going to keep both CallStack and
292 // CallStackId while we are transitioning from CallStack to CallStackId.
294 // The statistics obtained from the runtime for the allocation.
296
299 const MemInfoBlock &MB)
300 : CallStack(CS.begin(), CS.end()), CSId(CSId), Info(MB) {}
301
302 // Returns the size in bytes when this allocation info struct is serialized.
303 size_t serializedSize(const MemProfSchema &Schema,
304 IndexedVersion Version) const;
305
307 if (Other.Info != Info)
308 return false;
309
310 if (Other.CSId != CSId)
311 return false;
312 return true;
313 }
314
316 return !operator==(Other);
317 }
318};
319
320// Holds allocation information with frame contents inline. The type should
321// be used for temporary in-memory instances.
323 // Same as IndexedAllocationInfo::CallStack with the frame contents inline.
325 // Same as IndexedAllocationInfo::Info;
327
328 AllocationInfo() = default;
330 const IndexedAllocationInfo &IndexedAI,
331 llvm::function_ref<const Frame(const FrameId)> IdToFrameCallback) {
332 for (const FrameId &Id : IndexedAI.CallStack) {
333 CallStack.push_back(IdToFrameCallback(Id));
334 }
335 Info = IndexedAI.Info;
336 }
337
338 void printYAML(raw_ostream &OS) const {
339 OS << " -\n";
340 OS << " Callstack:\n";
341 // TODO: Print out the frame on one line with to make it easier for deep
342 // callstacks once we have a test to check valid YAML is generated.
343 for (const Frame &F : CallStack) {
344 F.printYAML(OS);
345 }
347 }
348};
349
350// Holds the memprof profile information for a function. The internal
351// representation stores frame ids for efficiency. This representation should
352// be used in the profile conversion and manipulation tools.
354 // Memory allocation sites in this function for which we have memory
355 // profiling data.
357 // Holds call sites in this function which are part of some memory
358 // allocation context. We store this as a list of locations, each with its
359 // list of inline locations in bottom-up order i.e. from leaf to root. The
360 // inline location list may include additional entries, users should pick
361 // the last entry in the list with the same function GUID.
363 // Conceptually the same as above. We are going to keep both CallSites and
364 // CallSiteIds while we are transitioning from CallSites to CallSiteIds.
366
367 void clear() {
368 AllocSites.clear();
369 CallSites.clear();
370 }
371
373 // TODO: Filter out duplicates which may occur if multiple memprof
374 // profiles are merged together using llvm-profdata.
375 AllocSites.append(Other.AllocSites);
376 CallSites.append(Other.CallSites);
377 }
378
379 size_t serializedSize(const MemProfSchema &Schema,
380 IndexedVersion Version) const;
381
383 if (Other.AllocSites != AllocSites)
384 return false;
385
386 if (Other.CallSiteIds != CallSiteIds)
387 return false;
388 return true;
389 }
390
391 // Serializes the memprof records in \p Records to the ostream \p OS based
392 // on the schema provided in \p Schema.
393 void serialize(const MemProfSchema &Schema, raw_ostream &OS,
394 IndexedVersion Version);
395
396 // Deserializes memprof records from the Buffer.
398 const unsigned char *Buffer,
399 IndexedVersion Version);
400
401 // Convert IndexedMemProfRecord to MemProfRecord. Callback is used to
402 // translate CallStackId to call stacks with frames inline.
404 std::function<const llvm::SmallVector<Frame>(const CallStackId)> Callback)
405 const;
406
407 // Returns the GUID for the function name after canonicalization. For
408 // memprof, we remove any .llvm suffix added by LTO. MemProfRecords are
409 // mapped to functions using this GUID.
410 static GlobalValue::GUID getGUID(const StringRef FunctionName);
411};
412
413// Holds the memprof profile information for a function. The internal
414// representation stores frame contents inline. This representation should
415// be used for small amount of temporary, in memory instances.
417 // Same as IndexedMemProfRecord::AllocSites with frame contents inline.
419 // Same as IndexedMemProfRecord::CallSites with frame contents inline.
421
422 MemProfRecord() = default;
425 llvm::function_ref<const Frame(const FrameId Id)> IdToFrameCallback) {
426 for (const IndexedAllocationInfo &IndexedAI : Record.AllocSites) {
427 AllocSites.emplace_back(IndexedAI, IdToFrameCallback);
428 }
429 for (const ArrayRef<FrameId> Site : Record.CallSites) {
431 for (const FrameId Id : Site) {
432 Frames.push_back(IdToFrameCallback(Id));
433 }
434 CallSites.push_back(Frames);
435 }
436 }
437
438 // Prints out the contents of the memprof record in YAML.
440 if (!AllocSites.empty()) {
441 OS << " AllocSites:\n";
442 for (const AllocationInfo &N : AllocSites)
443 N.printYAML(OS);
444 }
445
446 if (!CallSites.empty()) {
447 OS << " CallSites:\n";
448 for (const llvm::SmallVector<Frame> &Frames : CallSites) {
449 for (const Frame &F : Frames) {
450 OS << " -\n";
451 F.printYAML(OS);
452 }
453 }
454 }
455 }
456};
457
458// Reads a memprof schema from a buffer. All entries in the buffer are
459// interpreted as uint64_t. The first entry in the buffer denotes the number of
460// ids in the schema. Subsequent entries are integers which map to memprof::Meta
461// enum class entries. After successfully reading the schema, the pointer is one
462// byte past the schema contents.
463Expected<MemProfSchema> readMemProfSchema(const unsigned char *&Buffer);
464
465// Trait for reading IndexedMemProfRecord data from the on-disk hash table.
467public:
473
476 : Version(V), Schema(S) {}
477
478 static bool EqualKey(uint64_t A, uint64_t B) { return A == B; }
479 static uint64_t GetInternalKey(uint64_t K) { return K; }
480 static uint64_t GetExternalKey(uint64_t K) { return K; }
481
483
484 static std::pair<offset_type, offset_type>
485 ReadKeyDataLength(const unsigned char *&D) {
486 using namespace support;
487
488 offset_type KeyLen =
489 endian::readNext<offset_type, llvm::endianness::little>(D);
490 offset_type DataLen =
491 endian::readNext<offset_type, llvm::endianness::little>(D);
492 return std::make_pair(KeyLen, DataLen);
493 }
494
495 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
496 using namespace support;
497 return endian::readNext<external_key_type, llvm::endianness::little>(D);
498 }
499
500 data_type ReadData(uint64_t K, const unsigned char *D,
501 offset_type /*Unused*/) {
502 Record = IndexedMemProfRecord::deserialize(Schema, D, Version);
503 return Record;
504 }
505
506private:
507 // Holds the MemProf version.
508 IndexedVersion Version;
509 // Holds the memprof schema used to deserialize records.
510 MemProfSchema Schema;
511 // Holds the records from one function deserialized from the indexed format.
513};
514
515// Trait for writing IndexedMemProfRecord data to the on-disk hash table.
517public:
520
523
526
527private:
528 // Pointer to the memprof schema to use for the generator.
529 const MemProfSchema *Schema;
530 // The MemProf version to use for the serialization.
531 IndexedVersion Version;
532
533public:
534 // We do not support the default constructor, which does not set Version.
537 : Schema(Schema), Version(V) {}
538
540
541 std::pair<offset_type, offset_type>
543 using namespace support;
544
546 offset_type N = sizeof(K);
547 LE.write<offset_type>(N);
548 offset_type M = V.serializedSize(*Schema, Version);
549 LE.write<offset_type>(M);
550 return std::make_pair(N, M);
551 }
552
553 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
554 using namespace support;
556 LE.write<uint64_t>(K);
557 }
558
560 offset_type /*Unused*/) {
561 assert(Schema != nullptr && "MemProf schema is not initialized!");
562 V.serialize(*Schema, Out, Version);
563 // Clear the IndexedMemProfRecord which results in clearing/freeing its
564 // vectors of allocs and callsites. This is owned by the associated on-disk
565 // hash table, but unused after this point. See also the comment added to
566 // the client which constructs the on-disk hash table for this trait.
567 V.clear();
568 }
569};
570
571// Trait for writing frame mappings to the on-disk hash table.
573public:
576
579
582
584
585 static std::pair<offset_type, offset_type>
587 using namespace support;
589 offset_type N = sizeof(K);
590 LE.write<offset_type>(N);
591 offset_type M = V.serializedSize();
592 LE.write<offset_type>(M);
593 return std::make_pair(N, M);
594 }
595
596 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
597 using namespace support;
599 LE.write<key_type>(K);
600 }
601
603 offset_type /*Unused*/) {
604 V.serialize(Out);
605 }
606};
607
608// Trait for reading frame mappings from the on-disk hash table.
610public:
611 using data_type = const Frame;
616
618 return A == B;
619 }
622
624
625 static std::pair<offset_type, offset_type>
626 ReadKeyDataLength(const unsigned char *&D) {
627 using namespace support;
628
629 offset_type KeyLen =
630 endian::readNext<offset_type, llvm::endianness::little>(D);
631 offset_type DataLen =
632 endian::readNext<offset_type, llvm::endianness::little>(D);
633 return std::make_pair(KeyLen, DataLen);
634 }
635
636 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
637 using namespace support;
638 return endian::readNext<external_key_type, llvm::endianness::little>(D);
639 }
640
641 data_type ReadData(uint64_t K, const unsigned char *D,
642 offset_type /*Unused*/) {
643 return Frame::deserialize(D);
644 }
645};
646
647// Trait for writing call stacks to the on-disk hash table.
649public:
652
655
658
660
661 static std::pair<offset_type, offset_type>
663 using namespace support;
665 // We do not explicitly emit the key length because it is a constant.
666 offset_type N = sizeof(K);
667 offset_type M = sizeof(FrameId) * V.size();
668 LE.write<offset_type>(M);
669 return std::make_pair(N, M);
670 }
671
672 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
673 using namespace support;
675 LE.write<key_type>(K);
676 }
677
679 offset_type /*Unused*/) {
680 using namespace support;
682 // Emit the frames. We do not explicitly emit the length of the vector
683 // because it can be inferred from the data length.
684 for (FrameId F : V)
685 LE.write<FrameId>(F);
686 }
687};
688
689// Trait for reading call stack mappings from the on-disk hash table.
691public:
697
699 return A == B;
700 }
703
705
706 static std::pair<offset_type, offset_type>
707 ReadKeyDataLength(const unsigned char *&D) {
708 using namespace support;
709
710 // We do not explicitly read the key length because it is a constant.
711 offset_type KeyLen = sizeof(external_key_type);
712 offset_type DataLen =
713 endian::readNext<offset_type, llvm::endianness::little>(D);
714 return std::make_pair(KeyLen, DataLen);
715 }
716
717 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
718 using namespace support;
719 return endian::readNext<external_key_type, llvm::endianness::little>(D);
720 }
721
722 data_type ReadData(uint64_t K, const unsigned char *D, offset_type Length) {
723 using namespace support;
725 // Derive the number of frames from the data length.
726 uint64_t NumFrames = Length / sizeof(FrameId);
727 assert(Length % sizeof(FrameId) == 0);
728 CS.reserve(NumFrames);
729 for (size_t I = 0; I != NumFrames; ++I) {
730 FrameId F = endian::readNext<FrameId, llvm::endianness::little>(D);
731 CS.push_back(F);
732 }
733 return CS;
734 }
735};
736
737// Compute a CallStackId for a given call stack.
739
740// Verify that each CallStackId is computed with hashCallStack. This function
741// is intended to help transition from CallStack to CSId in
742// IndexedAllocationInfo.
743void verifyIndexedMemProfRecord(const IndexedMemProfRecord &Record);
744
745// Verify that each CallStackId is computed with hashCallStack. This function
746// is intended to help transition from CallStack to CSId in
747// IndexedAllocationInfo.
750 &FunctionProfileData);
751} // namespace memprof
752} // namespace llvm
753
754#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:587
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
void reserve(size_type N)
Definition: SmallVector.h:676
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.
static uint64_t GetInternalKey(internal_key_type K)
Definition: MemProf.h:701
hash_value_type ComputeHash(internal_key_type K)
Definition: MemProf.h:704
static bool EqualKey(internal_key_type A, internal_key_type B)
Definition: MemProf.h:698
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:707
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:717
data_type ReadData(uint64_t K, const unsigned char *D, offset_type Length)
Definition: MemProf.h:722
static uint64_t GetExternalKey(external_key_type K)
Definition: MemProf.h:702
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:659
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:662
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:678
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:672
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:641
static uint64_t GetExternalKey(external_key_type K)
Definition: MemProf.h:621
static bool EqualKey(internal_key_type A, internal_key_type B)
Definition: MemProf.h:617
static uint64_t GetInternalKey(internal_key_type K)
Definition: MemProf.h:620
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:626
hash_value_type ComputeHash(internal_key_type K)
Definition: MemProf.h:623
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:636
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:583
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:596
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:602
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:586
static bool EqualKey(uint64_t A, uint64_t B)
Definition: MemProf.h:478
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:495
data_type ReadData(uint64_t K, const unsigned char *D, offset_type)
Definition: MemProf.h:500
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:485
static uint64_t GetInternalKey(uint64_t K)
Definition: MemProf.h:479
hash_value_type ComputeHash(uint64_t K)
Definition: MemProf.h:482
static uint64_t GetExternalKey(uint64_t K)
Definition: MemProf.h:480
RecordLookupTrait(IndexedVersion V, const MemProfSchema &S)
Definition: MemProf.h:475
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:539
std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:542
RecordWriterTrait(const MemProfSchema *Schema, IndexedVersion V)
Definition: MemProf.h:536
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:553
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:559
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:316
constexpr uint64_t MaximumSupportedVersion
Definition: MemProf.h:32
MemProfSchema getHotColdSchema()
Definition: MemProf.cpp:21
CallStackId hashCallStack(ArrayRef< FrameId > CS)
Definition: MemProf.cpp:305
uint64_t FrameId
Definition: MemProf.h:164
constexpr uint64_t MinimumSupportedVersion
Definition: MemProf.h:31
uint64_t CallStackId
Definition: MemProf.h:282
MemProfSchema getFullSchema()
Definition: MemProf.cpp:13
Expected< MemProfSchema > readMemProfSchema(const unsigned char *&Buffer)
Definition: MemProf.cpp:279
void verifyFunctionProfileData(const llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord > &FunctionProfileData)
Definition: MemProf.cpp:323
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:456
@ Other
Any other memory.
#define N
AllocationInfo(const IndexedAllocationInfo &IndexedAI, llvm::function_ref< const Frame(const FrameId)> IdToFrameCallback)
Definition: MemProf.h:329
PortableMemInfoBlock Info
Definition: MemProf.h:326
llvm::SmallVector< Frame > CallStack
Definition: MemProf.h:324
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:338
Frame & operator=(const Frame &Other)
Definition: MemProf.h:201
Frame(const Frame &Other)
Definition: MemProf.h:183
static constexpr size_t serializedSize()
Definition: MemProf.h:245
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:251
GlobalValue::GUID Function
Definition: MemProf.h:171
void serialize(raw_ostream &OS) const
Definition: MemProf.h:213
std::optional< std::string > SymbolName
Definition: MemProf.h:174
Frame(uint64_t Hash, uint32_t Off, uint32_t Col, bool Inline)
Definition: MemProf.h:191
bool operator==(const Frame &Other) const
Definition: MemProf.h:194
bool operator!=(const Frame &Other) const
Definition: MemProf.h:210
static Frame deserialize(const unsigned char *Ptr)
Definition: MemProf.h:230
FrameId hash() const
Definition: MemProf.h:263
uint32_t LineOffset
Definition: MemProf.h:176
bool operator==(const IndexedAllocationInfo &Other) const
Definition: MemProf.h:306
bool operator!=(const IndexedAllocationInfo &Other) const
Definition: MemProf.h:315
PortableMemInfoBlock Info
Definition: MemProf.h:295
size_t serializedSize(const MemProfSchema &Schema, IndexedVersion Version) const
Definition: MemProf.cpp:48
llvm::SmallVector< FrameId > CallStack
Definition: MemProf.h:290
IndexedAllocationInfo(ArrayRef< FrameId > CS, CallStackId CSId, const MemInfoBlock &MB)
Definition: MemProf.h:298
llvm::SmallVector< CallStackId > CallSiteIds
Definition: MemProf.h:365
llvm::SmallVector< IndexedAllocationInfo > AllocSites
Definition: MemProf.h:356
size_t serializedSize(const MemProfSchema &Schema, IndexedVersion Version) const
Definition: MemProf.cpp:91
static IndexedMemProfRecord deserialize(const MemProfSchema &Schema, const unsigned char *Buffer, IndexedVersion Version)
Definition: MemProf.cpp:232
llvm::SmallVector< llvm::SmallVector< FrameId > > CallSites
Definition: MemProf.h:362
MemProfRecord toMemProfRecord(std::function< const llvm::SmallVector< Frame >(const CallStackId)> Callback) const
Definition: MemProf.cpp:245
bool operator==(const IndexedMemProfRecord &Other) const
Definition: MemProf.h:382
void serialize(const MemProfSchema &Schema, raw_ostream &OS, IndexedVersion Version)
Definition: MemProf.cpp:144
static GlobalValue::GUID getGUID(const StringRef FunctionName)
Definition: MemProf.cpp:263
void merge(const IndexedMemProfRecord &Other)
Definition: MemProf.h:372
llvm::SmallVector< AllocationInfo > AllocSites
Definition: MemProf.h:418
void print(llvm::raw_ostream &OS) const
Definition: MemProf.h:439
MemProfRecord(const IndexedMemProfRecord &Record, llvm::function_ref< const Frame(const FrameId Id)> IdToFrameCallback)
Definition: MemProf.h:423
llvm::SmallVector< llvm::SmallVector< Frame > > CallSites
Definition: MemProf.h:420
bool operator!=(const PortableMemInfoBlock &Other) const
Definition: MemProf.h:134
PortableMemInfoBlock(const MemInfoBlock &Block)
Definition: MemProf.h:58
PortableMemInfoBlock(const MemProfSchema &Schema, const unsigned char *Ptr)
Definition: MemProf.h:64
static size_t serializedSize(const MemProfSchema &Schema)
Definition: MemProf.h:138
void deserialize(const MemProfSchema &Schema, const unsigned char *Ptr)
Definition: MemProf.h:70
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:109
void serialize(const MemProfSchema &Schema, raw_ostream &OS) const
Definition: MemProf.h:90
bool operator==(const PortableMemInfoBlock &Other) const
Definition: MemProf.h:125
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:67