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);
76 std::vector<std::pair<memprof::FrameId, const memprof::Frame *>> FrameIdOrder;
77 FrameIdOrder.reserve(MemProfFrameData.
size());
78 for (
const auto &[Id, Frame] : MemProfFrameData)
79 FrameIdOrder.emplace_back(Id, &Frame);
80 assert(MemProfFrameData.
size() == FrameIdOrder.size());
82 [&](
const std::pair<memprof::FrameId, const memprof::Frame *> &L,
83 const std::pair<memprof::FrameId, const memprof::Frame *> &R) {
84 const auto &SL = FrameHistogram[L.first];
85 const auto &SR = FrameHistogram[R.first];
87 if (SL.Count != SR.Count)
88 return SL.Count > SR.Count;
91 if (SL.PositionSum != SR.PositionSum)
92 return SL.PositionSum < SR.PositionSum;
94 return L.first < R.first;
99 MemProfFrameIndexes.
reserve(FrameIdOrder.size());
100 for (
const auto &[Id,
F] : FrameIdOrder) {
102 MemProfFrameIndexes.
insert({Id, Index});
109 MemProfFrameData.
clear();
111 return MemProfFrameIndexes;
118 &MemProfCallStackData,
120 &MemProfFrameIndexes,
122 unsigned &NumElements) {
124 MemProfCallStackIndexes;
127 Builder.
build(std::move(MemProfCallStackData), &MemProfFrameIndexes,
129 for (
auto I : Builder.getRadixArray())
131 NumElements = Builder.getRadixArray().size();
132 MemProfCallStackIndexes = Builder.takeCallStackPos();
135 MemProfCallStackData.
clear();
137 return MemProfCallStackIndexes;
143 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData =
145 std::unique_ptr<memprof::MemProfSummary> MemProfSum =
nullptr) {
147 "Unsupported version for radix tree format");
157 MemProfSum->write(OS);
161 if (MemProfFullSchema)
174 unsigned NumElements = 0;
176 MemProfCallStackIndexes =
178 MemProfFrameIndexes, FrameHistogram,
183 OS, MemProfData.
Records, &Schema,
Version, &MemProfCallStackIndexes);
186 if (DataAccessProfileData !=
nullptr) {
188 "Data access profiles are added starting from v4");
189 DataAccessProfOffset = OS.
tell();
190 if (
Error E = DataAccessProfileData->serialize(OS))
196 assert(CallStackPayloadOffset +
198 RecordPayloadOffset);
201 CallStackPayloadOffset,
208 OS.
patch({{HeaderUpdatePos, Header}});
216 bool MemProfFullSchema) {
224 bool MemProfFullSchema,
225 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData,
226 std::unique_ptr<memprof::MemProfSummary> MemProfSum) {
229 std::move(DataAccessProfileData), std::move(MemProfSum));
236 std::unique_ptr<memprof::DataAccessProfData> DataAccessProfileData,
237 std::unique_ptr<memprof::MemProfSummary> MemProfSum) {
238 switch (MemProfVersionRequested) {
243 std::move(DataAccessProfileData),
244 std::move(MemProfSum));
249 formatv(
"MemProf version {} not supported; "
250 "requires version between {} and {}, inclusive",
255Error IndexedMemProfReader::deserializeRadixTreeBased(
256 const unsigned char *Start,
const unsigned char *Ptr,
259 "Unsupported version for radix tree format");
262 const uint64_t CallStackPayloadOffset =
265 const uint64_t RecordPayloadOffset =
273 DataAccessProfOffset =
277 if (DataAccessProfOffset > RecordTableOffset) {
278 DataAccessProfileData = std::make_unique<memprof::DataAccessProfData>();
279 const unsigned char *DAPPtr = Start + DataAccessProfOffset;
280 if (Error
E = DataAccessProfileData->deserialize(DAPPtr))
282 MemProfSum->buildDataAccessSummary(*DataAccessProfileData);
286 assert((!DataAccessProfOffset || DataAccessProfOffset > RecordTableOffset) &&
287 "Data access profile is either empty or after the record table");
292 return SchemaOr.takeError();
293 Schema = SchemaOr.get();
296 CallStackBase =
Start + CallStackPayloadOffset;
301 RadixTreeSize = (RecordPayloadOffset - CallStackPayloadOffset) /
306 Start + RecordTableOffset,
307 Start + RecordPayloadOffset,
308 Start, memprof::RecordLookupTrait(Version, Schema)));
315 const unsigned char *Ptr = Start + MemProfOffset;
329 formatv(
"MemProf version {} not supported; "
330 "requires version between {} and {}, inclusive",
339 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.
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
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 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)
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)
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)
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)
llvm::MapVector< CallStackId, llvm::SmallVector< FrameId > > CallStacks
llvm::MapVector< GlobalValue::GUID, IndexedMemProfRecord > Records
llvm::MapVector< FrameId, Frame > Frames