LLVM 22.0.0git
MemProf.h
Go to the documentation of this file.
1//===- MemProf.h - MemProf support ------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains common definitions used in the reading and writing of
10// memory profile data.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_PROFILEDATA_MEMPROF_H
15#define LLVM_PROFILEDATA_MEMPROF_H
16
17#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/StringRef.h"
22#include "llvm/IR/GlobalValue.h"
25#include "llvm/Support/Endian.h"
28
29#include <bitset>
30#include <cstdint>
31
32namespace llvm {
33namespace yaml {
34template <typename T> struct CustomMappingTraits;
35} // namespace yaml
36
37namespace memprof {
38
39struct MemProfRecord;
40
41// The versions of the indexed MemProf format
43 // Version 2: Added a call stack table.
45 // Version 3: Added a radix tree for call stacks. Switched to linear IDs for
46 // frames and call stacks.
48 // Version 4: Added CalleeGuids to call site info.
50};
51
54
55// Verify that the minimum and maximum satisfy the obvious constraint.
57
59 return "___memprof_default_options_str";
60}
61
63 // Darwin linkage names are prefixed with an extra "_". See
64 // DataLayout::getGlobalPrefix().
66}
67
68enum class Meta : uint64_t {
69 Start = 0,
70#define MIBEntryDef(NameTag, Name, Type) NameTag,
72#undef MIBEntryDef
73 Size
74};
75
77
78// Returns the full schema currently in use.
80
81// Returns the schema consisting of the fields used for hot cold memory hinting.
83
84// Holds the actual MemInfoBlock data with all fields. Contents may be read or
85// written partially by providing an appropriate schema to the serialize and
86// deserialize methods.
89 explicit PortableMemInfoBlock(const MemInfoBlock &Block,
90 const MemProfSchema &IncomingSchema) {
91 for (const Meta Id : IncomingSchema)
92 Schema.set(llvm::to_underlying(Id));
93#define MIBEntryDef(NameTag, Name, Type) Name = Block.Name;
95#undef MIBEntryDef
96 }
97
98 PortableMemInfoBlock(const MemProfSchema &Schema, const unsigned char *Ptr) {
99 deserialize(Schema, Ptr);
100 }
101
102 // Read the contents of \p Ptr based on the \p Schema to populate the
103 // MemInfoBlock member.
104 void deserialize(const MemProfSchema &IncomingSchema,
105 const unsigned char *Ptr) {
106 using namespace support;
107
108 Schema.reset();
109 for (const Meta Id : IncomingSchema) {
110 switch (Id) {
111#define MIBEntryDef(NameTag, Name, Type) \
112 case Meta::Name: { \
113 Name = endian::readNext<Type, llvm::endianness::little>(Ptr); \
114 } break;
116#undef MIBEntryDef
117 default:
118 llvm_unreachable("Unknown meta type id, is the profile collected from "
119 "a newer version of the runtime?");
120 }
121
122 Schema.set(llvm::to_underlying(Id));
123 }
124 }
125
126 // Write the contents of the MemInfoBlock based on the \p Schema provided to
127 // the raw_ostream \p OS.
128 void serialize(const MemProfSchema &Schema, raw_ostream &OS) const {
129 using namespace support;
130
132 for (const Meta Id : Schema) {
133 switch (Id) {
134#define MIBEntryDef(NameTag, Name, Type) \
135 case Meta::Name: { \
136 LE.write<Type>(Name); \
137 } break;
139#undef MIBEntryDef
140 default:
141 llvm_unreachable("Unknown meta type id, invalid input?");
142 }
143 }
144 }
145
146 // Print out the contents of the MemInfoBlock in YAML format.
147 void printYAML(raw_ostream &OS) const {
148 OS << " MemInfoBlock:\n";
149#define MIBEntryDef(NameTag, Name, Type) \
150 OS << " " << #Name << ": " << Name << "\n";
152#undef MIBEntryDef
153 if (AccessHistogramSize > 0) {
154 OS << " " << "AccessHistogramValues" << ":";
155 for (uint32_t I = 0; I < AccessHistogramSize; ++I) {
156 OS << " " << ((uint64_t *)AccessHistogram)[I];
157 }
158 OS << "\n";
159 }
160 }
161
162 // Return the schema, only for unit tests.
164 return Schema;
165 }
166
167 // Define getters for each type which can be called by analyses.
168#define MIBEntryDef(NameTag, Name, Type) \
169 Type get##Name() const { \
170 assert(Schema[llvm::to_underlying(Meta::Name)]); \
171 return Name; \
172 }
174#undef MIBEntryDef
175
176 // Define setters for each type which can be called by the writer.
177#define MIBEntryDef(NameTag, Name, Type) \
178 void set##Name(Type NewVal) { \
179 assert(Schema[llvm::to_underlying(Meta::Name)]); \
180 Name = NewVal; \
181 }
183#undef MIBEntryDef
184
185 void clear() { *this = PortableMemInfoBlock(); }
186
188 if (Other.Schema != Schema)
189 return false;
190
191#define MIBEntryDef(NameTag, Name, Type) \
192 if (Schema[llvm::to_underlying(Meta::Name)] && \
193 Other.get##Name() != get##Name()) \
194 return false;
196#undef MIBEntryDef
197 return true;
198 }
199
201 return !operator==(Other);
202 }
203
204 static size_t serializedSize(const MemProfSchema &Schema) {
205 size_t Result = 0;
206
207 for (const Meta Id : Schema) {
208 switch (Id) {
209#define MIBEntryDef(NameTag, Name, Type) \
210 case Meta::Name: { \
211 Result += sizeof(Type); \
212 } break;
214#undef MIBEntryDef
215 default:
216 llvm_unreachable("Unknown meta type id, invalid input?");
217 }
218 }
219
220 return Result;
221 }
222
223 // Give YAML access to the individual MIB fields.
224 friend struct yaml::CustomMappingTraits<memprof::PortableMemInfoBlock>;
225
226private:
227 // The set of available fields, indexed by Meta::Name.
228 std::bitset<llvm::to_underlying(Meta::Size)> Schema;
229
230#define MIBEntryDef(NameTag, Name, Type) Type Name = Type();
231#include "llvm/ProfileData/MIBEntryDef.inc"
232#undef MIBEntryDef
233};
234
235// A type representing the id generated by hashing the contents of the Frame.
237// A type representing the id to index into the frame array.
239// Describes a call frame for a dynamic allocation context. The contents of
240// the frame are populated by symbolizing the stack depot call frame from the
241// compiler runtime.
242struct Frame {
243 // A uuid (uint64_t) identifying the function. It is obtained by
244 // llvm::md5(FunctionName) which returns the lower 64 bits.
246 // The symbol name for the function. Only populated in the Frame by the reader
247 // if requested during initialization. This field should not be serialized.
248 std::unique_ptr<std::string> SymbolName;
249 // The source line offset of the call from the beginning of parent function.
250 uint32_t LineOffset = 0;
251 // The source column number of the call to help distinguish multiple calls
252 // on the same line.
253 uint32_t Column = 0;
254 // Whether the current frame is inlined.
255 bool IsInlineFrame = false;
256
257 Frame() = default;
258 Frame(const Frame &Other) {
259 Function = Other.Function;
260 SymbolName = Other.SymbolName
261 ? std::make_unique<std::string>(*Other.SymbolName)
262 : nullptr;
263 LineOffset = Other.LineOffset;
264 Column = Other.Column;
265 IsInlineFrame = Other.IsInlineFrame;
266 }
267
268 Frame(GlobalValue::GUID Hash, uint32_t Off, uint32_t Col, bool Inline)
269 : Function(Hash), LineOffset(Off), Column(Col), IsInlineFrame(Inline) {}
270
271 bool operator==(const Frame &Other) const {
272 // Ignore the SymbolName field to avoid a string compare. Comparing the
273 // function hash serves the same purpose.
274 return Other.Function == Function && Other.LineOffset == LineOffset &&
275 Other.Column == Column && Other.IsInlineFrame == IsInlineFrame;
276 }
277
279 Function = Other.Function;
280 SymbolName = Other.SymbolName
281 ? std::make_unique<std::string>(*Other.SymbolName)
282 : nullptr;
283 LineOffset = Other.LineOffset;
284 Column = Other.Column;
285 IsInlineFrame = Other.IsInlineFrame;
286 return *this;
287 }
288
289 bool operator!=(const Frame &Other) const { return !operator==(Other); }
290
291 bool hasSymbolName() const { return !!SymbolName; }
292
294 assert(hasSymbolName());
295 return *SymbolName;
296 }
297
298 std::string getSymbolNameOr(StringRef Alt) const {
299 return std::string(hasSymbolName() ? getSymbolName() : Alt);
300 }
301
302 // Write the contents of the frame to the ostream \p OS.
303 void serialize(raw_ostream &OS) const {
304 using namespace support;
305
307
308 // If the type of the GlobalValue::GUID changes, then we need to update
309 // the reader and the writer.
310 static_assert(std::is_same<GlobalValue::GUID, uint64_t>::value,
311 "Expect GUID to be uint64_t.");
312 LE.write<uint64_t>(Function);
313
314 LE.write<uint32_t>(LineOffset);
315 LE.write<uint32_t>(Column);
316 LE.write<bool>(IsInlineFrame);
317 }
318
319 // Read a frame from char data which has been serialized as little endian.
320 static Frame deserialize(const unsigned char *Ptr) {
321 using namespace support;
322
323 const uint64_t F =
324 endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
325 const uint32_t L =
326 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
327 const uint32_t C =
328 endian::readNext<uint32_t, llvm::endianness::little>(Ptr);
329 const bool I = endian::readNext<bool, llvm::endianness::little>(Ptr);
330 return Frame(/*Function=*/F, /*LineOffset=*/L, /*Column=*/C,
331 /*IsInlineFrame=*/I);
332 }
333
334 // Returns the size of the frame information.
335 static constexpr size_t serializedSize() {
336 return sizeof(Frame::Function) + sizeof(Frame::LineOffset) +
337 sizeof(Frame::Column) + sizeof(Frame::IsInlineFrame);
338 }
339
340 // Print the frame information in YAML format.
341 void printYAML(raw_ostream &OS) const {
342 OS << " -\n"
343 << " Function: " << Function << "\n"
344 << " SymbolName: " << getSymbolNameOr("<None>") << "\n"
345 << " LineOffset: " << LineOffset << "\n"
346 << " Column: " << Column << "\n"
347 << " Inline: " << IsInlineFrame << "\n";
348 }
349};
350
351// A type representing the index into the table of call stacks.
353
354// A type representing the index into the call stack array.
356
357// Holds call site information with indexed frame contents.
359 // The call stack ID for this call site
360 CallStackId CSId = 0;
361 // The GUIDs of the callees at this call site
363
365 IndexedCallSiteInfo(CallStackId CSId) : CSId(CSId) {}
368 : CSId(CSId), CalleeGuids(std::move(CalleeGuids)) {}
369
371 return CSId == Other.CSId && CalleeGuids == Other.CalleeGuids;
372 }
373
375 return !operator==(Other);
376 }
377};
378
379// Holds allocation information in a space efficient format where frames are
380// represented using unique identifiers.
382 // The dynamic calling context for the allocation in bottom-up (leaf-to-root)
383 // order. Frame contents are stored out-of-line.
384 CallStackId CSId = 0;
385 // The statistics obtained from the runtime for the allocation.
387
389 IndexedAllocationInfo(CallStackId CSId, const MemInfoBlock &MB,
390 const MemProfSchema &Schema = getFullSchema())
391 : CSId(CSId), Info(MB, Schema) {}
393 : CSId(CSId), Info(MB) {}
394
395 // Returns the size in bytes when this allocation info struct is serialized.
396 LLVM_ABI size_t serializedSize(const MemProfSchema &Schema,
397 IndexedVersion Version) const;
398
400 if (Other.Info != Info)
401 return false;
402
403 if (Other.CSId != CSId)
404 return false;
405 return true;
406 }
407
409 return !operator==(Other);
410 }
411};
412
413// Holds allocation information with frame contents inline. The type should
414// be used for temporary in-memory instances.
416 // Same as IndexedAllocationInfo::CallStack with the frame contents inline.
417 std::vector<Frame> CallStack;
418 // Same as IndexedAllocationInfo::Info;
420
421 AllocationInfo() = default;
422
423 void printYAML(raw_ostream &OS) const {
424 OS << " -\n";
425 OS << " Callstack:\n";
426 // TODO: Print out the frame on one line with to make it easier for deep
427 // callstacks once we have a test to check valid YAML is generated.
428 for (const Frame &F : CallStack) {
429 F.printYAML(OS);
430 }
431 Info.printYAML(OS);
432 }
433};
434
435// Holds the memprof profile information for a function. The internal
436// representation stores frame ids for efficiency. This representation should
437// be used in the profile conversion and manipulation tools.
439 // Memory allocation sites in this function for which we have memory
440 // profiling data.
442 // Holds call sites in this function which are part of some memory
443 // allocation context. We store this as a list of locations, each with its
444 // list of inline locations in bottom-up order i.e. from leaf to root. The
445 // inline location list may include additional entries, users should pick
446 // the last entry in the list with the same function GUID.
448
449 void clear() { *this = IndexedMemProfRecord(); }
450
452 // TODO: Filter out duplicates which may occur if multiple memprof
453 // profiles are merged together using llvm-profdata.
454 AllocSites.append(Other.AllocSites);
455 }
456
457 LLVM_ABI size_t serializedSize(const MemProfSchema &Schema,
458 IndexedVersion Version) const;
459
461 if (Other.AllocSites != AllocSites)
462 return false;
463
464 if (Other.CallSites != CallSites)
465 return false;
466 return true;
467 }
468
469 // Serializes the memprof records in \p Records to the ostream \p OS based
470 // on the schema provided in \p Schema.
471 LLVM_ABI void serialize(const MemProfSchema &Schema, raw_ostream &OS,
472 IndexedVersion Version,
474 *MemProfCallStackIndexes = nullptr) const;
475
476 // Deserializes memprof records from the Buffer.
477 LLVM_ABI static IndexedMemProfRecord deserialize(const MemProfSchema &Schema,
478 const unsigned char *Buffer,
479 IndexedVersion Version);
480
481 // Convert IndexedMemProfRecord to MemProfRecord. Callback is used to
482 // translate CallStackId to call stacks with frames inline.
483 LLVM_ABI MemProfRecord toMemProfRecord(
484 llvm::function_ref<std::vector<Frame>(const CallStackId)> Callback) const;
485};
486
487// Returns the GUID for the function name after canonicalization. For
488// memprof, we remove any .llvm suffix added by LTO. MemProfRecords are
489// mapped to functions using this GUID.
490LLVM_ABI GlobalValue::GUID getGUID(const StringRef FunctionName);
491
492// Holds call site information with frame contents inline.
494 // The frames in the call stack
495 std::vector<Frame> Frames;
496
497 // The GUIDs of the callees at this call site
499
500 CallSiteInfo() = default;
501 CallSiteInfo(std::vector<Frame> Frames) : Frames(std::move(Frames)) {}
502 CallSiteInfo(std::vector<Frame> Frames,
504 : Frames(std::move(Frames)), CalleeGuids(std::move(CalleeGuids)) {}
505
506 bool operator==(const CallSiteInfo &Other) const {
507 return Frames == Other.Frames && CalleeGuids == Other.CalleeGuids;
508 }
509
510 bool operator!=(const CallSiteInfo &Other) const {
511 return !operator==(Other);
512 }
513};
514
515// Holds the memprof profile information for a function. The internal
516// representation stores frame contents inline. This representation should
517// be used for small amount of temporary, in memory instances.
519 // Same as IndexedMemProfRecord::AllocSites with frame contents inline.
521 // Same as IndexedMemProfRecord::CallSites with frame contents inline.
523
524 MemProfRecord() = default;
525
526 // Prints out the contents of the memprof record in YAML.
528 if (!AllocSites.empty()) {
529 OS << " AllocSites:\n";
530 for (const AllocationInfo &N : AllocSites)
531 N.printYAML(OS);
532 }
533
534 if (!CallSites.empty()) {
535 OS << " CallSites:\n";
536 for (const CallSiteInfo &CS : CallSites) {
537 for (const Frame &F : CS.Frames) {
538 OS << " -\n";
539 F.printYAML(OS);
540 }
541 }
542 }
543 }
544};
545
546// Reads a memprof schema from a buffer. All entries in the buffer are
547// interpreted as uint64_t. The first entry in the buffer denotes the number of
548// ids in the schema. Subsequent entries are integers which map to memprof::Meta
549// enum class entries. After successfully reading the schema, the pointer is one
550// byte past the schema contents.
552readMemProfSchema(const unsigned char *&Buffer);
553
554// Trait for reading IndexedMemProfRecord data from the on-disk hash table.
556public:
562
565 : Version(V), Schema(S) {}
566
567 static bool EqualKey(uint64_t A, uint64_t B) { return A == B; }
568 static uint64_t GetInternalKey(uint64_t K) { return K; }
569 static uint64_t GetExternalKey(uint64_t K) { return K; }
570
572
573 static std::pair<offset_type, offset_type>
574 ReadKeyDataLength(const unsigned char *&D) {
575 using namespace support;
576
577 offset_type KeyLen =
578 endian::readNext<offset_type, llvm::endianness::little>(D);
579 offset_type DataLen =
580 endian::readNext<offset_type, llvm::endianness::little>(D);
581 return std::make_pair(KeyLen, DataLen);
582 }
583
584 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
585 using namespace support;
586 return endian::readNext<external_key_type, llvm::endianness::little>(D);
587 }
588
589 data_type ReadData(uint64_t K, const unsigned char *D,
590 offset_type /*Unused*/) {
591 Record = IndexedMemProfRecord::deserialize(Schema, D, Version);
592 return Record;
593 }
594
595private:
596 // Holds the MemProf version.
597 IndexedVersion Version;
598 // Holds the memprof schema used to deserialize records.
599 MemProfSchema Schema;
600 // Holds the records from one function deserialized from the indexed format.
602};
603
604// Trait for writing IndexedMemProfRecord data to the on-disk hash table.
606public:
609
612
615
616private:
617 // Pointer to the memprof schema to use for the generator.
618 const MemProfSchema *Schema;
619 // The MemProf version to use for the serialization.
620 IndexedVersion Version;
621
622 // Mappings from CallStackId to the indexes into the call stack array.
623 llvm::DenseMap<CallStackId, LinearCallStackId> *MemProfCallStackIndexes;
624
625public:
626 // We do not support the default constructor, which does not set Version.
629 const MemProfSchema *Schema, IndexedVersion V,
630 llvm::DenseMap<CallStackId, LinearCallStackId> *MemProfCallStackIndexes)
631 : Schema(Schema), Version(V),
632 MemProfCallStackIndexes(MemProfCallStackIndexes) {}
633
635
636 std::pair<offset_type, offset_type>
638 using namespace support;
639
641 offset_type N = sizeof(K);
642 LE.write<offset_type>(N);
643 offset_type M = V.serializedSize(*Schema, Version);
644 LE.write<offset_type>(M);
645 return std::make_pair(N, M);
646 }
647
648 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
649 using namespace support;
651 LE.write<uint64_t>(K);
652 }
653
655 offset_type /*Unused*/) {
656 assert(Schema != nullptr && "MemProf schema is not initialized!");
657 V.serialize(*Schema, Out, Version, MemProfCallStackIndexes);
658 // Clear the IndexedMemProfRecord which results in clearing/freeing its
659 // vectors of allocs and callsites. This is owned by the associated on-disk
660 // hash table, but unused after this point. See also the comment added to
661 // the client which constructs the on-disk hash table for this trait.
662 V.clear();
663 }
664};
665
666// Trait for writing frame mappings to the on-disk hash table.
668public:
671
674
677
679
680 static std::pair<offset_type, offset_type>
682 using namespace support;
684 offset_type N = sizeof(K);
685 LE.write<offset_type>(N);
686 offset_type M = V.serializedSize();
687 LE.write<offset_type>(M);
688 return std::make_pair(N, M);
689 }
690
691 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
692 using namespace support;
694 LE.write<key_type>(K);
695 }
696
698 offset_type /*Unused*/) {
699 V.serialize(Out);
700 }
701};
702
703// Trait for reading frame mappings from the on-disk hash table.
705public:
706 using data_type = const Frame;
711
713 return A == B;
714 }
717
719
720 static std::pair<offset_type, offset_type>
721 ReadKeyDataLength(const unsigned char *&D) {
722 using namespace support;
723
724 offset_type KeyLen =
725 endian::readNext<offset_type, llvm::endianness::little>(D);
726 offset_type DataLen =
727 endian::readNext<offset_type, llvm::endianness::little>(D);
728 return std::make_pair(KeyLen, DataLen);
729 }
730
731 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
732 using namespace support;
733 return endian::readNext<external_key_type, llvm::endianness::little>(D);
734 }
735
736 data_type ReadData(uint64_t K, const unsigned char *D,
737 offset_type /*Unused*/) {
738 return Frame::deserialize(D);
739 }
740};
741
742// Trait for writing call stacks to the on-disk hash table.
744public:
747
750
753
755
756 static std::pair<offset_type, offset_type>
758 using namespace support;
760 // We do not explicitly emit the key length because it is a constant.
761 offset_type N = sizeof(K);
762 offset_type M = sizeof(FrameId) * V.size();
763 LE.write<offset_type>(M);
764 return std::make_pair(N, M);
765 }
766
767 void EmitKey(raw_ostream &Out, key_type_ref K, offset_type /*Unused*/) {
768 using namespace support;
770 LE.write<key_type>(K);
771 }
772
774 offset_type /*Unused*/) {
775 using namespace support;
777 // Emit the frames. We do not explicitly emit the length of the vector
778 // because it can be inferred from the data length.
779 for (FrameId F : V)
780 LE.write<FrameId>(F);
781 }
782};
783
784// Trait for reading call stack mappings from the on-disk hash table.
786public:
792
794 return A == B;
795 }
798
800
801 static std::pair<offset_type, offset_type>
802 ReadKeyDataLength(const unsigned char *&D) {
803 using namespace support;
804
805 // We do not explicitly read the key length because it is a constant.
806 offset_type KeyLen = sizeof(external_key_type);
807 offset_type DataLen =
808 endian::readNext<offset_type, llvm::endianness::little>(D);
809 return std::make_pair(KeyLen, DataLen);
810 }
811
812 uint64_t ReadKey(const unsigned char *D, offset_type /*Unused*/) {
813 using namespace support;
814 return endian::readNext<external_key_type, llvm::endianness::little>(D);
815 }
816
817 data_type ReadData(uint64_t K, const unsigned char *D, offset_type Length) {
818 using namespace support;
820 // Derive the number of frames from the data length.
821 uint64_t NumFrames = Length / sizeof(FrameId);
822 assert(Length % sizeof(FrameId) == 0);
823 CS.reserve(NumFrames);
824 for (size_t I = 0; I != NumFrames; ++I) {
825 FrameId F = endian::readNext<FrameId, llvm::endianness::little>(D);
826 CS.push_back(F);
827 }
828 return CS;
829 }
830};
831
833 LineLocation(uint32_t L, uint32_t D) : LineOffset(L), Column(D) {}
834
835 bool operator<(const LineLocation &O) const {
836 return std::tie(LineOffset, Column) < std::tie(O.LineOffset, O.Column);
837 }
838
839 bool operator==(const LineLocation &O) const {
840 return LineOffset == O.LineOffset && Column == O.Column;
841 }
842
843 bool operator!=(const LineLocation &O) const {
844 return LineOffset != O.LineOffset || Column != O.Column;
845 }
846
847 uint64_t getHashCode() const { return ((uint64_t)Column << 32) | LineOffset; }
848
851};
852
853// A pair of a call site location and its corresponding callee GUID.
854using CallEdgeTy = std::pair<LineLocation, uint64_t>;
855} // namespace memprof
856} // namespace llvm
857#endif // LLVM_PROFILEDATA_MEMPROF_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
static StringRef getSymbolName(SymbolKind SymKind)
#define LLVM_ABI
Definition: Compiler.h:213
This file defines the DenseMap class.
std::optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1328
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file contains library features backported from future STL versions.
raw_pwrite_stream & OS
This file defines the SmallVector class.
Tagged union holding either a T or a Error.
Definition: Error.h:485
bool empty() const
Definition: SmallVector.h:82
void reserve(size_type N)
Definition: SmallVector.h:664
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:684
void push_back(const T &Elt)
Definition: SmallVector.h:414
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
StringRef drop_front(size_t N=1) const
Return a StringRef equal to 'this' but with the first N elements dropped.
Definition: StringRef.h:619
An efficient, type-erasing, non-owning reference to a callable.
static uint64_t GetInternalKey(internal_key_type K)
Definition: MemProf.h:796
hash_value_type ComputeHash(internal_key_type K)
Definition: MemProf.h:799
static bool EqualKey(internal_key_type A, internal_key_type B)
Definition: MemProf.h:793
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:802
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:812
data_type ReadData(uint64_t K, const unsigned char *D, offset_type Length)
Definition: MemProf.h:817
static uint64_t GetExternalKey(external_key_type K)
Definition: MemProf.h:797
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:754
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:757
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:773
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:767
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:736
static uint64_t GetExternalKey(external_key_type K)
Definition: MemProf.h:716
static bool EqualKey(internal_key_type A, internal_key_type B)
Definition: MemProf.h:712
static uint64_t GetInternalKey(internal_key_type K)
Definition: MemProf.h:715
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:721
hash_value_type ComputeHash(internal_key_type K)
Definition: MemProf.h:718
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:731
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:678
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:691
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:697
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:681
static bool EqualKey(uint64_t A, uint64_t B)
Definition: MemProf.h:567
uint64_t ReadKey(const unsigned char *D, offset_type)
Definition: MemProf.h:584
data_type ReadData(uint64_t K, const unsigned char *D, offset_type)
Definition: MemProf.h:589
static std::pair< offset_type, offset_type > ReadKeyDataLength(const unsigned char *&D)
Definition: MemProf.h:574
static uint64_t GetInternalKey(uint64_t K)
Definition: MemProf.h:568
hash_value_type ComputeHash(uint64_t K)
Definition: MemProf.h:571
static uint64_t GetExternalKey(uint64_t K)
Definition: MemProf.h:569
RecordLookupTrait(IndexedVersion V, const MemProfSchema &S)
Definition: MemProf.h:564
static hash_value_type ComputeHash(key_type_ref K)
Definition: MemProf.h:634
RecordWriterTrait(const MemProfSchema *Schema, IndexedVersion V, llvm::DenseMap< CallStackId, LinearCallStackId > *MemProfCallStackIndexes)
Definition: MemProf.h:628
std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: MemProf.h:637
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type)
Definition: MemProf.h:648
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: MemProf.h:654
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr uint64_t MaximumSupportedVersion
Definition: MemProf.h:53
LLVM_ABI MemProfSchema getHotColdSchema()
Definition: MemProf.cpp:19
uint32_t LinearCallStackId
Definition: MemProf.h:355
llvm::StringRef getMemprofOptionsSymbolName()
Definition: MemProf.h:62
constexpr uint64_t MinimumSupportedVersion
Definition: MemProf.h:52
uint64_t CallStackId
Definition: MemProf.h:352
std::pair< LineLocation, uint64_t > CallEdgeTy
Definition: MemProf.h:854
LLVM_ABI MemProfSchema getFullSchema()
Definition: MemProf.cpp:11
LLVM_ABI GlobalValue::GUID getGUID(const StringRef FunctionName)
Definition: MemProf.cpp:344
LLVM_ABI Expected< MemProfSchema > readMemProfSchema(const unsigned char *&Buffer)
Definition: MemProf.cpp:360
llvm::StringRef getMemprofOptionsSymbolDarwinLinkageName()
Definition: MemProf.h:58
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Length
Definition: DWP.cpp:477
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
@ Other
Any other memory.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1886
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
#define N
std::vector< Frame > CallStack
Definition: MemProf.h:417
PortableMemInfoBlock Info
Definition: MemProf.h:419
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:423
bool operator!=(const CallSiteInfo &Other) const
Definition: MemProf.h:510
CallSiteInfo(std::vector< Frame > Frames)
Definition: MemProf.h:501
std::vector< Frame > Frames
Definition: MemProf.h:495
bool operator==(const CallSiteInfo &Other) const
Definition: MemProf.h:506
SmallVector< GlobalValue::GUID, 1 > CalleeGuids
Definition: MemProf.h:498
CallSiteInfo(std::vector< Frame > Frames, SmallVector< GlobalValue::GUID, 1 > CalleeGuids)
Definition: MemProf.h:502
Frame & operator=(const Frame &Other)
Definition: MemProf.h:278
Frame(const Frame &Other)
Definition: MemProf.h:258
static constexpr size_t serializedSize()
Definition: MemProf.h:335
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:341
void serialize(raw_ostream &OS) const
Definition: MemProf.h:303
bool hasSymbolName() const
Definition: MemProf.h:291
std::string getSymbolNameOr(StringRef Alt) const
Definition: MemProf.h:298
StringRef getSymbolName() const
Definition: MemProf.h:293
bool operator==(const Frame &Other) const
Definition: MemProf.h:271
bool operator!=(const Frame &Other) const
Definition: MemProf.h:289
static Frame deserialize(const unsigned char *Ptr)
Definition: MemProf.h:320
Frame(GlobalValue::GUID Hash, uint32_t Off, uint32_t Col, bool Inline)
Definition: MemProf.h:268
std::unique_ptr< std::string > SymbolName
Definition: MemProf.h:248
IndexedAllocationInfo(CallStackId CSId, const MemInfoBlock &MB, const MemProfSchema &Schema=getFullSchema())
Definition: MemProf.h:389
bool operator==(const IndexedAllocationInfo &Other) const
Definition: MemProf.h:399
bool operator!=(const IndexedAllocationInfo &Other) const
Definition: MemProf.h:408
PortableMemInfoBlock Info
Definition: MemProf.h:386
IndexedAllocationInfo(CallStackId CSId, const PortableMemInfoBlock &MB)
Definition: MemProf.h:392
bool operator!=(const IndexedCallSiteInfo &Other) const
Definition: MemProf.h:374
IndexedCallSiteInfo(CallStackId CSId, SmallVector< GlobalValue::GUID, 1 > CalleeGuids)
Definition: MemProf.h:366
IndexedCallSiteInfo(CallStackId CSId)
Definition: MemProf.h:365
SmallVector< GlobalValue::GUID, 1 > CalleeGuids
Definition: MemProf.h:362
bool operator==(const IndexedCallSiteInfo &Other) const
Definition: MemProf.h:370
llvm::SmallVector< IndexedAllocationInfo > AllocSites
Definition: MemProf.h:441
bool operator==(const IndexedMemProfRecord &Other) const
Definition: MemProf.h:460
void merge(const IndexedMemProfRecord &Other)
Definition: MemProf.h:451
llvm::SmallVector< IndexedCallSiteInfo > CallSites
Definition: MemProf.h:447
LineLocation(uint32_t L, uint32_t D)
Definition: MemProf.h:833
bool operator!=(const LineLocation &O) const
Definition: MemProf.h:843
bool operator==(const LineLocation &O) const
Definition: MemProf.h:839
bool operator<(const LineLocation &O) const
Definition: MemProf.h:835
uint64_t getHashCode() const
Definition: MemProf.h:847
llvm::SmallVector< CallSiteInfo > CallSites
Definition: MemProf.h:522
llvm::SmallVector< AllocationInfo > AllocSites
Definition: MemProf.h:520
void print(llvm::raw_ostream &OS) const
Definition: MemProf.h:527
bool operator!=(const PortableMemInfoBlock &Other) const
Definition: MemProf.h:200
void deserialize(const MemProfSchema &IncomingSchema, const unsigned char *Ptr)
Definition: MemProf.h:104
PortableMemInfoBlock(const MemProfSchema &Schema, const unsigned char *Ptr)
Definition: MemProf.h:98
std::bitset< llvm::to_underlying(Meta::Size)> getSchema() const
Definition: MemProf.h:163
static size_t serializedSize(const MemProfSchema &Schema)
Definition: MemProf.h:204
void printYAML(raw_ostream &OS) const
Definition: MemProf.h:147
void serialize(const MemProfSchema &Schema, raw_ostream &OS) const
Definition: MemProf.h:128
PortableMemInfoBlock(const MemInfoBlock &Block, const MemProfSchema &IncomingSchema)
Definition: MemProf.h:89
bool operator==(const PortableMemInfoBlock &Other) const
Definition: MemProf.h:187
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:67