Skip to content

[memprof] Refactor getMemProfRecord (NFC) #93138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/include/llvm/ProfileData/InstrProfReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,8 @@ class InstrProfReaderRemapper {

class IndexedMemProfReader {
private:
/// The MemProf version.
memprof::IndexedVersion Version = memprof::Version0;
/// MemProf profile schema (if available).
memprof::MemProfSchema Schema;
/// MemProf record profile data on-disk indexed via llvm::md5(FunctionName).
Expand Down
100 changes: 67 additions & 33 deletions llvm/lib/ProfileData/InstrProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,6 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start,
const uint64_t FirstWord =
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);

memprof::IndexedVersion Version = memprof::Version0;
if (FirstWord == memprof::Version1 || FirstWord == memprof::Version2) {
// Everything is good. We can proceed to deserialize the rest.
Version = static_cast<memprof::IndexedVersion>(FirstWord);
Expand Down Expand Up @@ -1490,6 +1489,55 @@ Expected<InstrProfRecord> IndexedInstrProfReader::getInstrProfRecord(
return error(instrprof_error::unknown_function);
}

static Expected<memprof::MemProfRecord>
getMemProfRecordV0(const memprof::IndexedMemProfRecord &IndexedRecord,
MemProfFrameHashTable &MemProfFrameTable) {
memprof::FrameIdConverter<MemProfFrameHashTable> FrameIdConv(
MemProfFrameTable);

memprof::MemProfRecord Record =
memprof::MemProfRecord(IndexedRecord, FrameIdConv);

// Check that all frame ids were successfully converted to frames.
if (FrameIdConv.LastUnmappedId) {
return make_error<InstrProfError>(instrprof_error::hash_mismatch,
"memprof frame not found for frame id " +
Twine(*FrameIdConv.LastUnmappedId));
}

return Record;
}

static Expected<memprof::MemProfRecord>
getMemProfRecordV2(const memprof::IndexedMemProfRecord &IndexedRecord,
MemProfFrameHashTable &MemProfFrameTable,
MemProfCallStackHashTable &MemProfCallStackTable) {
memprof::FrameIdConverter<MemProfFrameHashTable> FrameIdConv(
MemProfFrameTable);

memprof::CallStackIdConverter<MemProfCallStackHashTable> CSIdConv(
MemProfCallStackTable, FrameIdConv);

memprof::MemProfRecord Record = IndexedRecord.toMemProfRecord(CSIdConv);

// Check that all call stack ids were successfully converted to call stacks.
if (CSIdConv.LastUnmappedId) {
return make_error<InstrProfError>(
instrprof_error::hash_mismatch,
"memprof call stack not found for call stack id " +
Twine(*CSIdConv.LastUnmappedId));
}

// Check that all frame ids were successfully converted to frames.
if (FrameIdConv.LastUnmappedId) {
return make_error<InstrProfError>(instrprof_error::hash_mismatch,
"memprof frame not found for frame id " +
Twine(*FrameIdConv.LastUnmappedId));
}

return Record;
}

Expected<memprof::MemProfRecord>
IndexedMemProfReader::getMemProfRecord(const uint64_t FuncNameHash) const {
// TODO: Add memprof specific errors.
Expand All @@ -1502,41 +1550,27 @@ IndexedMemProfReader::getMemProfRecord(const uint64_t FuncNameHash) const {
instrprof_error::unknown_function,
"memprof record not found for function hash " + Twine(FuncNameHash));

// Setup a callback to convert from frame ids to frame using the on-disk
// FrameData hash table.
memprof::FrameIdConverter<MemProfFrameHashTable> FrameIdConv(
*MemProfFrameTable.get());

const memprof::IndexedMemProfRecord IndexedRecord = *Iter;
memprof::MemProfRecord Record;
if (MemProfCallStackTable) {
// Setup a callback to convert call stack ids to call stacks using the
// on-disk hash table.
memprof::CallStackIdConverter<MemProfCallStackHashTable> CSIdConv(
*MemProfCallStackTable.get(), FrameIdConv);

Record = IndexedRecord.toMemProfRecord(CSIdConv);

// Check that all call stack ids were successfully converted to call stacks.
if (CSIdConv.LastUnmappedId) {
return make_error<InstrProfError>(
instrprof_error::hash_mismatch,
"memprof call stack not found for call stack id " +
Twine(*CSIdConv.LastUnmappedId));
}
} else {
Record = memprof::MemProfRecord(IndexedRecord, FrameIdConv);
switch (Version) {
case memprof::Version0:
case memprof::Version1:
assert(MemProfFrameTable && "MemProfFrameTable must be available");
assert(!MemProfCallStackTable &&
"MemProfCallStackTable must not be available");
return getMemProfRecordV0(IndexedRecord, *MemProfFrameTable);
case memprof::Version2:
assert(MemProfFrameTable && "MemProfFrameTable must be available");
assert(MemProfCallStackTable && "MemProfCallStackTable must be available");
return getMemProfRecordV2(IndexedRecord, *MemProfFrameTable,
*MemProfCallStackTable);
}

// Check that all frame ids were successfully converted to frames.
if (FrameIdConv.LastUnmappedId) {
return make_error<InstrProfError>(
instrprof_error::hash_mismatch,
"memprof frame not found for frame id " +
Twine(*FrameIdConv.LastUnmappedId));
}

return Record;
return make_error<InstrProfError>(
instrprof_error::unsupported_version,
formatv("MemProf version {} not supported; "
"requires version between {} and {}, inclusive",
Version, memprof::MinimumSupportedVersion,
memprof::MaximumSupportedVersion));
}

Error IndexedInstrProfReader::getFunctionCounts(StringRef FuncName,
Expand Down
Loading