[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:
Kazu Hirata 2025-04-23 19:24:17 -07:00 committed by GitHub
parent 30fec128e8
commit ea0dbee808
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 124 additions and 123 deletions

View File

@ -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

View File

@ -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;