Skip to content

Commit 0dc80e4

Browse files
[memprof] Group MemProf data structures into a struct (NFC) (#92360)
This patch groups the three Memprof data structures into a struct named IndexedMemProfData and teaches InstrProfWriter to use it. This way, we can pass IndexedMemProfData to writeMemProf and its helpers instead of individual data structures. As a follow-up, we can use the new struct in MemProfReader also. That in turn allows loadInput in llvm-profdata to move the MemProf data into the writer context, saving a few seconds for a large MemProf profile.
1 parent c7ae8c6 commit 0dc80e4

File tree

3 files changed

+50
-64
lines changed

3 files changed

+50
-64
lines changed

llvm/include/llvm/ProfileData/InstrProfWriter.h

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,8 @@ class InstrProfWriter {
5151
SmallVector<TemporalProfTraceTy> TemporalProfTraces;
5252
std::mt19937 RNG;
5353

54-
// A map to hold memprof data per function. The lower 64 bits obtained from
55-
// the md5 hash of the function name is used to index into the map.
56-
llvm::MapVector<GlobalValue::GUID, memprof::IndexedMemProfRecord>
57-
MemProfRecordData;
58-
// A map to hold frame id to frame mappings. The mappings are used to
59-
// convert IndexedMemProfRecord to MemProfRecords with frame information
60-
// inline.
61-
llvm::MapVector<memprof::FrameId, memprof::Frame> MemProfFrameData;
62-
63-
// A map to hold call stack id to call stacks.
64-
llvm::MapVector<memprof::CallStackId, llvm::SmallVector<memprof::FrameId>>
65-
MemProfCallStackData;
54+
// The MemProf data.
55+
memprof::IndexedMemProfData MemProfData;
6656

6757
// List of binary ids.
6858
std::vector<llvm::object::BuildID> BinaryIds;

llvm/include/llvm/ProfileData/MemProf.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -833,6 +833,20 @@ template <typename MapTy> struct CallStackIdConverter {
833833
}
834834
};
835835

836+
struct IndexedMemProfData {
837+
// A map to hold memprof data per function. The lower 64 bits obtained from
838+
// the md5 hash of the function name is used to index into the map.
839+
llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord> RecordData;
840+
841+
// A map to hold frame id to frame mappings. The mappings are used to
842+
// convert IndexedMemProfRecord to MemProfRecords with frame information
843+
// inline.
844+
llvm::MapVector<FrameId, Frame> FrameData;
845+
846+
// A map to hold call stack id to call stacks.
847+
llvm::MapVector<CallStackId, llvm::SmallVector<FrameId>> CallStackData;
848+
};
849+
836850
// Verify that each CallStackId is computed with hashCallStack. This function
837851
// is intended to help transition from CallStack to CSId in
838852
// IndexedAllocationInfo.

llvm/lib/ProfileData/InstrProfWriter.cpp

Lines changed: 34 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ void InstrProfWriter::addRecord(StringRef Name, uint64_t Hash,
273273

274274
void InstrProfWriter::addMemProfRecord(
275275
const Function::GUID Id, const memprof::IndexedMemProfRecord &Record) {
276-
auto [Iter, Inserted] = MemProfRecordData.insert({Id, Record});
276+
auto [Iter, Inserted] = MemProfData.RecordData.insert({Id, Record});
277277
// If we inserted a new record then we are done.
278278
if (Inserted) {
279279
return;
@@ -285,7 +285,7 @@ void InstrProfWriter::addMemProfRecord(
285285
bool InstrProfWriter::addMemProfFrame(const memprof::FrameId Id,
286286
const memprof::Frame &Frame,
287287
function_ref<void(Error)> Warn) {
288-
auto [Iter, Inserted] = MemProfFrameData.insert({Id, Frame});
288+
auto [Iter, Inserted] = MemProfData.FrameData.insert({Id, Frame});
289289
// If a mapping already exists for the current frame id and it does not
290290
// match the new mapping provided then reset the existing contents and bail
291291
// out. We don't support the merging of memprof data whose Frame -> Id
@@ -302,7 +302,7 @@ bool InstrProfWriter::addMemProfCallStack(
302302
const memprof::CallStackId CSId,
303303
const llvm::SmallVector<memprof::FrameId> &CallStack,
304304
function_ref<void(Error)> Warn) {
305-
auto [Iter, Inserted] = MemProfCallStackData.insert({CSId, CallStack});
305+
auto [Iter, Inserted] = MemProfData.CallStackData.insert({CSId, CallStack});
306306
// If a mapping already exists for the current call stack id and it does not
307307
// match the new mapping provided then reset the existing contents and bail
308308
// out. We don't support the merging of memprof data whose CallStack -> Id
@@ -389,22 +389,22 @@ void InstrProfWriter::mergeRecordsFromWriter(InstrProfWriter &&IPW,
389389
addTemporalProfileTraces(IPW.TemporalProfTraces,
390390
IPW.TemporalProfTraceStreamSize);
391391

392-
MemProfFrameData.reserve(IPW.MemProfFrameData.size());
393-
for (auto &[FrameId, Frame] : IPW.MemProfFrameData) {
392+
MemProfData.FrameData.reserve(IPW.MemProfData.FrameData.size());
393+
for (auto &[FrameId, Frame] : IPW.MemProfData.FrameData) {
394394
// If we weren't able to add the frame mappings then it doesn't make sense
395395
// to try to merge the records from this profile.
396396
if (!addMemProfFrame(FrameId, Frame, Warn))
397397
return;
398398
}
399399

400-
MemProfCallStackData.reserve(IPW.MemProfCallStackData.size());
401-
for (auto &[CSId, CallStack] : IPW.MemProfCallStackData) {
400+
MemProfData.CallStackData.reserve(IPW.MemProfData.CallStackData.size());
401+
for (auto &[CSId, CallStack] : IPW.MemProfData.CallStackData) {
402402
if (!addMemProfCallStack(CSId, CallStack, Warn))
403403
return;
404404
}
405405

406-
MemProfRecordData.reserve(IPW.MemProfRecordData.size());
407-
for (auto &[GUID, Record] : IPW.MemProfRecordData) {
406+
MemProfData.RecordData.reserve(IPW.MemProfData.RecordData.size());
407+
for (auto &[GUID, Record] : IPW.MemProfData.RecordData) {
408408
addMemProfRecord(GUID, Record);
409409
}
410410
}
@@ -499,11 +499,8 @@ static uint64_t writeMemProfCallStacks(
499499
return CallStackTableGenerator.Emit(OS.OS);
500500
}
501501

502-
static Error writeMemProfV0(
503-
ProfOStream &OS,
504-
llvm::MapVector<GlobalValue::GUID, memprof::IndexedMemProfRecord>
505-
&MemProfRecordData,
506-
llvm::MapVector<memprof::FrameId, memprof::Frame> &MemProfFrameData) {
502+
static Error writeMemProfV0(ProfOStream &OS,
503+
memprof::IndexedMemProfData &MemProfData) {
507504
uint64_t HeaderUpdatePos = OS.tell();
508505
OS.write(0ULL); // Reserve space for the memprof record table offset.
509506
OS.write(0ULL); // Reserve space for the memprof frame payload offset.
@@ -512,23 +509,20 @@ static Error writeMemProfV0(
512509
auto Schema = memprof::getFullSchema();
513510
writeMemProfSchema(OS, Schema);
514511

515-
uint64_t RecordTableOffset =
516-
writeMemProfRecords(OS, MemProfRecordData, &Schema, memprof::Version0);
512+
uint64_t RecordTableOffset = writeMemProfRecords(OS, MemProfData.RecordData,
513+
&Schema, memprof::Version0);
517514

518515
uint64_t FramePayloadOffset = OS.tell();
519-
uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfFrameData);
516+
uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfData.FrameData);
520517

521518
uint64_t Header[] = {RecordTableOffset, FramePayloadOffset, FrameTableOffset};
522519
OS.patch({{HeaderUpdatePos, Header, std::size(Header)}});
523520

524521
return Error::success();
525522
}
526523

527-
static Error writeMemProfV1(
528-
ProfOStream &OS,
529-
llvm::MapVector<GlobalValue::GUID, memprof::IndexedMemProfRecord>
530-
&MemProfRecordData,
531-
llvm::MapVector<memprof::FrameId, memprof::Frame> &MemProfFrameData) {
524+
static Error writeMemProfV1(ProfOStream &OS,
525+
memprof::IndexedMemProfData &MemProfData) {
532526
OS.write(memprof::Version1);
533527
uint64_t HeaderUpdatePos = OS.tell();
534528
OS.write(0ULL); // Reserve space for the memprof record table offset.
@@ -538,26 +532,21 @@ static Error writeMemProfV1(
538532
auto Schema = memprof::getFullSchema();
539533
writeMemProfSchema(OS, Schema);
540534

541-
uint64_t RecordTableOffset =
542-
writeMemProfRecords(OS, MemProfRecordData, &Schema, memprof::Version1);
535+
uint64_t RecordTableOffset = writeMemProfRecords(OS, MemProfData.RecordData,
536+
&Schema, memprof::Version1);
543537

544538
uint64_t FramePayloadOffset = OS.tell();
545-
uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfFrameData);
539+
uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfData.FrameData);
546540

547541
uint64_t Header[] = {RecordTableOffset, FramePayloadOffset, FrameTableOffset};
548542
OS.patch({{HeaderUpdatePos, Header, std::size(Header)}});
549543

550544
return Error::success();
551545
}
552546

553-
static Error writeMemProfV2(
554-
ProfOStream &OS,
555-
llvm::MapVector<GlobalValue::GUID, memprof::IndexedMemProfRecord>
556-
&MemProfRecordData,
557-
llvm::MapVector<memprof::FrameId, memprof::Frame> &MemProfFrameData,
558-
llvm::MapVector<memprof::CallStackId, llvm::SmallVector<memprof::FrameId>>
559-
&MemProfCallStackData,
560-
bool MemProfFullSchema) {
547+
static Error writeMemProfV2(ProfOStream &OS,
548+
memprof::IndexedMemProfData &MemProfData,
549+
bool MemProfFullSchema) {
561550
OS.write(memprof::Version2);
562551
uint64_t HeaderUpdatePos = OS.tell();
563552
OS.write(0ULL); // Reserve space for the memprof record table offset.
@@ -571,15 +560,15 @@ static Error writeMemProfV2(
571560
Schema = memprof::getFullSchema();
572561
writeMemProfSchema(OS, Schema);
573562

574-
uint64_t RecordTableOffset =
575-
writeMemProfRecords(OS, MemProfRecordData, &Schema, memprof::Version2);
563+
uint64_t RecordTableOffset = writeMemProfRecords(OS, MemProfData.RecordData,
564+
&Schema, memprof::Version2);
576565

577566
uint64_t FramePayloadOffset = OS.tell();
578-
uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfFrameData);
567+
uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfData.FrameData);
579568

580569
uint64_t CallStackPayloadOffset = OS.tell();
581570
uint64_t CallStackTableOffset =
582-
writeMemProfCallStacks(OS, MemProfCallStackData);
571+
writeMemProfCallStacks(OS, MemProfData.CallStackData);
583572

584573
uint64_t Header[] = {
585574
RecordTableOffset, FramePayloadOffset, FrameTableOffset,
@@ -603,23 +592,17 @@ static Error writeMemProfV2(
603592
// uint64_t Schema entry N - 1
604593
// OnDiskChainedHashTable MemProfRecordData
605594
// OnDiskChainedHashTable MemProfFrameData
606-
static Error writeMemProf(
607-
ProfOStream &OS,
608-
llvm::MapVector<GlobalValue::GUID, memprof::IndexedMemProfRecord>
609-
&MemProfRecordData,
610-
llvm::MapVector<memprof::FrameId, memprof::Frame> &MemProfFrameData,
611-
llvm::MapVector<memprof::CallStackId, llvm::SmallVector<memprof::FrameId>>
612-
&MemProfCallStackData,
613-
memprof::IndexedVersion MemProfVersionRequested, bool MemProfFullSchema) {
614-
595+
static Error writeMemProf(ProfOStream &OS,
596+
memprof::IndexedMemProfData &MemProfData,
597+
memprof::IndexedVersion MemProfVersionRequested,
598+
bool MemProfFullSchema) {
615599
switch (MemProfVersionRequested) {
616600
case memprof::Version0:
617-
return writeMemProfV0(OS, MemProfRecordData, MemProfFrameData);
601+
return writeMemProfV0(OS, MemProfData);
618602
case memprof::Version1:
619-
return writeMemProfV1(OS, MemProfRecordData, MemProfFrameData);
603+
return writeMemProfV1(OS, MemProfData);
620604
case memprof::Version2:
621-
return writeMemProfV2(OS, MemProfRecordData, MemProfFrameData,
622-
MemProfCallStackData, MemProfFullSchema);
605+
return writeMemProfV2(OS, MemProfData, MemProfFullSchema);
623606
}
624607

625608
return make_error<InstrProfError>(
@@ -737,8 +720,7 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
737720
uint64_t MemProfSectionStart = 0;
738721
if (static_cast<bool>(ProfileKind & InstrProfKind::MemProf)) {
739722
MemProfSectionStart = OS.tell();
740-
if (auto E = writeMemProf(OS, MemProfRecordData, MemProfFrameData,
741-
MemProfCallStackData, MemProfVersionRequested,
723+
if (auto E = writeMemProf(OS, MemProfData, MemProfVersionRequested,
742724
MemProfFullSchema))
743725
return E;
744726
}

0 commit comments

Comments
 (0)