28 for (
const auto Id : Schema)
39 *MemProfCallStackIndexes =
nullptr) {
41 MemProfCallStackIndexes);
44 for (
auto &[GUID,
Record] : MemProfRecordData) {
46 RecordTableGenerator.insert(GUID,
Record, RecordWriter);
49 MemProfRecordData.
clear();
54 return RecordTableGenerator.
Emit(
OS.OS, RecordWriter);
63 for (
auto &[FrameId, Frame] : MemProfFrameData) {
65 FrameTableGenerator.insert(FrameId, Frame);
68 MemProfFrameData.
clear();
70 return FrameTableGenerator.
Emit(
OS.OS);
92 std::vector<std::pair<memprof::FrameId, const memprof::Frame *>> FrameIdOrder;
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];
103 if (SL.Count != SR.Count)
104 return SL.Count > SR.Count;
107 if (SL.PositionSum != SR.PositionSum)
108 return SL.PositionSum < SR.PositionSum;
110 return L.first < R.first;
115 MemProfFrameIndexes.
reserve(FrameIdOrder.size());
116 for (
const auto &[Id,
F] : FrameIdOrder) {
125 MemProfFrameData.
clear();
127 return MemProfFrameIndexes;
133 &MemProfCallStackData) {
135 CallStackTableGenerator;
136 for (
auto &[CSId, CallStack] : MemProfCallStackData)
137 CallStackTableGenerator.insert(CSId, CallStack);
139 MemProfCallStackData.clear();
141 return CallStackTableGenerator.
Emit(
OS.OS);
148 &MemProfCallStackData,
150 &MemProfFrameIndexes,
152 unsigned &NumElements) {
154 MemProfCallStackIndexes;
157 Builder.
build(std::move(MemProfCallStackData), &MemProfFrameIndexes,
165 MemProfCallStackData.clear();
167 return MemProfCallStackIndexes;
187 bool MemProfFullSchema) {
197 if (MemProfFullSchema)
212 RecordTableOffset, FramePayloadOffset, FrameTableOffset,
213 CallStackPayloadOffset, CallStackTableOffset,
215 OS.patch({{HeaderUpdatePos, Header}});
223 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData =
225 std::unique_ptr<memprof::MemProfSummary> MemProfSum =
nullptr) {
227 "Unsupported version for radix tree format");
241 if (MemProfFullSchema)
254 unsigned NumElements = 0;
256 MemProfCallStackIndexes =
258 MemProfFrameIndexes, FrameHistogram,
266 if (DataAccessProfileData !=
nullptr) {
268 "Data access profiles are added starting from v4");
269 DataAccessProfOffset =
OS.
tell();
270 if (
Error E = DataAccessProfileData->serialize(
OS))
276 assert(CallStackPayloadOffset +
278 RecordPayloadOffset);
281 CallStackPayloadOffset,
286 Header.push_back(DataAccessProfOffset);
288 OS.patch({{HeaderUpdatePos, Header}});
296 bool MemProfFullSchema) {
304 bool MemProfFullSchema,
305 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData,
306 std::unique_ptr<memprof::MemProfSummary> MemProfSum) {
309 std::move(DataAccessProfileData), std::move(MemProfSum));
316 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData,
317 std::unique_ptr<memprof::MemProfSummary> MemProfSum) {
318 switch (MemProfVersionRequested) {
325 std::move(DataAccessProfileData),
326 std::move(MemProfSum));
329 return make_error<InstrProfError>(
331 formatv(
"MemProf version {} not supported; "
332 "requires version between {} and {}, inclusive",
337Error IndexedMemProfReader::deserializeV2(
const unsigned char *Start,
338 const unsigned char *
Ptr) {
341 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
345 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
348 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
352 uint64_t CallStackPayloadOffset = 0;
356 CallStackPayloadOffset =
357 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
358 CallStackTableOffset =
359 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
365 return SchemaOr.takeError();
366 Schema = SchemaOr.get();
370 Start + RecordTableOffset,
372 Start, memprof::RecordLookupTrait(Version, Schema)));
376 Start + FrameTableOffset,
377 Start + FramePayloadOffset,
382 Start + CallStackTableOffset,
383 Start + CallStackPayloadOffset,
389Error IndexedMemProfReader::deserializeRadixTreeBased(
390 const unsigned char *Start,
const unsigned char *
Ptr,
393 "Unsupported version for radix tree format");
396 const uint64_t CallStackPayloadOffset =
397 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
399 const uint64_t RecordPayloadOffset =
400 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
403 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
407 DataAccessProfOffset =
408 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
415 return SchemaOr.takeError();
416 Schema = SchemaOr.get();
419 CallStackBase = Start + CallStackPayloadOffset;
424 RadixTreeSize = (RecordPayloadOffset - CallStackPayloadOffset) /
429 Start + RecordTableOffset,
430 Start + RecordPayloadOffset,
431 Start, memprof::RecordLookupTrait(Version, Schema)));
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_unique<memprof::DataAccessProfData>();
437 const unsigned char *DAPPtr = Start + DataAccessProfOffset;
438 if (Error
E = DataAccessProfileData->deserialize(DAPPtr))
447 const unsigned char *
Ptr = Start + MemProfOffset;
451 support::endian::readNext<uint64_t, llvm::endianness::little>(
Ptr);
459 return make_error<InstrProfError>(
461 formatv(
"MemProf version {} not supported; "
462 "requires version between {} and {}, inclusive",
475 if (
Error E = deserializeRadixTreeBased(Start,
Ptr, Version))
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)
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 Info &InfoObj=Info())
Create the hash table.
void build(llvm::MapVector< CallStackId, llvm::SmallVector< FrameIdTy > > &&MemProfCallStackData, const llvm::DenseMap< FrameIdTy, LinearFrameId > *MemProfFrameIndexes, llvm::DenseMap< FrameIdTy, FrameStat > &FrameHistogram)
ArrayRef< LinearFrameId > getRadixArray() const
llvm::DenseMap< CallStackId, LinearCallStackId > takeCallStackPos()
static LLVM_ABI std::unique_ptr< MemProfSummary > deserialize(const unsigned char *&)
Read from indexed MemProf profile.
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
constexpr uint64_t MaximumSupportedVersion
LLVM_ABI MemProfSchema getHotColdSchema()
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)
This is an optimization pass for GlobalISel generic memory operations.
static void writeMemProfSchema(ProfOStream &OS, const memprof::MemProfSchema &Schema)
static Error writeMemProfV3(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, bool MemProfFullSchema)
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
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)
static llvm::DenseMap< memprof::FrameId, memprof::LinearFrameId > writeMemProfFrameArray(ProfOStream &OS, llvm::MapVector< memprof::FrameId, memprof::Frame > &MemProfFrameData, llvm::DenseMap< memprof::FrameId, memprof::FrameStat > &FrameHistogram)
static Error writeMemProfV4(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, bool MemProfFullSchema, std::unique_ptr< memprof::DataAccessProfData > DataAccessProfileData, std::unique_ptr< memprof::MemProfSummary > MemProfSum)
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)
static Error writeMemProfV2(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData, bool MemProfFullSchema)
static uint64_t writeMemProfCallStacks(ProfOStream &OS, llvm::MapVector< memprof::CallStackId, llvm::SmallVector< memprof::FrameId > > &MemProfCallStackData)
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)
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)
static uint64_t writeMemProfFrames(ProfOStream &OS, llvm::MapVector< memprof::FrameId, memprof::Frame > &MemProfFrameData)
llvm::MapVector< CallStackId, llvm::SmallVector< FrameId > > CallStacks
llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord > Records
llvm::MapVector< FrameId, Frame > Frames