LLVM 20.0.0git
MemProfYAML.h
Go to the documentation of this file.
1#ifndef LLVM_PROFILEDATA_MEMPROFYAML_H_
2#define LLVM_PROFILEDATA_MEMPROFYAML_H_
3
7
8namespace llvm {
9namespace memprof {
10// A "typedef" for GUID. See ScalarTraits<memprof::GUIDHex64> for how a GUID is
11// serialized and deserialized in YAML.
13
14// Helper struct for AllMemProfData. In YAML, we treat the GUID and the fields
15// within MemProfRecord at the same level as if the GUID were part of
16// MemProfRecord.
18 GUIDHex64 GUID;
20};
21
22// The top-level data structure, only used with YAML for now.
24 std::vector<GUIDMemProfRecordPair> HeapProfileRecords;
25};
26} // namespace memprof
27
28namespace yaml {
29template <> struct ScalarTraits<memprof::GUIDHex64> {
30 static void output(const memprof::GUIDHex64 &Val, void *, raw_ostream &Out) {
31 // Print GUID as a 16-digit hexadecimal number.
32 Out << format("0x%016" PRIx64, (uint64_t)Val);
33 }
34 static StringRef input(StringRef Scalar, void *, memprof::GUIDHex64 &Val) {
35 // Reject decimal GUIDs.
36 if (all_of(Scalar, [](char C) { return std::isdigit(C); }))
37 return "use a hexadecimal GUID or a function instead";
38
39 uint64_t Num;
40 if (Scalar.starts_with_insensitive("0x")) {
41 // Accept hexadecimal numbers starting with 0x or 0X.
42 if (Scalar.getAsInteger(0, Num))
43 return "invalid hex64 number";
44 Val = Num;
45 } else {
46 // Otherwise, treat the input as a string containing a function name.
47 Val = memprof::IndexedMemProfRecord::getGUID(Scalar);
48 }
49 return StringRef();
50 }
51 static QuotingType mustQuote(StringRef) { return QuotingType::None; }
52};
53
54template <> struct MappingTraits<memprof::Frame> {
55 // Essentially the same as memprof::Frame except that Function is of type
56 // memprof::GUIDHex64 instead of GlobalValue::GUID. This class helps in two
57 // ways. During serialization, we print Function as a 16-digit hexadecimal
58 // number. During deserialization, we accept a function name as an
59 // alternative to the usual GUID expressed as a hexadecimal number.
60 class FrameWithHex64 {
61 public:
64 : Function(F.Function), LineOffset(F.LineOffset), Column(F.Column),
65 IsInlineFrame(F.IsInlineFrame) {}
67 return memprof::Frame(Function, LineOffset, Column, IsInlineFrame);
68 }
69
70 memprof::GUIDHex64 Function = 0;
71 static_assert(std::is_same_v<decltype(Function.value),
72 decltype(memprof::Frame::Function)>);
73 decltype(memprof::Frame::LineOffset) LineOffset = 0;
74 decltype(memprof::Frame::Column) Column = 0;
75 decltype(memprof::Frame::IsInlineFrame) IsInlineFrame = false;
76 };
77
78 static void mapping(IO &Io, memprof::Frame &F) {
79 MappingNormalization<FrameWithHex64, memprof::Frame> Keys(Io, F);
80
81 Io.mapRequired("Function", Keys->Function);
82 Io.mapRequired("LineOffset", Keys->LineOffset);
83 Io.mapRequired("Column", Keys->Column);
84 Io.mapRequired("IsInlineFrame", Keys->IsInlineFrame);
85
86 // Assert that the definition of Frame matches what we expect. The
87 // structured bindings below detect changes to the number of fields.
88 // static_assert checks the type of each field.
89 const auto &[Function, SymbolName, LineOffset, Column, IsInlineFrame] = F;
90 static_assert(
91 std::is_same_v<remove_cvref_t<decltype(Function)>, GlobalValue::GUID>);
92 static_assert(std::is_same_v<remove_cvref_t<decltype(SymbolName)>,
93 std::unique_ptr<std::string>>);
94 static_assert(
95 std::is_same_v<remove_cvref_t<decltype(LineOffset)>, uint32_t>);
96 static_assert(std::is_same_v<remove_cvref_t<decltype(Column)>, uint32_t>);
97 static_assert(
98 std::is_same_v<remove_cvref_t<decltype(IsInlineFrame)>, bool>);
99
100 // MSVC issues unused variable warnings despite the uses in static_assert
101 // above.
102 (void)Function;
103 (void)SymbolName;
104 (void)LineOffset;
105 (void)Column;
106 (void)IsInlineFrame;
107 }
108
109 // Request the inline notation for brevity:
110 // { Function: 123, LineOffset: 11, Column: 10; IsInlineFrame: true }
111 static const bool flow = true;
112};
113
114template <> struct CustomMappingTraits<memprof::PortableMemInfoBlock> {
115 static void inputOne(IO &Io, StringRef KeyStr,
117 // PortableMemInfoBlock keeps track of the set of fields that actually have
118 // values. We update the set here as we receive a key-value pair from the
119 // YAML document.
120 //
121 // We set MIB.Name via a temporary variable because ScalarTraits<uintptr_t>
122 // isn't available on macOS.
123#define MIBEntryDef(NameTag, Name, Type) \
124 if (KeyStr == #Name) { \
125 uint64_t Value; \
126 Io.mapRequired(KeyStr.str().c_str(), Value); \
127 MIB.Name = static_cast<Type>(Value); \
128 MIB.Schema.set(llvm::to_underlying(memprof::Meta::Name)); \
129 return; \
130 }
132#undef MIBEntryDef
133 Io.setError("Key is not a valid validation event");
134 }
135
136 static void output(IO &Io, memprof::PortableMemInfoBlock &MIB) {
137 auto Schema = MIB.getSchema();
138#define MIBEntryDef(NameTag, Name, Type) \
139 if (Schema.test(llvm::to_underlying(memprof::Meta::Name))) { \
140 uint64_t Value = MIB.Name; \
141 Io.mapRequired(#Name, Value); \
142 }
144#undef MIBEntryDef
145 }
146};
147
148template <> struct MappingTraits<memprof::AllocationInfo> {
149 static void mapping(IO &Io, memprof::AllocationInfo &AI) {
150 Io.mapRequired("Callstack", AI.CallStack);
151 Io.mapRequired("MemInfoBlock", AI.Info);
152 }
153};
154
155// In YAML, we use GUIDMemProfRecordPair instead of MemProfRecord so that we can
156// treat the GUID and the fields within MemProfRecord at the same level as if
157// the GUID were part of MemProfRecord.
158template <> struct MappingTraits<memprof::GUIDMemProfRecordPair> {
159 static void mapping(IO &Io, memprof::GUIDMemProfRecordPair &Pair) {
160 Io.mapRequired("GUID", Pair.GUID);
161 Io.mapRequired("AllocSites", Pair.Record.AllocSites);
162 Io.mapRequired("CallSites", Pair.Record.CallSites);
163 }
164};
165
166template <> struct MappingTraits<memprof::AllMemProfData> {
167 static void mapping(IO &Io, memprof::AllMemProfData &Data) {
168 Io.mapRequired("HeapProfileRecords", Data.HeapProfileRecords);
169 }
170};
171} // namespace yaml
172} // namespace llvm
173
174LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::Frame)
175LLVM_YAML_IS_SEQUENCE_VECTOR(std::vector<memprof::Frame>)
176LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::AllocationInfo)
177LLVM_YAML_IS_SEQUENCE_VECTOR(memprof::GUIDMemProfRecordPair)
178
179#endif // LLVM_PROFILEDATA_MEMPROFYAML_H_
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
#define F(x, y, z)
Definition: MD5.cpp:55
#define LLVM_YAML_IS_SEQUENCE_VECTOR(type)
#define LLVM_YAML_STRONG_TYPEDEF(_base, _type)
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1739
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:125
std::vector< GUIDMemProfRecordPair > HeapProfileRecords
Definition: MemProfYAML.h:24
std::vector< Frame > CallStack
Definition: MemProf.h:372
PortableMemInfoBlock Info
Definition: MemProf.h:374
llvm::SmallVector< std::vector< Frame > > CallSites
Definition: MemProf.h:454
llvm::SmallVector< AllocationInfo > AllocSites
Definition: MemProf.h:452
std::bitset< llvm::to_underlying(Meta::Size)> getSchema() const
Definition: MemProf.h:140
static void inputOne(IO &Io, StringRef KeyStr, memprof::PortableMemInfoBlock &MIB)
Definition: MemProfYAML.h:115
static void output(IO &Io, memprof::PortableMemInfoBlock &MIB)
Definition: MemProfYAML.h:136
static void mapping(IO &Io, memprof::AllMemProfData &Data)
Definition: MemProfYAML.h:167
static void mapping(IO &Io, memprof::AllocationInfo &AI)
Definition: MemProfYAML.h:149
static void mapping(IO &Io, memprof::Frame &F)
Definition: MemProfYAML.h:78
static void mapping(IO &Io, memprof::GUIDMemProfRecordPair &Pair)
Definition: MemProfYAML.h:159
static QuotingType mustQuote(StringRef)
Definition: MemProfYAML.h:51
static StringRef input(StringRef Scalar, void *, memprof::GUIDHex64 &Val)
Definition: MemProfYAML.h:34
static void output(const memprof::GUIDHex64 &Val, void *, raw_ostream &Out)
Definition: MemProfYAML.h:30