[memprof] Move IndexedMemProfReader::deserialize to IndexedemProfData.cpp (NFC) (#137089)
This patch moves IndexedMemProfReader::deserialize and its subroutines to IndexedMemProfData.cpp, building on: commit 9a8f90dba3f8c25cbb3525a482053d3abcd3fddc Author: Kazu Hirata <kazu@google.com> Date: Wed Apr 23 15:39:45 2025 -0700 The intent is as follows: - Reduce the size of InstrProfReader.cpp. - Move the subroutines to a separate file because they don't interact with anything else in InstrProfReader.cpp.
This commit is contained in:
parent
30fec128e8
commit
ea0dbee808
@ -11,6 +11,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ProfileData/InstrProf.h"
|
||||
#include "llvm/ProfileData/InstrProfReader.h"
|
||||
#include "llvm/ProfileData/MemProf.h"
|
||||
#include "llvm/Support/FormatVariadic.h"
|
||||
#include "llvm/Support/OnDiskHashTable.h"
|
||||
@ -297,4 +298,127 @@ Error writeMemProf(ProfOStream &OS, memprof::IndexedMemProfData &MemProfData,
|
||||
memprof::MaximumSupportedVersion));
|
||||
}
|
||||
|
||||
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);
|
||||
// The offset in the stream right before invoking
|
||||
// FrameTableGenerator.Emit.
|
||||
const uint64_t FramePayloadOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
// The value returned from FrameTableGenerator.Emit.
|
||||
const uint64_t FrameTableOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
|
||||
// The offset in the stream right before invoking
|
||||
// CallStackTableGenerator.Emit.
|
||||
uint64_t CallStackPayloadOffset = 0;
|
||||
// The value returned from CallStackTableGenerator.Emit.
|
||||
uint64_t CallStackTableOffset = 0;
|
||||
if (Version >= memprof::Version2) {
|
||||
CallStackPayloadOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
CallStackTableOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
}
|
||||
|
||||
// Read the schema.
|
||||
auto SchemaOr = memprof::readMemProfSchema(Ptr);
|
||||
if (!SchemaOr)
|
||||
return SchemaOr.takeError();
|
||||
Schema = SchemaOr.get();
|
||||
|
||||
// Now initialize the table reader with a pointer into data buffer.
|
||||
MemProfRecordTable.reset(MemProfRecordHashTable::Create(
|
||||
/*Buckets=*/Start + RecordTableOffset,
|
||||
/*Payload=*/Ptr,
|
||||
/*Base=*/Start, memprof::RecordLookupTrait(Version, Schema)));
|
||||
|
||||
// Initialize the frame table reader with the payload and bucket offsets.
|
||||
MemProfFrameTable.reset(MemProfFrameHashTable::Create(
|
||||
/*Buckets=*/Start + FrameTableOffset,
|
||||
/*Payload=*/Start + FramePayloadOffset,
|
||||
/*Base=*/Start));
|
||||
|
||||
if (Version >= memprof::Version2)
|
||||
MemProfCallStackTable.reset(MemProfCallStackHashTable::Create(
|
||||
/*Buckets=*/Start + CallStackTableOffset,
|
||||
/*Payload=*/Start + CallStackPayloadOffset,
|
||||
/*Base=*/Start));
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error IndexedMemProfReader::deserializeV3(const unsigned char *Start,
|
||||
const unsigned char *Ptr) {
|
||||
// The offset in the stream right before invoking
|
||||
// CallStackTableGenerator.Emit.
|
||||
const uint64_t CallStackPayloadOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
// The offset in the stream right before invoking RecordTableGenerator.Emit.
|
||||
const uint64_t RecordPayloadOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
// The value returned from RecordTableGenerator.Emit.
|
||||
const uint64_t RecordTableOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
|
||||
// Read the schema.
|
||||
auto SchemaOr = memprof::readMemProfSchema(Ptr);
|
||||
if (!SchemaOr)
|
||||
return SchemaOr.takeError();
|
||||
Schema = SchemaOr.get();
|
||||
|
||||
FrameBase = Ptr;
|
||||
CallStackBase = Start + CallStackPayloadOffset;
|
||||
|
||||
// Compute the number of elements in the radix tree array. Since we use this
|
||||
// to reserve enough bits in a BitVector, it's totally OK if we overestimate
|
||||
// this number a little bit because of padding just before the next section.
|
||||
RadixTreeSize = (RecordPayloadOffset - CallStackPayloadOffset) /
|
||||
sizeof(memprof::LinearFrameId);
|
||||
|
||||
// Now initialize the table reader with a pointer into data buffer.
|
||||
MemProfRecordTable.reset(MemProfRecordHashTable::Create(
|
||||
/*Buckets=*/Start + RecordTableOffset,
|
||||
/*Payload=*/Start + RecordPayloadOffset,
|
||||
/*Base=*/Start, memprof::RecordLookupTrait(memprof::Version3, Schema)));
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error IndexedMemProfReader::deserialize(const unsigned char *Start,
|
||||
uint64_t MemProfOffset) {
|
||||
const unsigned char *Ptr = Start + MemProfOffset;
|
||||
|
||||
// Read the MemProf version number.
|
||||
const uint64_t FirstWord =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
|
||||
if (FirstWord == memprof::Version2 || FirstWord == memprof::Version3) {
|
||||
// Everything is good. We can proceed to deserialize the rest.
|
||||
Version = static_cast<memprof::IndexedVersion>(FirstWord);
|
||||
} else {
|
||||
return make_error<InstrProfError>(
|
||||
instrprof_error::unsupported_version,
|
||||
formatv("MemProf version {} not supported; "
|
||||
"requires version between {} and {}, inclusive",
|
||||
FirstWord, memprof::MinimumSupportedVersion,
|
||||
memprof::MaximumSupportedVersion));
|
||||
}
|
||||
|
||||
switch (Version) {
|
||||
case memprof::Version2:
|
||||
if (Error E = deserializeV2(Start, Ptr))
|
||||
return E;
|
||||
break;
|
||||
case memprof::Version3:
|
||||
if (Error E = deserializeV3(Start, Ptr))
|
||||
return E;
|
||||
break;
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
@ -1230,129 +1230,6 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
// The offset in the stream right before invoking
|
||||
// FrameTableGenerator.Emit.
|
||||
const uint64_t FramePayloadOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
// The value returned from FrameTableGenerator.Emit.
|
||||
const uint64_t FrameTableOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
|
||||
// The offset in the stream right before invoking
|
||||
// CallStackTableGenerator.Emit.
|
||||
uint64_t CallStackPayloadOffset = 0;
|
||||
// The value returned from CallStackTableGenerator.Emit.
|
||||
uint64_t CallStackTableOffset = 0;
|
||||
if (Version >= memprof::Version2) {
|
||||
CallStackPayloadOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
CallStackTableOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
}
|
||||
|
||||
// Read the schema.
|
||||
auto SchemaOr = memprof::readMemProfSchema(Ptr);
|
||||
if (!SchemaOr)
|
||||
return SchemaOr.takeError();
|
||||
Schema = SchemaOr.get();
|
||||
|
||||
// Now initialize the table reader with a pointer into data buffer.
|
||||
MemProfRecordTable.reset(MemProfRecordHashTable::Create(
|
||||
/*Buckets=*/Start + RecordTableOffset,
|
||||
/*Payload=*/Ptr,
|
||||
/*Base=*/Start, memprof::RecordLookupTrait(Version, Schema)));
|
||||
|
||||
// Initialize the frame table reader with the payload and bucket offsets.
|
||||
MemProfFrameTable.reset(MemProfFrameHashTable::Create(
|
||||
/*Buckets=*/Start + FrameTableOffset,
|
||||
/*Payload=*/Start + FramePayloadOffset,
|
||||
/*Base=*/Start));
|
||||
|
||||
if (Version >= memprof::Version2)
|
||||
MemProfCallStackTable.reset(MemProfCallStackHashTable::Create(
|
||||
/*Buckets=*/Start + CallStackTableOffset,
|
||||
/*Payload=*/Start + CallStackPayloadOffset,
|
||||
/*Base=*/Start));
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error IndexedMemProfReader::deserializeV3(const unsigned char *Start,
|
||||
const unsigned char *Ptr) {
|
||||
// The offset in the stream right before invoking
|
||||
// CallStackTableGenerator.Emit.
|
||||
const uint64_t CallStackPayloadOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
// The offset in the stream right before invoking RecordTableGenerator.Emit.
|
||||
const uint64_t RecordPayloadOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
// The value returned from RecordTableGenerator.Emit.
|
||||
const uint64_t RecordTableOffset =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
|
||||
// Read the schema.
|
||||
auto SchemaOr = memprof::readMemProfSchema(Ptr);
|
||||
if (!SchemaOr)
|
||||
return SchemaOr.takeError();
|
||||
Schema = SchemaOr.get();
|
||||
|
||||
FrameBase = Ptr;
|
||||
CallStackBase = Start + CallStackPayloadOffset;
|
||||
|
||||
// Compute the number of elements in the radix tree array. Since we use this
|
||||
// to reserve enough bits in a BitVector, it's totally OK if we overestimate
|
||||
// this number a little bit because of padding just before the next section.
|
||||
RadixTreeSize = (RecordPayloadOffset - CallStackPayloadOffset) /
|
||||
sizeof(memprof::LinearFrameId);
|
||||
|
||||
// Now initialize the table reader with a pointer into data buffer.
|
||||
MemProfRecordTable.reset(MemProfRecordHashTable::Create(
|
||||
/*Buckets=*/Start + RecordTableOffset,
|
||||
/*Payload=*/Start + RecordPayloadOffset,
|
||||
/*Base=*/Start, memprof::RecordLookupTrait(memprof::Version3, Schema)));
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error IndexedMemProfReader::deserialize(const unsigned char *Start,
|
||||
uint64_t MemProfOffset) {
|
||||
const unsigned char *Ptr = Start + MemProfOffset;
|
||||
|
||||
// Read the MemProf version number.
|
||||
const uint64_t FirstWord =
|
||||
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
|
||||
|
||||
if (FirstWord == memprof::Version2 || FirstWord == memprof::Version3) {
|
||||
// Everything is good. We can proceed to deserialize the rest.
|
||||
Version = static_cast<memprof::IndexedVersion>(FirstWord);
|
||||
} else {
|
||||
return make_error<InstrProfError>(
|
||||
instrprof_error::unsupported_version,
|
||||
formatv("MemProf version {} not supported; "
|
||||
"requires version between {} and {}, inclusive",
|
||||
FirstWord, memprof::MinimumSupportedVersion,
|
||||
memprof::MaximumSupportedVersion));
|
||||
}
|
||||
|
||||
switch (Version) {
|
||||
case memprof::Version2:
|
||||
if (Error E = deserializeV2(Start, Ptr))
|
||||
return E;
|
||||
break;
|
||||
case memprof::Version3:
|
||||
if (Error E = deserializeV3(Start, Ptr))
|
||||
return E;
|
||||
break;
|
||||
}
|
||||
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
Error IndexedInstrProfReader::readHeader() {
|
||||
using namespace support;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user