[memprof] Add MemProfReader::takeMemProfData (#116769)

This patch adds MemProfReader::takeMemProfData, a function to return
the complete MemProf profile from the reader.  We can directly pass
its return value to InstrProfWriter::addMemProfData without having to
deal with the indivual components of the MemProf profile.  The new
function is named "take", but it doesn't do std::move yet because of
type differences (DenseMap v.s. MapVector).

The end state I'm trying to get to is roughly as follows:

- MemProfReader accepts IndexedMemProfData as a parameter as opposed
  to the three individual components (frames, call stacks, and
  records).

- MemProfReader keeps IndexedMemProfData as a class member without
  decomposing it into its individual components.

- MemProfReader returns IndexedMemProfData like:

  IndexedMemProfData takeMemProfData() {
    return std::move(MemProfData);
  }
This commit is contained in:
Kazu Hirata
2024-11-19 19:33:26 -08:00
committed by GitHub
parent a2e266b346
commit f97c610d1f
3 changed files with 21 additions and 28 deletions

View File

@@ -63,6 +63,24 @@ public:
return FunctionProfileData;
}
// Take the complete profile data.
IndexedMemProfData takeMemProfData() {
// TODO: Once we replace the three member variables, namely IdToFrame,
// CSIdToCallStack, and FunctionProfileData, with MemProfData, replace the
// following code with just "return std::move(MemProfData);".
IndexedMemProfData MemProfData;
// Copy key-value pairs because IdToFrame uses DenseMap, whereas
// IndexedMemProfData::Frames uses MapVector.
for (const auto &[FrameId, F] : IdToFrame)
MemProfData.Frames.try_emplace(FrameId, F);
// Copy key-value pairs because CSIdToCallStack uses DenseMap, whereas
// IndexedMemProfData::CallStacks uses MapVector.
for (const auto &[CSId, CS] : CSIdToCallStack)
MemProfData.CallStacks.try_emplace(CSId, CS);
MemProfData.Records = FunctionProfileData;
return MemProfData;
}
virtual Error
readNextRecord(GuidMemProfRecordPair &GuidRecord,
std::function<const Frame(const FrameId)> Callback = nullptr) {

View File

@@ -370,7 +370,8 @@ bool InstrProfWriter::addMemProfData(memprof::IndexedMemProfData Incoming,
if (addMemProfCallStack(CSId, CS, Warn))
return false;
if (MemProfData.Records.empty())
// Add one record at a time if randomization is requested.
if (MemProfData.Records.empty() && !MemprofGenerateRandomHotness)
MemProfData.Records = std::move(Incoming.Records);
else
for (const auto &[GUID, Record] : Incoming.Records)

View File

@@ -720,33 +720,7 @@ loadInput(const WeightedFile &Input, SymbolRemapper *Remapper,
Filename);
};
// Add the frame mappings into the writer context.
const auto &IdToFrame = Reader->getFrameMapping();
for (const auto &I : IdToFrame) {
bool Succeeded = WC->Writer.addMemProfFrame(
/*Id=*/I.first, /*Frame=*/I.getSecond(), MemProfError);
// If we weren't able to add the frame mappings then it doesn't make sense
// to try to add the records from this profile.
if (!Succeeded)
return;
}
// Add the call stacks into the writer context.
const auto &CSIdToCallStacks = Reader->getCallStacks();
for (const auto &I : CSIdToCallStacks) {
bool Succeeded = WC->Writer.addMemProfCallStack(
/*Id=*/I.first, /*Frame=*/I.getSecond(), MemProfError);
// If we weren't able to add the call stacks then it doesn't make sense
// to try to add the records from this profile.
if (!Succeeded)
return;
}
const auto &FunctionProfileData = Reader->getProfileData();
// Add the memprof records into the writer context.
for (const auto &[GUID, Record] : FunctionProfileData) {
WC->Writer.addMemProfRecord(GUID, Record);
}
WC->Writer.addMemProfData(Reader->takeMemProfData(), MemProfError);
return;
}