LLVM: lib/ProfileData/IndexedMemProfData.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
21
22namespace llvm {
23
24
28 for (const auto Id : Schema)
30}
31
32
36 &MemProfRecordData,
39 *MemProfCallStackIndexes = nullptr) {
41 MemProfCallStackIndexes);
43 RecordTableGenerator;
44 for (auto &[GUID, Record] : MemProfRecordData) {
45
46 RecordTableGenerator.insert(GUID, Record, RecordWriter);
47 }
48
49 MemProfRecordData.clear();
50
51
52
53
54 return RecordTableGenerator.Emit(OS.OS, RecordWriter);
55}
56
57
62 FrameTableGenerator;
63 for (auto &[FrameId, Frame] : MemProfFrameData) {
64
65 FrameTableGenerator.insert(FrameId, Frame);
66 }
67
68 MemProfFrameData.clear();
69
70 return FrameTableGenerator.Emit(OS.OS);
71}
72
73
74
80
82
83
84
85
86
87
88
89
90
91
92 std::vector<std::pair<memprof::FrameId, const memprof::Frame *>> FrameIdOrder;
93 FrameIdOrder.reserve(MemProfFrameData.size());
94 for (const auto &[Id, Frame] : MemProfFrameData)
95 FrameIdOrder.emplace_back(Id, &Frame);
96 assert(MemProfFrameData.size() == FrameIdOrder.size());
98 [&](const std::pair<memprof::FrameId, const memprof::Frame *> &L,
99 const std::pair<memprof::FrameId, const memprof::Frame *> &R) {
100 const auto &SL = FrameHistogram[L.first];
101 const auto &SR = FrameHistogram[R.first];
102
103 if (SL.Count != SR.Count)
104 return SL.Count > SR.Count;
105
106
107 if (SL.PositionSum != SR.PositionSum)
108 return SL.PositionSum < SR.PositionSum;
109
110 return L.first < R.first;
111 });
112
113
115 MemProfFrameIndexes.reserve(FrameIdOrder.size());
116 for (const auto &[Id, F] : FrameIdOrder) {
118 MemProfFrameIndexes.insert({Id, Index});
119 ++Index;
120 }
121 assert(MemProfFrameData.size() == Index);
122 assert(MemProfFrameData.size() == MemProfFrameIndexes.size());
123
124
125 MemProfFrameData.clear();
126
127 return MemProfFrameIndexes;
128}
129
133 &MemProfCallStackData) {
135 CallStackTableGenerator;
136 for (auto &[CSId, CallStack] : MemProfCallStackData)
137 CallStackTableGenerator.insert(CSId, CallStack);
138
139 MemProfCallStackData.clear();
140
141 return CallStackTableGenerator.Emit(OS.OS);
142}
143
148 &MemProfCallStackData,
150 &MemProfFrameIndexes,
152 unsigned &NumElements) {
154 MemProfCallStackIndexes;
155
157 Builder.build(std::move(MemProfCallStackData), &MemProfFrameIndexes,
158 FrameHistogram);
159 for (auto I : Builder.getRadixArray())
161 NumElements = Builder.getRadixArray().size();
162 MemProfCallStackIndexes = Builder.takeCallStackPos();
163
164
165 MemProfCallStackData.clear();
166
167 return MemProfCallStackIndexes;
168}
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
187 bool MemProfFullSchema) {
190 OS.write(0ULL);
191 OS.write(0ULL);
192 OS.write(0ULL);
193 OS.write(0ULL);
194 OS.write(0ULL);
195
197 if (MemProfFullSchema)
200
203
206
208 uint64_t CallStackTableOffset =
210
212 RecordTableOffset, FramePayloadOffset, FrameTableOffset,
213 CallStackPayloadOffset, CallStackTableOffset,
214 };
215 OS.patch({{HeaderUpdatePos, Header}});
216
218}
219
223 std::unique_ptrmemprof::DataAccessProfData DataAccessProfileData =
224 nullptr,
225 std::unique_ptrmemprof::MemProfSummary MemProfSum = nullptr) {
227 "Unsupported version for radix tree format");
228
231 OS.write(0ULL);
232 OS.write(0ULL);
233 OS.write(0ULL);
235 OS.write(0ULL);
236
237 MemProfSum->write(OS);
238 }
239
241 if (MemProfFullSchema)
244
248
251
253
254 unsigned NumElements = 0;
256 MemProfCallStackIndexes =
258 MemProfFrameIndexes, FrameHistogram,
259 NumElements);
260
263 OS, MemProfData.Records, &Schema, Version, &MemProfCallStackIndexes);
264
265 uint64_t DataAccessProfOffset = 0;
266 if (DataAccessProfileData != nullptr) {
268 "Data access profiles are added starting from v4");
269 DataAccessProfOffset = OS.tell();
270 if (Error E = DataAccessProfileData->serialize(OS))
271 return E;
272 }
273
274
275
276 assert(CallStackPayloadOffset +
278 RecordPayloadOffset);
279
281 CallStackPayloadOffset,
282 RecordPayloadOffset,
283 RecordTableOffset,
284 };
286 Header.push_back(DataAccessProfOffset);
287
288 OS.patch({{HeaderUpdatePos, Header}});
289
291}
292
293
296 bool MemProfFullSchema) {
298 MemProfFullSchema);
299}
300
301
304 bool MemProfFullSchema,
305 std::unique_ptrmemprof::DataAccessProfData DataAccessProfileData,
306 std::unique_ptrmemprof::MemProfSummary MemProfSum) {
309 std::move(DataAccessProfileData), std::move(MemProfSum));
310}
311
312
316 std::unique_ptrmemprof::DataAccessProfData DataAccessProfileData,
317 std::unique_ptrmemprof::MemProfSummary MemProfSum) {
318 switch (MemProfVersionRequested) {
320 return writeMemProfV2(OS, MemProfData, MemProfFullSchema);
322 return writeMemProfV3(OS, MemProfData, MemProfFullSchema);
324 return writeMemProfV4(OS, MemProfData, MemProfFullSchema,
325 std::move(DataAccessProfileData),
326 std::move(MemProfSum));
327 }
328
331 formatv("MemProf version {} not supported; "
332 "requires version between {} and {}, inclusive",
335}
336
337Error IndexedMemProfReader::deserializeV2(const unsigned char *Start,
338 const unsigned char *Ptr) {
339
340 const uint64_t RecordTableOffset =
342
343
344 const uint64_t FramePayloadOffset =
346
347 const uint64_t FrameTableOffset =
349
350
351
352 uint64_t CallStackPayloadOffset = 0;
353
354 uint64_t CallStackTableOffset = 0;
356 CallStackPayloadOffset =
358 CallStackTableOffset =
360 }
361
362
364 if (!SchemaOr)
365 return SchemaOr.takeError();
366 Schema = SchemaOr.get();
367
368
370 Start + RecordTableOffset,
371 Ptr,
372 Start, memprof::RecordLookupTrait(Version, Schema)));
373
374
376 Start + FrameTableOffset,
377 Start + FramePayloadOffset,
378 Start));
379
382 Start + CallStackTableOffset,
383 Start + CallStackPayloadOffset,
384 Start));
385
387}
388
389Error IndexedMemProfReader::deserializeRadixTreeBased(
390 const unsigned char *Start, const unsigned char *Ptr,
393 "Unsupported version for radix tree format");
394
395
396 const uint64_t CallStackPayloadOffset =
398
399 const uint64_t RecordPayloadOffset =
401
402 const uint64_t RecordTableOffset =
404
405 uint64_t DataAccessProfOffset = 0;
407 DataAccessProfOffset =
410 }
411
412
414 if (!SchemaOr)
415 return SchemaOr.takeError();
416 Schema = SchemaOr.get();
417
418 FrameBase = Ptr;
419 CallStackBase = Start + CallStackPayloadOffset;
420
421
422
423
424 RadixTreeSize = (RecordPayloadOffset - CallStackPayloadOffset) /
426
427
429 Start + RecordTableOffset,
430 Start + RecordPayloadOffset,
431 Start, memprof::RecordLookupTrait(Version, Schema)));
432
433 assert((!DataAccessProfOffset || DataAccessProfOffset > RecordTableOffset) &&
434 "Data access profile is either empty or after the record table");
435 if (DataAccessProfOffset > RecordTableOffset) {
436 DataAccessProfileData = std::make_uniquememprof::DataAccessProfData();
437 const unsigned char *DAPPtr = Start + DataAccessProfOffset;
438 if (Error E = DataAccessProfileData->deserialize(DAPPtr))
439 return E;
440 }
441
443}
444
447 const unsigned char *Ptr = Start + MemProfOffset;
448
449
452
453
456
458 } else {
461 formatv("MemProf version {} not supported; "
462 "requires version between {} and {}, inclusive",
465 }
466
467 switch (Version) {
469 if (Error E = deserializeV2(Start, Ptr))
470 return E;
471 break;
474
475 if (Error E = deserializeRadixTreeBased(Start, Ptr, Version))
476 return E;
477 break;
478 }
479
481}
482}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Defines facilities for reading and writing on-disk hash tables.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
LLVM_ABI Error deserialize(const unsigned char *Start, uint64_t MemProfOffset)
Definition IndexedMemProfData.cpp:445
This class implements a map that also provides access to all stored values in a deterministic order.
Generates an on disk hash table.
offset_type Emit(raw_ostream &Out)
Emit the table to Out, which must not be at offset 0.
static OnDiskIterableChainedHashTable * Create(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, const memprof::RecordLookupTrait &InfoObj=memprof::RecordLookupTrait())
LLVM_ABI uint64_t tell() const
LLVM_ABI void patch(ArrayRef< PatchItem > P)
LLVM_ABI void write32(uint32_t V)
LLVM_ABI void write(uint64_t V)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
void build(llvm::MapVector< CallStackId, llvm::SmallVector< FrameIdTy > > &&MemProfCallStackData, const llvm::DenseMap< FrameIdTy, LinearFrameId > *MemProfFrameIndexes, llvm::DenseMap< FrameIdTy, FrameStat > &FrameHistogram)
static LLVM_ABI std::unique_ptr< MemProfSummary > deserialize(const unsigned char *&)
Read from indexed MemProf profile.
constexpr uint64_t MaximumSupportedVersion
LLVM_ABI MemProfSchema getHotColdSchema()
llvm::SmallVector< Meta, static_cast< int >(Meta::Size)> MemProfSchema
constexpr uint64_t MinimumSupportedVersion
LLVM_ABI MemProfSchema getFullSchema()
LLVM_ABI Expected< MemProfSchema > readMemProfSchema(const unsigned char *&Buffer)
llvm::DenseMap< FrameIdTy, FrameStat > computeFrameHistogram(llvm::MapVector< CallStackId, llvm::SmallVector< FrameIdTy > > &MemProfCallStackData)
value_type readNext(const CharT *&memory, endianness endian)
Read a value of a particular endianness from a buffer, and increment the buffer past that value.
This is an optimization pass for GlobalISel generic memory operations.
static void writeMemProfSchema(ProfOStream &OS, const memprof::MemProfSchema &Schema)
Definition IndexedMemProfData.cpp:25
static Error writeMemProfV3(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, bool MemProfFullSchema)
Definition IndexedMemProfData.cpp:294
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionAddr VTableAddr uintptr_t uintptr_t Version
void sort(IteratorTy Start, IteratorTy End)
static llvm::DenseMap< memprof::CallStackId, memprof::LinearCallStackId > writeMemProfCallStackArray(ProfOStream &OS, llvm::MapVector< memprof::CallStackId, llvm::SmallVector< memprof::FrameId > > &MemProfCallStackData, llvm::DenseMap< memprof::FrameId, memprof::LinearFrameId > &MemProfFrameIndexes, llvm::DenseMap< memprof::FrameId, memprof::FrameStat > &FrameHistogram, unsigned &NumElements)
Definition IndexedMemProfData.cpp:145
static llvm::DenseMap< memprof::FrameId, memprof::LinearFrameId > writeMemProfFrameArray(ProfOStream &OS, llvm::MapVector< memprof::FrameId, memprof::Frame > &MemProfFrameData, llvm::DenseMap< memprof::FrameId, memprof::FrameStat > &FrameHistogram)
Definition IndexedMemProfData.cpp:76
static Error writeMemProfV4(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, bool MemProfFullSchema, std::unique_ptr< memprof::DataAccessProfData > DataAccessProfileData, std::unique_ptr< memprof::MemProfSummary > MemProfSum)
Definition IndexedMemProfData.cpp:302
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
static Error writeMemProfRadixTreeBased(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, memprof::IndexedVersion Version, bool MemProfFullSchema, std::unique_ptr< memprof::DataAccessProfData > DataAccessProfileData=nullptr, std::unique_ptr< memprof::MemProfSummary > MemProfSum=nullptr)
Definition IndexedMemProfData.cpp:220
static Error writeMemProfV2(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, bool MemProfFullSchema)
Definition IndexedMemProfData.cpp:185
static uint64_t writeMemProfCallStacks(ProfOStream &OS, llvm::MapVector< memprof::CallStackId, llvm::SmallVector< memprof::FrameId > > &MemProfCallStackData)
Definition IndexedMemProfData.cpp:130
static uint64_t writeMemProfRecords(ProfOStream &OS, llvm::MapVector< GlobalValue::GUID, memprof::IndexedMemProfRecord > &MemProfRecordData, memprof::MemProfSchema *Schema, memprof::IndexedVersion Version, llvm::DenseMap< memprof::CallStackId, memprof::LinearCallStackId > *MemProfCallStackIndexes=nullptr)
Definition IndexedMemProfData.cpp:33
LLVM_ABI Error writeMemProf(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema, std::unique_ptr< memprof::DataAccessProfData > DataAccessProfileData, std::unique_ptr< memprof::MemProfSummary > MemProfSum)
Definition IndexedMemProfData.cpp:313
static uint64_t writeMemProfFrames(ProfOStream &OS, llvm::MapVector< memprof::FrameId, memprof::Frame > &MemProfFrameData)
Definition IndexedMemProfData.cpp:58
llvm::MapVector< CallStackId, llvm::SmallVector< FrameId > > CallStacks
llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord > Records
llvm::MapVector< FrameId, Frame > Frames