Skip to content

Commit 951742c

Browse files
[memprof] Use IndexedMemProfRecord in MemProfReader (NFC)
IndexedMemProfRecord contains a complete package of the MemProf profile, including frames, call stacks, and records. This patch replaces the three member variables of MemProfReader with IndexedMemProfRecord. This transition significantly simplies both the constructor and the final "take" method: MemProfReader(IndexedMemProfData MemProfData) : MemProfData(std::move(MemProfData)) {} IndexedMemProfData takeMemProfData() { return std::move(MemProfData); }
1 parent fe3c23b commit 951742c

File tree

2 files changed

+19
-44
lines changed

2 files changed

+19
-44
lines changed

llvm/include/llvm/ProfileData/MemProfReader.h

Lines changed: 13 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -42,43 +42,28 @@ class MemProfReader {
4242
using Iterator = InstrProfIterator<GuidMemProfRecordPair, MemProfReader>;
4343
Iterator end() { return Iterator(); }
4444
Iterator begin() {
45-
Iter = FunctionProfileData.begin();
45+
Iter = MemProfData.Records.begin();
4646
return Iterator(this);
4747
}
4848

4949
// Take the complete profile data.
50-
IndexedMemProfData takeMemProfData() {
51-
// TODO: Once we replace the three member variables, namely IdToFrame,
52-
// CSIdToCallStack, and FunctionProfileData, with MemProfData, replace the
53-
// following code with just "return std::move(MemProfData);".
54-
IndexedMemProfData MemProfData;
55-
// Copy key-value pairs because IdToFrame uses DenseMap, whereas
56-
// IndexedMemProfData::Frames uses MapVector.
57-
for (const auto &[FrameId, F] : IdToFrame)
58-
MemProfData.Frames.try_emplace(FrameId, F);
59-
// Copy key-value pairs because CSIdToCallStack uses DenseMap, whereas
60-
// IndexedMemProfData::CallStacks uses MapVector.
61-
for (const auto &[CSId, CS] : CSIdToCallStack)
62-
MemProfData.CallStacks.try_emplace(CSId, CS);
63-
MemProfData.Records = FunctionProfileData;
64-
return MemProfData;
65-
}
50+
IndexedMemProfData takeMemProfData() { return std::move(MemProfData); }
6651

6752
virtual Error
6853
readNextRecord(GuidMemProfRecordPair &GuidRecord,
6954
std::function<const Frame(const FrameId)> Callback = nullptr) {
70-
if (FunctionProfileData.empty())
55+
if (MemProfData.Records.empty())
7156
return make_error<InstrProfError>(instrprof_error::empty_raw_profile);
7257

73-
if (Iter == FunctionProfileData.end())
58+
if (Iter == MemProfData.Records.end())
7459
return make_error<InstrProfError>(instrprof_error::eof);
7560

7661
if (Callback == nullptr)
7762
Callback =
7863
std::bind(&MemProfReader::idToFrame, this, std::placeholders::_1);
7964

80-
CallStackIdConverter<decltype(CSIdToCallStack)> CSIdConv(CSIdToCallStack,
81-
Callback);
65+
CallStackIdConverter<decltype(MemProfData.CallStacks)> CSIdConv(
66+
MemProfData.CallStacks, Callback);
8267

8368
const IndexedMemProfRecord &IndexedRecord = Iter->second;
8469
GuidRecord = {
@@ -97,28 +82,18 @@ class MemProfReader {
9782
virtual ~MemProfReader() = default;
9883

9984
// Initialize the MemProfReader with the given MemProf profile.
100-
MemProfReader(IndexedMemProfData MemProfData) {
101-
for (const auto &[FrameId, F] : MemProfData.Frames)
102-
IdToFrame.try_emplace(FrameId, F);
103-
for (const auto &[CSId, CS] : MemProfData.CallStacks)
104-
CSIdToCallStack.try_emplace(CSId, CS);
105-
FunctionProfileData = std::move(MemProfData.Records);
106-
}
85+
MemProfReader(IndexedMemProfData MemProfData)
86+
: MemProfData(std::move(MemProfData)) {}
10787

10888
protected:
10989
// A helper method to extract the frame from the IdToFrame map.
11090
const Frame &idToFrame(const FrameId Id) const {
111-
auto It = IdToFrame.find(Id);
112-
assert(It != IdToFrame.end() && "Id not found in map.");
113-
return It->getSecond();
91+
auto It = MemProfData.Frames.find(Id);
92+
assert(It != MemProfData.Frames.end() && "Id not found in map.");
93+
return It->second;
11494
}
115-
// A mapping from FrameId (a hash of the contents) to the frame.
116-
llvm::DenseMap<FrameId, Frame> IdToFrame;
117-
// A mapping from CallStackId to the call stack.
118-
llvm::DenseMap<CallStackId, llvm::SmallVector<FrameId>> CSIdToCallStack;
119-
// A mapping from function GUID, hash of the canonical function symbol to the
120-
// memprof profile data for that function, i.e allocation and callsite info.
121-
llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord> FunctionProfileData;
95+
// A complete pacakge of the MemProf profile.
96+
IndexedMemProfData MemProfData;
12297
// An iterator to the internal function profile data structure.
12398
llvm::MapVector<GlobalValue::GUID, IndexedMemProfRecord>::iterator Iter;
12499
};

llvm/lib/ProfileData/MemProfReader.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ bool RawMemProfReader::hasFormat(const MemoryBuffer &Buffer) {
304304

305305
void RawMemProfReader::printYAML(raw_ostream &OS) {
306306
uint64_t NumAllocFunctions = 0, NumMibInfo = 0;
307-
for (const auto &KV : FunctionProfileData) {
307+
for (const auto &KV : MemProfData.Records) {
308308
const size_t NumAllocSites = KV.second.AllocSites.size();
309309
if (NumAllocSites > 0) {
310310
NumAllocFunctions++;
@@ -500,13 +500,13 @@ Error RawMemProfReader::mapRawProfileToRecords() {
500500
}
501501

502502
CallStackId CSId = hashCallStack(Callstack);
503-
CSIdToCallStack.insert({CSId, Callstack});
503+
MemProfData.CallStacks.insert({CSId, Callstack});
504504

505505
// We attach the memprof record to each function bottom-up including the
506506
// first non-inline frame.
507507
for (size_t I = 0; /*Break out using the condition below*/; I++) {
508508
const Frame &F = idToFrame(Callstack[I]);
509-
IndexedMemProfRecord &Record = FunctionProfileData[F.Function];
509+
IndexedMemProfRecord &Record = MemProfData.Records[F.Function];
510510
Record.AllocSites.emplace_back(Callstack, CSId, MIB);
511511

512512
if (!F.IsInlineFrame)
@@ -518,10 +518,10 @@ Error RawMemProfReader::mapRawProfileToRecords() {
518518
for (const auto &[Id, Locs] : PerFunctionCallSites) {
519519
// Some functions may have only callsite data and no allocation data. Here
520520
// we insert a new entry for callsite data if we need to.
521-
IndexedMemProfRecord &Record = FunctionProfileData[Id];
521+
IndexedMemProfRecord &Record = MemProfData.Records[Id];
522522
for (LocationPtr Loc : Locs) {
523523
CallStackId CSId = hashCallStack(*Loc);
524-
CSIdToCallStack.insert({CSId, *Loc});
524+
MemProfData.CallStacks.insert({CSId, *Loc});
525525
Record.CallSites.push_back(*Loc);
526526
Record.CallSiteIds.push_back(CSId);
527527
}
@@ -585,7 +585,7 @@ Error RawMemProfReader::symbolizeAndFilterStackFrames(
585585
}
586586

587587
const FrameId Hash = F.hash();
588-
IdToFrame.insert({Hash, F});
588+
MemProfData.Frames.insert({Hash, F});
589589
SymbolizedFrame[VAddr].push_back(Hash);
590590
}
591591
}

0 commit comments

Comments
 (0)