Skip to content
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: 1 addition & 1 deletion llvm/include/llvm/ProfileData/InstrProfReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ class IndexedMemProfReader {
// The number of elements in the radix tree array.
unsigned RadixTreeSize = 0;

Error deserializeV12(const unsigned char *Start, const unsigned char *Ptr);
Error deserializeV2(const unsigned char *Start, const unsigned char *Ptr);
Error deserializeV3(const unsigned char *Start, const unsigned char *Ptr);

public:
Expand Down
18 changes: 1 addition & 17 deletions llvm/include/llvm/ProfileData/MemProf.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,14 @@ struct MemProfRecord;

// The versions of the indexed MemProf format
enum IndexedVersion : uint64_t {
// Version 1: Added a version field to the header.
Version1 = 1,
// Version 2: Added a call stack table.
Version2 = 2,
// Version 3: Added a radix tree for call stacks. Switched to linear IDs for
// frames and call stacks.
Version3 = 3,
};

constexpr uint64_t MinimumSupportedVersion = Version1;
constexpr uint64_t MinimumSupportedVersion = Version2;
constexpr uint64_t MaximumSupportedVersion = Version3;

// Verify that the minimum and maximum satisfy the obvious constraint.
Expand Down Expand Up @@ -486,20 +484,6 @@ struct MemProfRecord {
llvm::SmallVector<std::vector<Frame>> CallSites;

MemProfRecord() = default;
MemProfRecord(
const IndexedMemProfRecord &Record,
llvm::function_ref<const Frame(const FrameId Id)> IdToFrameCallback) {
for (const IndexedAllocationInfo &IndexedAI : Record.AllocSites) {
AllocSites.emplace_back(IndexedAI, IdToFrameCallback);
}
for (const ArrayRef<FrameId> Site : Record.CallSites) {
std::vector<Frame> Frames;
for (const FrameId Id : Site) {
Frames.push_back(IdToFrameCallback(Id));
}
CallSites.push_back(Frames);
}
}

// Prints out the contents of the memprof record in YAML.
void print(llvm::raw_ostream &OS) const {
Expand Down
34 changes: 4 additions & 30 deletions llvm/lib/ProfileData/InstrProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1225,8 +1225,8 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
}
}

Error IndexedMemProfReader::deserializeV12(const unsigned char *Start,
const unsigned char *Ptr) {
Error IndexedMemProfReader::deserializeV2(const unsigned char *Start,
const unsigned char *Ptr) {
// The value returned from RecordTableGenerator.Emit.
const uint64_t RecordTableOffset =
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
Expand Down Expand Up @@ -1322,8 +1322,7 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start,
const uint64_t FirstWord =
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);

if (FirstWord == memprof::Version1 || FirstWord == memprof::Version2 ||
FirstWord == memprof::Version3) {
if (FirstWord == memprof::Version2 || FirstWord == memprof::Version3) {
// Everything is good. We can proceed to deserialize the rest.
Version = static_cast<memprof::IndexedVersion>(FirstWord);
} else {
Expand All @@ -1336,9 +1335,8 @@ Error IndexedMemProfReader::deserialize(const unsigned char *Start,
}

switch (Version) {
case memprof::Version1:
case memprof::Version2:
if (Error E = deserializeV12(Start, Ptr))
if (Error E = deserializeV2(Start, Ptr))
return E;
break;
case memprof::Version3:
Expand Down Expand Up @@ -1558,25 +1556,6 @@ 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,
Expand Down Expand Up @@ -1631,11 +1610,6 @@ IndexedMemProfReader::getMemProfRecord(const uint64_t FuncNameHash) const {

const memprof::IndexedMemProfRecord &IndexedRecord = *Iter;
switch (Version) {
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");
Expand Down
37 changes: 0 additions & 37 deletions llvm/lib/ProfileData/InstrProfWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,41 +649,6 @@ writeMemProfCallStackArray(
return MemProfCallStackIndexes;
}

// Write out MemProf Version1 as follows:
// uint64_t Version (NEW in V1)
// uint64_t RecordTableOffset = RecordTableGenerator.Emit
// uint64_t FramePayloadOffset = Offset for the frame payload
// uint64_t FrameTableOffset = FrameTableGenerator.Emit
// uint64_t Num schema entries
// uint64_t Schema entry 0
// uint64_t Schema entry 1
// ....
// uint64_t Schema entry N - 1
// OnDiskChainedHashTable MemProfRecordData
// OnDiskChainedHashTable MemProfFrameData
static Error writeMemProfV1(ProfOStream &OS,
memprof::IndexedMemProfData &MemProfData) {
OS.write(memprof::Version1);
uint64_t HeaderUpdatePos = OS.tell();
OS.write(0ULL); // Reserve space for the memprof record table offset.
OS.write(0ULL); // Reserve space for the memprof frame payload offset.
OS.write(0ULL); // Reserve space for the memprof frame table offset.

auto Schema = memprof::getFullSchema();
writeMemProfSchema(OS, Schema);

uint64_t RecordTableOffset =
writeMemProfRecords(OS, MemProfData.Records, &Schema, memprof::Version1);

uint64_t FramePayloadOffset = OS.tell();
uint64_t FrameTableOffset = writeMemProfFrames(OS, MemProfData.Frames);

uint64_t Header[] = {RecordTableOffset, FramePayloadOffset, FrameTableOffset};
OS.patch({{HeaderUpdatePos, Header}});

return Error::success();
}

// Write out MemProf Version2 as follows:
// uint64_t Version
// uint64_t RecordTableOffset = RecordTableGenerator.Emit
Expand Down Expand Up @@ -805,8 +770,6 @@ static Error writeMemProf(ProfOStream &OS,
memprof::IndexedVersion MemProfVersionRequested,
bool MemProfFullSchema) {
switch (MemProfVersionRequested) {
case memprof::Version1:
return writeMemProfV1(OS, MemProfData);
case memprof::Version2:
return writeMemProfV2(OS, MemProfData, MemProfFullSchema);
case memprof::Version3:
Expand Down
105 changes: 0 additions & 105 deletions llvm/lib/ProfileData/MemProf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,6 @@ MemProfSchema getHotColdSchema() {
Meta::TotalLifetimeAccessDensity};
}

static size_t serializedSizeV0(const IndexedAllocationInfo &IAI,
const MemProfSchema &Schema) {
size_t Size = 0;
// The number of frames to serialize.
Size += sizeof(uint64_t);
// The callstack frame ids.
Size += sizeof(FrameId) * IAI.CallStack.size();
// The size of the payload.
Size += PortableMemInfoBlock::serializedSize(Schema);
return Size;
}

static size_t serializedSizeV2(const IndexedAllocationInfo &IAI,
const MemProfSchema &Schema) {
size_t Size = 0;
Expand All @@ -58,8 +46,6 @@ static size_t serializedSizeV3(const IndexedAllocationInfo &IAI,
size_t IndexedAllocationInfo::serializedSize(const MemProfSchema &Schema,
IndexedVersion Version) const {
switch (Version) {
case Version1:
return serializedSizeV0(*this, Schema);
case Version2:
return serializedSizeV2(*this, Schema);
case Version3:
Expand All @@ -68,23 +54,6 @@ size_t IndexedAllocationInfo::serializedSize(const MemProfSchema &Schema,
llvm_unreachable("unsupported MemProf version");
}

static size_t serializedSizeV1(const IndexedMemProfRecord &Record,
const MemProfSchema &Schema) {
// The number of alloc sites to serialize.
size_t Result = sizeof(uint64_t);
for (const IndexedAllocationInfo &N : Record.AllocSites)
Result += N.serializedSize(Schema, Version1);

// The number of callsites we have information for.
Result += sizeof(uint64_t);
for (const auto &Frames : Record.CallSites) {
// The number of frame ids to serialize.
Result += sizeof(uint64_t);
Result += Frames.size() * sizeof(FrameId);
}
return Result;
}

static size_t serializedSizeV2(const IndexedMemProfRecord &Record,
const MemProfSchema &Schema) {
// The number of alloc sites to serialize.
Expand Down Expand Up @@ -116,8 +85,6 @@ static size_t serializedSizeV3(const IndexedMemProfRecord &Record,
size_t IndexedMemProfRecord::serializedSize(const MemProfSchema &Schema,
IndexedVersion Version) const {
switch (Version) {
case Version1:
return serializedSizeV1(*this, Schema);
case Version2:
return serializedSizeV2(*this, Schema);
case Version3:
Expand All @@ -126,29 +93,6 @@ size_t IndexedMemProfRecord::serializedSize(const MemProfSchema &Schema,
llvm_unreachable("unsupported MemProf version");
}

static void serializeV1(const IndexedMemProfRecord &Record,
const MemProfSchema &Schema, raw_ostream &OS) {
using namespace support;

endian::Writer LE(OS, llvm::endianness::little);

LE.write<uint64_t>(Record.AllocSites.size());
for (const IndexedAllocationInfo &N : Record.AllocSites) {
LE.write<uint64_t>(N.CallStack.size());
for (const FrameId &Id : N.CallStack)
LE.write<FrameId>(Id);
N.Info.serialize(Schema, OS);
}

// Related contexts.
LE.write<uint64_t>(Record.CallSites.size());
for (const auto &Frames : Record.CallSites) {
LE.write<uint64_t>(Frames.size());
for (const FrameId &Id : Frames)
LE.write<FrameId>(Id);
}
}

static void serializeV2(const IndexedMemProfRecord &Record,
const MemProfSchema &Schema, raw_ostream &OS) {
using namespace support;
Expand Down Expand Up @@ -195,9 +139,6 @@ void IndexedMemProfRecord::serialize(
llvm::DenseMap<CallStackId, LinearCallStackId> *MemProfCallStackIndexes)
const {
switch (Version) {
case Version1:
serializeV1(*this, Schema, OS);
return;
case Version2:
serializeV2(*this, Schema, OS);
return;
Expand All @@ -208,50 +149,6 @@ void IndexedMemProfRecord::serialize(
llvm_unreachable("unsupported MemProf version");
}

static IndexedMemProfRecord deserializeV1(const MemProfSchema &Schema,
const unsigned char *Ptr) {
using namespace support;

IndexedMemProfRecord Record;

// Read the meminfo nodes.
const uint64_t NumNodes =
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (uint64_t I = 0; I < NumNodes; I++) {
IndexedAllocationInfo Node;
const uint64_t NumFrames =
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (uint64_t J = 0; J < NumFrames; J++) {
const FrameId Id =
endian::readNext<FrameId, llvm::endianness::little>(Ptr);
Node.CallStack.push_back(Id);
}
Node.CSId = hashCallStack(Node.CallStack);
Node.Info.deserialize(Schema, Ptr);
Ptr += PortableMemInfoBlock::serializedSize(Schema);
Record.AllocSites.push_back(Node);
}

// Read the callsite information.
const uint64_t NumCtxs =
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
for (uint64_t J = 0; J < NumCtxs; J++) {
const uint64_t NumFrames =
endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
llvm::SmallVector<FrameId> Frames;
Frames.reserve(NumFrames);
for (uint64_t K = 0; K < NumFrames; K++) {
const FrameId Id =
endian::readNext<FrameId, llvm::endianness::little>(Ptr);
Frames.push_back(Id);
}
Record.CallSites.push_back(Frames);
Record.CallSiteIds.push_back(hashCallStack(Frames));
}

return Record;
}

static IndexedMemProfRecord deserializeV2(const MemProfSchema &Schema,
const unsigned char *Ptr) {
using namespace support;
Expand Down Expand Up @@ -324,8 +221,6 @@ IndexedMemProfRecord::deserialize(const MemProfSchema &Schema,
const unsigned char *Ptr,
IndexedVersion Version) {
switch (Version) {
case Version1:
return deserializeV1(Schema, Ptr);
case Version2:
return deserializeV2(Schema, Ptr);
case Version3:
Expand Down
3 changes: 0 additions & 3 deletions llvm/test/tools/llvm-profdata/memprof-merge-versions.test
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ RUN: echo "1" >> %t.proftext
RUN: echo "1" >> %t.proftext

To update the inputs used below run Inputs/update_memprof_inputs.sh /path/to/updated/clang
RUN: llvm-profdata merge %t.proftext %p/Inputs/basic.memprofraw --memprof-version=1 --profiled-binary %p/Inputs/basic.memprofexe -o %t.prof.v1
RUN: llvm-profdata show %t.prof.v1 | FileCheck %s

RUN: llvm-profdata merge %t.proftext %p/Inputs/basic.memprofraw --memprof-version=2 --profiled-binary %p/Inputs/basic.memprofexe -o %t.prof.v2
RUN: llvm-profdata show %t.prof.v2 | FileCheck %s

Expand Down
3 changes: 1 addition & 2 deletions llvm/tools/llvm-profdata/llvm-profdata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,8 +333,7 @@ cl::opt<memprof::IndexedVersion> MemProfVersionRequested(
"memprof-version", cl::Hidden, cl::sub(MergeSubcommand),
cl::desc("Specify the version of the memprof format to use"),
cl::init(memprof::Version3),
cl::values(clEnumValN(memprof::Version1, "1", "version 1"),
clEnumValN(memprof::Version2, "2", "version 2"),
cl::values(clEnumValN(memprof::Version2, "2", "version 2"),
clEnumValN(memprof::Version3, "3", "version 3")));

cl::opt<bool> MemProfFullSchema(
Expand Down
Loading
Loading