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
10#include "llvm/Support/Endian.h"
13
14#include <bitset>
15#include <cstdint>
16#include <optional>
17
18namespace llvm {
19namespace memprof {
20
21struct MemProfRecord;
22
23// The versions of the indexed MemProf format
25 // Version 0: This version didn't have a version field.
27 // Version 1: Added a version field to the header.
29 // Version 2: Added a call stack table. Under development.
31};
32
35
36// Verify that the minimum and maximum satisfy the obvious constraint.
38
39enum class Meta : uint64_t {
40 Start = 0,
41#define MIBEntryDef(NameTag, Name, Type) NameTag,
43#undef MIBEntryDef
44 Size
45};
46
48
49// Returns the full schema currently in use.
51
52// Returns the schema consisting of the fields used for hot cold memory hinting.
54
55// Holds the actual MemInfoBlock data with all fields. Contents may be read or
56// written partially by providing an appropriate schema to the serialize and
57// deserialize methods.
60 explicit PortableMemInfoBlock(const MemInfoBlock &Block,
61 const MemProfSchema &IncomingSchema) {
62 for (const Meta Id : IncomingSchema)
63 Schema.set(llvm::to_underlying(Id));
64#define MIBEntryDef(NameTag, Name, Type) Name = Block.Name;
66#undef MIBEntryDef
67 }
68
69 PortableMemInfoBlock(const MemProfSchema &Schema, const unsigned char *Ptr) {
70 deserialize(Schema, Ptr);
71 }
72
73 // Read the contents of \p Ptr based on the \p Schema to populate the
74 // MemInfoBlock member.
75 void deserialize(const MemProfSchema &IncomingSchema,
76 const unsigned char *Ptr) {
77 using namespace support;
78
79 Schema.reset();
80 for (const Meta Id : IncomingSchema) {
81 switch (Id) {
82#define MIBEntryDef(NameTag, Name, Type) \
83 case Meta::Name: { \
84 Name = endian::readNext<Type, llvm::endianness::little>(Ptr); \
85 } break;
87#undef MIBEntryDef
88 default:
89 llvm_unreachable("Unknown meta type id, is the profile collected from "
90 "a newer version of the runtime?");
91 }
92
93 Schema.set(llvm::to_underlying(Id));
94 }
95 }
96
97 // Write the contents of the MemInfoBlock based on the \p Schema provided to
98 // the raw_ostream \p OS.
99 void serialize(const MemProfSchema &Schema, raw_ostream &OS) const {
100 using namespace support;
101
103 for (const Meta Id : Schema) {
104 switch (Id) {
105#define MIBEntryDef(NameTag, Name, Type) \
106 case Meta::Name: { \
107 LE.write<Type>(Name); \
108 } break;
110#undef MIBEntryDef
111 default:
112 llvm_unreachable("Unknown meta type id, invalid input?");
113 }
114 }
115 }
116
117 // Print out the contents of the MemInfoBlock in YAML format.
118 void printYAML(raw_ostream &OS) const {
119 OS << " MemInfoBlock:\n";
120#define MIBEntryDef(NameTag, Name, Type) \
121 OS << " " << #Name << ": " << Name << "\n";
123#undef MIBEntryDef
124 }
125
126 // Return the schema, only for unit tests.
128 return Schema;
129 }
130
131 // Define getters for each type which can be called by analyses.
132#define MIBEntryDef(NameTag, Name, Type) \
133 Type get##Name() const { \
134 assert(Schema[llvm::to_underlying(Meta::Name)]); \
135 return Name; \
136 }
138#undef MIBEntryDef
139
140 void clear() { *this = PortableMemInfoBlock(); }
141
143 if (Other.Schema != Schema)
144 return false;
145
146#define MIBEntryDef(NameTag, Name, Type) \
147 if (Schema[llvm::to_underlying(Meta::Name)] && \
148 Other.get##Name() != get##Name()) \
149 return false;
151#undef MIBEntryDef
152 return true;
153 }
154
156 return !operator==(Other);
157 }
158
159 static size_t serializedSize(const MemProfSchema &Schema) {
160 size_t Result = 0;
161
162 for (const Meta Id : Schema) {
163 switch (Id) {
164#define MIBEntryDef(NameTag, Name, Type) \
165 case Meta::Name: { \
166 Result += sizeof(Type); \
167 } break;
169#undef MIBEntryDef
170 default:
171 llvm_unreachable("Unknown meta type id, invalid input?");
172 }
173 }
174
175 return Result;
176 }
177
178private:
179 // The set of available fields, indexed by Meta::Name.
180 std::bitset<llvm::to_underlying(Meta::Size)> Schema;
181
182#define MIBEntryDef(NameTag, Name, Type) Type Name = Type();
184#undef MIBEntryDef
185};
186
187// A type representing the id generated by hashing the contents of the Frame.
189// Describes a call frame for a dynamic allocation context. The contents of
190// the frame are populated by symbolizing the stack depot call frame from the
191// compiler runtime.
192struct Frame {
193 // A uuid (uint64_t) identifying the function. It is obtained by
194 // llvm::md5(FunctionName) which returns the lower 64 bits.
196 // The symbol name for the function. Only populated in the Frame by the reader
197 // if requested during initialization. This field should not be serialized.
198 std::optional<std::string> SymbolName;
199 // The source line offset of the call from the beginning of parent function.
201 // The source column number of the call to help distinguish multiple calls
202 // on the same line.
204 // Whether the current frame is inlined.
206
207 Frame(const Frame &Other) {
208 Function = Other.Function;
209 SymbolName = Other.SymbolName;
210 LineOffset = Other.LineOffset;
211 Column = Other.Column;
212 IsInlineFrame = Other.IsInlineFrame;
213 }
214
215 Frame(uint64_t Hash, uint32_t Off, uint32_t Col, bool Inline)
216 : Function(Hash), LineOffset(Off), Column(Col), IsInlineFrame(Inline) {}
217
218 bool operator==(const Frame &Other) const {
219 // Ignore the SymbolName field to avoid a string compare. Comparing the
220 // function hash serves the same purpose.
221 return Other.Function == Function && Other.LineOffset == LineOffset &&
222 Other.Column == Column && Other.IsInlineFrame == IsInlineFrame;
223 }
224
226 Function = Other.Function;
227 SymbolName = Other.SymbolName;
228 LineOffset = Other.LineOffset;
229 Column = Other.Column;
230 IsInlineFrame = Other.IsInlineFrame;
231 return *this;
232 }
233
234 bool operator!=(const Frame &Other) const { return !operator==(Other); }
235
236 // Write the contents of the frame to the ostream \p OS.
237 void serialize(raw_ostream &OS) const {
238 using namespace support;
239
241
242 // If the type of the GlobalValue::GUID changes, then we need to update
243 // the reader and the writer.
244 static_assert(std::is_same<GlobalValue::GUID, uint64_t>::value,
245 "Expect GUID to be uint64_t.");
246 LE.write<uint64_t>(Function);
247
248 LE.write<uint32_t>(LineOffset);
249 LE.write<uint32_t>(Column);
250 LE.write<bool>(IsInlineFrame);
251 }
252
253 // Read a frame from char data which has been serialized as little endian.
254 static Frame deserialize(const unsigned char *Ptr) {
255 using namespace support;
256
257 const uint64_t F =
258 endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
259 const uint32_t L =
260 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
261 const uint32_t C =
262 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
263 const bool I = endian::readNext<bool, llvm::endianness::little>(Ptr);
264 return Frame(/*Function=*/F, /*LineOffset=*/L, /*Column=*/C,
265 /*IsInlineFrame=*/I);
266 }
267
268 // Returns the size of the frame information.
269 static constexpr size_t serializedSize() {
270 return sizeof(Frame::Function) + sizeof(Frame::LineOffset) +
271 sizeof(Frame::Column) + sizeof(Frame::IsInlineFrame);
272 }
273
274 // Print the frame information in YAML format.
275 void printYAML(raw_ostream &OS) const {
276 OS << " -\n"
277 << " Function: " << Function << "\n"
278 << " SymbolName: " << SymbolName.value_or("<None>") << "\n"
279 << " LineOffset: " << LineOffset << "\n"
280 << " Column: " << Column << "\n"
281 << " Inline: " << IsInlineFrame << "\n";
282 }
283
284 // Return a hash value based on the contents of the frame. Here we don't use
285 // hashing from llvm ADT since we are going to persist the hash id, the hash
286 // combine algorithm in ADT uses a new randomized seed each time.
287 inline FrameId hash() const {
288 auto HashCombine = [](auto Value, size_t Seed) {
289 std::hash<decltype(Value)> Hasher;
290 // The constant used below is the 64 bit representation of the fractional
291 // part of the golden ratio. Used here for the randomness in their bit
292 // pattern.
293 return Hasher(Value) + 0x9e3779b97f4a7c15 + (Seed << 6) + (Seed >> 2);
294 };
295
296 size_t Result = 0;
297 Result ^= HashCombine(Function, Result);
298 Result ^= HashCombine(LineOffset, Result);
299 Result ^= HashCombine(Column, Result);
300 Result ^= HashCombine(IsInlineFrame, Result);
301 return static_cast<FrameId>(Result);
302 }
303};
304
305// A type representing the index into the table of call stacks.
307
308// Holds allocation information in a space efficient format where frames are
309// represented using unique identifiers.
311 // The dynamic calling context for the allocation in bottom-up (leaf-to-root)
312 // order. Frame contents are stored out-of-line.
313 // TODO: Remove once we fully transition to CSId.
315 // Conceptually the same as above. We are going to keep both CallStack and
316 // CallStackId while we are transitioning from CallStack to CallStackId.
318 // The statistics obtained from the runtime for the allocation.
320
323 const MemInfoBlock &MB,
324 const MemProfSchema &Schema = getFullSchema())
325 : CallStack(CS.begin(), CS.end()), CSId(CSId), Info(MB, Schema) {}
326
327 // Returns the size in bytes when this allocation info struct is serialized.
328 size_t serializedSize(const MemProfSchema &Schema,
329 IndexedVersion Version) const;
330
332 if (Other.Info != Info)
333 return false;
334
335 if (Other.CSId != CSId)
336 return false;
337 return true;
338 }
339
341 return !operator==(Other);
342 }
343};
344
345// Holds allocation information with frame contents inline. The type should
346// be used for temporary in-memory instances.
348 // Same as IndexedAllocationInfo::CallStack with the frame contents inline.
350 // Same as IndexedAllocationInfo::Info;
352
353 AllocationInfo() = default;
355 const IndexedAllocationInfo &IndexedAI,
356 llvm::function_ref<const Frame(const FrameId)> IdToFrameCallback) {
357 for (const FrameId &Id : IndexedAI.CallStack) {
358 CallStack.push_back(IdToFrameCallback(Id));
359 }
360 Info = IndexedAI.Info;
361 }
362
363 void printYAML(raw_ostream &OS) const {
364 OS << " -\n";
365 OS << " Callstack:\n";
366 // TODO: Print out the frame on one line with to make it easier for deep
367 // callstacks once we have a test to check valid YAML is generated.
368 for (const Frame &F : CallStack) {
369 F.printYAML(OS);
370 }
372 }
373};
374
375// Holds the memprof profile information for a function. The internal
376// representation stores frame ids for efficiency. This representation should
377// be used in the profile conversion and manipulation tools.
379 // Memory allocation sites in this function for which we have memory
380 // profiling data.
382 // Holds call sites in this function which are part of some memory
383 // allocation context. We store this as a list of locations, each with its
384 // list of inline locations in bottom-up order i.e. from leaf to root. The
385 // inline location list may include additional entries, users should pick
386 // the last entry in the list with the same function GUID.
388 // Conceptually the same as above. We are going to keep both CallSites and
389 // CallSiteIds while we are transitioning from CallSites to CallSiteIds.
391
392 void clear() {
393 AllocSites.clear();
394 CallSites.clear();
395 }
396
398 // TODO: Filter out duplicates which may occur if multiple memprof
399 // profiles are merged together using llvm-profdata.
400 AllocSites.append(Other.AllocSites);
401 CallSites.append(Other.CallSites);
402 }
403
404 size_t serializedSize(const MemProfSchema &Schema,
405 IndexedVersion Version) const;
406
408 if (Other.AllocSites != AllocSites)
409 return false;
410
411 if (Other.CallSiteIds != CallSiteIds)
412 return false;
413 return true;
414 }
415
416 // Serializes the memprof records in \p Records to the ostream \p OS based
417 // on the schema provided in \p Schema.
418 void serialize(const MemProfSchema &Schema, raw_ostream &OS,
419 IndexedVersion Version);
420
421 // Deserializes memprof records from the Buffer.
423 const unsigned char *Buffer,
424 IndexedVersion Version);
425
426 // Convert IndexedMemProfRecord to MemProfRecord. Callback is used to
427 // translate CallStackId to call stacks with frames inline.
429 std::function<const llvm::SmallVector<Frame>(const CallStackId)> Callback)
430 const;
431
432 // Returns the GUID for the function name after canonicalization. For
433 // memprof, we remove any .llvm suffix added by LTO. MemProfRecords are
434 // mapped to functions using this GUID.
435 static GlobalValue::GUID getGUID(const StringRef FunctionName);
436};
437
438// Holds the memprof profile information for a function. The internal
439// representation stores frame contents inline. This representation should
440// be used for small amount of temporary, in memory instances.
442 // Same as IndexedMemProfRecord::AllocSites with frame contents inline.
444 // Same as IndexedMemProfRecord::CallSites with frame contents inline.
446
447 MemProfRecord() = default;
450 llvm::function_ref<const Frame(const FrameId Id)> IdToFrameCallback) {
451 for (const IndexedAllocationInfo &IndexedAI : Record.AllocSites) {
452 AllocSites.emplace_back(IndexedAI, IdToFrameCallback);
453 }
454 for (const ArrayRef<FrameId> Site : Record.CallSites) {
456 for (const FrameId Id : Site) {
457 Frames.push_back(IdToFrameCallback(Id));
458 }
459 CallSites.push_back(Frames);
460 }
461 }
462
463 // Prints out the contents of the memprof record in YAML.
465 if (!AllocSites.empty()) {
466 OS << " AllocSites:\n";
467 for (const AllocationInfo &N : AllocSites)
468 N.printYAML(OS);
469 }
470
471 if (!CallSites.empty()) {
472 OS << " CallSites:\n";
473 for (const llvm::SmallVector<Frame> &Frames : CallSites) {
474 for (const Frame &F : Frames) {
475 OS << " -\n";
476 F.printYAML(OS);
477 }
478 }
479 }
480 }
481};
482
483// Reads a memprof schema from a buffer. All entries in the buffer are
484// interpreted as uint64_t. The first entry in the buffer denotes the number of
485// ids in the schema. Subsequent entries are integers which map to memprof::Meta
486// enum class entries. After successfully reading the schema, the pointer is one
487// byte past the schema contents.
488Expected<MemProfSchema> readMemProfSchema(const unsigned char *&Buffer);
489
490// Trait for reading IndexedMemProfRecord data from the on-disk hash table.
492public:
498
501 : Version(V), Schema(S) {}
502
503 static bool EqualKey(uint64_t A, uint64_t B) { return A == B; }
504 static uint64_t GetInternalKey(uint64_t K) { return K; }
505 static uint64_t GetExternalKey(uint64_t K) { return K; }
506
508
509 static std::pair<offset_type, offset_type>
510 ReadKeyDataLength(const unsigned char *&D) {
511 using namespace support;
512
513 offset_type KeyLen =
514 endian::readNext<offset_type, llvm::endianness::little>(D);
515 offset_type DataLen =
516 endian::readNext<offset_type, llvm::endianness::little>(D);
517 return std::make_pair(KeyLen, DataLen);
518 }
519
520 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
521 using namespace support;
522 return endian::readNext<external_key_type, llvm::endianness::little>(D);
523 }
524
525 data_type ReadData(uint64_t K, const unsigned char *D,
526 offset_type /*Unused*/) {
527 Record = IndexedMemProfRecord::deserialize(Schema, D, Version);
528 return Record;
529 }
530
531private:
532 // Holds the MemProf version.
533 IndexedVersion Version;
534 // Holds the memprof schema used to deserialize records.
535 MemProfSchema Schema;
536 // Holds the records from one function deserialized from the indexed format.
538};
539
540// Trait for writing IndexedMemProfRecord data to the on-disk hash table.
542public:
545
548
551
552private:
553 // Pointer to the memprof schema to use for the generator.
554 const MemProfSchema *Schema;
555 // The MemProf version to use for the serialization.
556 IndexedVersion Version;
557
558public:
559 // We do not support the default constructor, which does not set Version.
562 : Schema(Schema), Version(V) {}
563
565
566 std::pair<offset_type, offset_type>
568 using namespace support;
569
571 offset_type N = sizeof(K);
572 LE.write<offset_type>(N);
573 offset_type M = V.serializedSize(*Schema, Version);
574 LE.write<offset_type>(M);
575 return std::make_pair(N, M);
576 }
577
578 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
579 using namespace support;
581 LE.write<uint64_t>(K);
582 }
583
585 offset_type /*Unused*/) {
586 assert(Schema != nullptr && "MemProf schema is not initialized!");
587 V.serialize(*Schema, Out, Version);
588 // Clear the IndexedMemProfRecord which results in clearing/freeing its
589 // vectors of allocs and callsites. This is owned by the associated on-disk
590 // hash table, but unused after this point. See also the comment added to
591 // the client which constructs the on-disk hash table for this trait.
592 V.clear();
593 }
594};
595
596// Trait for writing frame mappings to the on-disk hash table.
598public:
601
604
607
609
610 static std::pair<offset_type, offset_type>
612 using namespace support;
614 offset_type N = sizeof(K);
615 LE.write<offset_type>(N);
616 offset_type M = V.serializedSize();
617 LE.write<offset_type>(M);
618 return std::make_pair(N, M);
619 }
620
621 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
622 using namespace support;
624 LE.write<key_type>(K);
625 }
626
628 offset_type /*Unused*/) {
629 V.serialize(Out);
630 }
631};
632
633// Trait for reading frame mappings from the on-disk hash table.
635public:
636 using data_type = const Frame;
641
643 return A == B;
644 }
647
649
650 static std::pair<offset_type, offset_type>
651 ReadKeyDataLength(const unsigned char *&D) {
652 using namespace support;
653
654 offset_type KeyLen =
655 endian::readNext<offset_type, llvm::endianness::little>(D);
656 offset_type DataLen =
657 endian::readNext<offset_type, llvm::endianness::little>(D);
658 return std::make_pair(KeyLen, DataLen);
659 }
660
661 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
662 using namespace support;
663 return endian::readNext<external_key_type, llvm::endianness::little>(D);
664 }
665
666 data_type ReadData(uint64_t K, const unsigned char *D,
667 offset_type /*Unused*/) {
668 return Frame::deserialize(D);
669 }
670};
671
672// Trait for writing call stacks to the on-disk hash table.
674public:
677
680
683
685
686 static std::pair<offset_type, offset_type>
688 using namespace support;
690 // We do not explicitly emit the key length because it is a constant.
691 offset_type N = sizeof(K);
692 offset_type M = sizeof(FrameId) * V.size();
693 LE.write<offset_type>(M);
694 return std::make_pair(N, M);
695 }
696
697 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
698 using namespace support;
700 LE.write<key_type>(K);
701 }
702
704 offset_type /*Unused*/) {
705 using namespace support;
707 // Emit the frames. We do not explicitly emit the length of the vector
708 // because it can be inferred from the data length.
709 for (FrameId F : V)
710 LE.write<FrameId>(F);
711 }
712};
713
714// Trait for reading call stack mappings from the on-disk hash table.
716public:
722
724 return A == B;
725 }
728
730
731 static std::pair<offset_type, offset_type>
732 ReadKeyDataLength(const unsigned char *&D) {
733 using namespace support;
734
735 // We do not explicitly read the key length because it is a constant.
736 offset_type KeyLen = sizeof(external_key_type);
737 offset_type DataLen =
738 endian::readNext<offset_type, llvm::endianness::little>(D);
739 return std::make_pair(KeyLen, DataLen);
740 }
741
742 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
743 using namespace support;
744 return endian::readNext<external_key_type, llvm::endianness::little>(D);
745 }
746
747 data_type ReadData(uint64_t K, const unsigned char *D, offset_type Length) {
748 using namespace support;
750 // Derive the number of frames from the data length.
751 uint64_t NumFrames = Length / sizeof(FrameId);
752 assert(Length % sizeof(FrameId) == 0);
753 CS.reserve(NumFrames);
754 for (size_t I = 0; I != NumFrames; ++I) {
755 FrameId F = endian::readNext<FrameId, llvm::endianness::little>(D);
756 CS.push_back(F);
757 }
758 return CS;
759 }
760};
761
762// Compute a CallStackId for a given call stack.
764
765namespace detail {
766// "Dereference" the iterator from DenseMap or OnDiskChainedHashTable. We have
767// to do so in one of two different ways depending on the type of the hash
768// table.
769template <typename value_type, typename IterTy>
770value_type DerefIterator(IterTy Iter) {
771 using deref_type = llvm::remove_cvref_t<decltype(*Iter)>;
772 if constexpr (std::is_same_v<deref_type, value_type>)
773 return *Iter;
774 else
775 return Iter->second;
776}
777} // namespace detail
778
779// A function object that returns a frame for a given FrameId.
780template <typename MapTy> struct FrameIdConverter {
781 std::optional<FrameId> LastUnmappedId;
782 MapTy &Map;
783
786
788 auto Iter = Map.find(Id);
789 if (Iter == Map.end()) {
790 LastUnmappedId = Id;
791 return Frame(0, 0, 0, false);
792 }
793 return detail::DerefIterator<Frame>(Iter);
794 }
795};
796
797// A function object that returns a call stack for a given CallStackId.
798template <typename MapTy> struct CallStackIdConverter {
799 std::optional<CallStackId> LastUnmappedId;
800 MapTy &Map;
801 std::function<Frame(FrameId)> FrameIdToFrame;
802
806
809 auto CSIter = Map.find(CSId);
810 if (CSIter == Map.end()) {
811 LastUnmappedId = CSId;
812 } else {
814 detail::DerefIterator<llvm::SmallVector<FrameId>>(CSIter);
815 Frames.reserve(CS.size());
816 for (FrameId Id : CS)
817 Frames.push_back(FrameIdToFrame(Id));
818 }
819 return Frames;
820 }
821};
822
823// Verify that each CallStackId is computed with hashCallStack. This function
824// is intended to help transition from CallStack to CSId in
825// IndexedAllocationInfo.
826void verifyIndexedMemProfRecord(const IndexedMemProfRecord &Record);
827
828// Verify that each CallStackId is computed with hashCallStack. This function
829// is intended to help transition from CallStack to CSId in
830// IndexedAllocationInfo.
833 &FunctionProfileData);
834} // namespace memprof
835} // namespace llvm
836
837#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())
This file contains library features backported from future STL versions.
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
size_t size() const
Definition: SmallVector.h:91
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:726
hash_value_type ComputeHash(internal_key_type K)
Definition: MemProf.h:729
static bool EqualKey(internal_key_type A, internal_key_type B)
Definition: MemProf.h:723
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:732
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:742
data_type ReadData(uint64_t K, const unsigned char *D, offset_type Length)
Definition: MemProf.h:747
static uint64_t GetExternalKey(external_key_type K)
Definition: MemProf.h:727
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:684
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:687
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:703
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:697
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:666
static uint64_t GetExternalKey(external_key_type K)
Definition: MemProf.h:646
static bool EqualKey(internal_key_type A, internal_key_type B)
Definition: MemProf.h:642
static uint64_t GetInternalKey(internal_key_type K)
Definition: MemProf.h:645
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:651
hash_value_type ComputeHash(internal_key_type K)
Definition: MemProf.h:648
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:661
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:608
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:621
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:627
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:611
static bool EqualKey(uint64_t A, uint64_t B)
Definition: MemProf.h:503
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:520
data_type ReadData(uint64_t K, const unsigned char *D, offset_type)
Definition: MemProf.h:525
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:510
static uint64_t GetInternalKey(uint64_t K)
Definition: MemProf.h:504
hash_value_type ComputeHash(uint64_t K)
Definition: MemProf.h:507
static uint64_t GetExternalKey(uint64_t K)
Definition: MemProf.h:505
RecordLookupTrait(IndexedVersion V, const MemProfSchema &S)
Definition: MemProf.h:500
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:564
std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:567
RecordWriterTrait(const MemProfSchema *Schema, IndexedVersion V)
Definition: MemProf.h:561
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:578
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:584
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
value_type DerefIterator(IterTy Iter)
Definition: MemProf.h:770
void verifyIndexedMemProfRecord(const IndexedMemProfRecord &Record)
Definition: MemProf.cpp:316
constexpr uint64_t MaximumSupportedVersion
Definition: MemProf.h:34
MemProfSchema getHotColdSchema()
Definition: MemProf.cpp:21
CallStackId hashCallStack(ArrayRef< FrameId > CS)
Definition: MemProf.cpp:305
uint64_t FrameId
Definition: MemProf.h:188
constexpr uint64_t MinimumSupportedVersion
Definition: MemProf.h:33
uint64_t CallStackId
Definition: MemProf.h:306
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
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
typename llvm::remove_cvref< T >::type remove_cvref_t
@ Other
Any other memory.
#define N
AllocationInfo(const IndexedAllocationInfo &IndexedAI, llvm::function_ref< const Frame(const FrameId)> IdToFrameCallback)
Definition: MemProf.h:354
PortableMemInfoBlock Info
Definition: MemProf.h:351
llvm::SmallVector< Frame > CallStack
Definition: MemProf.h:349
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:363
llvm::SmallVector< Frame > operator()(CallStackId CSId)
Definition: MemProf.h:807
std::optional< CallStackId > LastUnmappedId
Definition: MemProf.h:799
std::function< Frame(FrameId)> FrameIdToFrame
Definition: MemProf.h:801
CallStackIdConverter(MapTy &Map, std::function< Frame(FrameId)> FrameIdToFrame)
Definition: MemProf.h:804
Frame operator()(FrameId Id)
Definition: MemProf.h:787
std::optional< FrameId > LastUnmappedId
Definition: MemProf.h:781
Frame & operator=(const Frame &Other)
Definition: MemProf.h:225
Frame(const Frame &Other)
Definition: MemProf.h:207
static constexpr size_t serializedSize()
Definition: MemProf.h:269
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:275
GlobalValue::GUID Function
Definition: MemProf.h:195
void serialize(raw_ostream &OS) const
Definition: MemProf.h:237
std::optional< std::string > SymbolName
Definition: MemProf.h:198
Frame(uint64_t Hash, uint32_t Off, uint32_t Col, bool Inline)
Definition: MemProf.h:215
bool operator==(const Frame &Other) const
Definition: MemProf.h:218
bool operator!=(const Frame &Other) const
Definition: MemProf.h:234
static Frame deserialize(const unsigned char *Ptr)
Definition: MemProf.h:254
FrameId hash() const
Definition: MemProf.h:287
uint32_t LineOffset
Definition: MemProf.h:200
IndexedAllocationInfo(ArrayRef< FrameId > CS, CallStackId CSId, const MemInfoBlock &MB, const MemProfSchema &Schema=getFullSchema())
Definition: MemProf.h:322
bool operator==(const IndexedAllocationInfo &Other) const
Definition: MemProf.h:331
bool operator!=(const IndexedAllocationInfo &Other) const
Definition: MemProf.h:340
PortableMemInfoBlock Info
Definition: MemProf.h:319
size_t serializedSize(const MemProfSchema &Schema, IndexedVersion Version) const
Definition: MemProf.cpp:48
llvm::SmallVector< FrameId > CallStack
Definition: MemProf.h:314
llvm::SmallVector< CallStackId > CallSiteIds
Definition: MemProf.h:390
llvm::SmallVector< IndexedAllocationInfo > AllocSites
Definition: MemProf.h:381
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:387
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:407
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:397
llvm::SmallVector< AllocationInfo > AllocSites
Definition: MemProf.h:443
void print(llvm::raw_ostream &OS) const
Definition: MemProf.h:464
MemProfRecord(const IndexedMemProfRecord &Record, llvm::function_ref< const Frame(const FrameId Id)> IdToFrameCallback)
Definition: MemProf.h:448
llvm::SmallVector< llvm::SmallVector< Frame > > CallSites
Definition: MemProf.h:445
bool operator!=(const PortableMemInfoBlock &Other) const
Definition: MemProf.h:155
void deserialize(const MemProfSchema &IncomingSchema, const unsigned char *Ptr)
Definition: MemProf.h:75
PortableMemInfoBlock(const MemProfSchema &Schema, const unsigned char *Ptr)
Definition: MemProf.h:69
std::bitset< llvm::to_underlying(Meta::Size)> getSchema() const
Definition: MemProf.h:127
static size_t serializedSize(const MemProfSchema &Schema)
Definition: MemProf.h:159
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:118
void serialize(const MemProfSchema &Schema, raw_ostream &OS) const
Definition: MemProf.h:99
PortableMemInfoBlock(const MemInfoBlock &Block, const MemProfSchema &IncomingSchema)
Definition: MemProf.h:60
bool operator==(const PortableMemInfoBlock &Other) const
Definition: MemProf.h:142
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:67