[llvm] [nfc][InstrProfReader]Store header fields in native endianness (PR #92947)
Mingming Liu via llvm-commits
llvm-commits at lists.llvm.org
Tue May 21 20:38:03 PDT 2024
https://github.com/minglotus-6 updated https://github.com/llvm/llvm-project/pull/92947
>From cea4e3ea9364350c5839e5de83a70614b5521c2f Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Tue, 21 May 2024 11:02:10 -0700
Subject: [PATCH 1/2] [nfc][InstrProfReader]Store header fields in native
endianness - Use Header.Version everywhere and remove Header::formatVersion
---
llvm/include/llvm/ProfileData/InstrProf.h | 7 +---
llvm/lib/ProfileData/InstrProf.cpp | 22 ++++------
llvm/lib/ProfileData/InstrProfReader.cpp | 50 ++++++++---------------
3 files changed, 28 insertions(+), 51 deletions(-)
diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h
index 88c7fe425b5a5..a57f9e1b7b4a2 100644
--- a/llvm/include/llvm/ProfileData/InstrProf.h
+++ b/llvm/include/llvm/ProfileData/InstrProf.h
@@ -1203,16 +1203,13 @@ struct Header {
// computation is correct. The methods below need to be updated to ensure that
// the new field is read correctly.
- // Reads a header struct from the buffer.
+ // Reads a header struct from the buffer. Header fields are in machine native
+ // endianness.
static Expected<Header> readFromBuffer(const unsigned char *Buffer);
// Returns the size of the header in bytes for all valid fields based on the
// version. I.e a older version header will return a smaller size.
size_t size() const;
-
- // Returns the format version in little endian. The header retains the version
- // in native endian of the compiler runtime.
- uint64_t formatVersion() const;
};
// Profile summary data recorded in the profile data file in indexed
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 806d01de1ada5..9a2e2273fdc40 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1620,13 +1620,12 @@ inline size_t constexpr offsetOf(T1 T2::*Member) {
return size_t(&(Object.*Member)) - size_t(&Object);
}
+// Read a uint64_t from the specified buffer offset, and swap the bytes in
+// native endianness if necessary.
static inline uint64_t read(const unsigned char *Buffer, size_t Offset) {
- return *reinterpret_cast<const uint64_t *>(Buffer + Offset);
-}
-
-uint64_t Header::formatVersion() const {
- using namespace support;
- return endian::byte_swap<uint64_t, llvm::endianness::little>(Version);
+ using namespace ::support;
+ uint64_t Data = *reinterpret_cast<const uint64_t *>(Buffer + Offset);
+ return endian::byte_swap<uint64_t, llvm::endianness::little>(Data);
}
Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
@@ -1638,18 +1637,15 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
H.Magic = read(Buffer, offsetOf(&Header::Magic));
// Check the magic number.
- uint64_t Magic =
- endian::byte_swap<uint64_t, llvm::endianness::little>(H.Magic);
- if (Magic != IndexedInstrProf::Magic)
+ if (H.Magic != IndexedInstrProf::Magic)
return make_error<InstrProfError>(instrprof_error::bad_magic);
// Read the version.
H.Version = read(Buffer, offsetOf(&Header::Version));
- if (GET_VERSION(H.formatVersion()) >
- IndexedInstrProf::ProfVersion::CurrentVersion)
+ if (GET_VERSION(H.Version) > IndexedInstrProf::ProfVersion::CurrentVersion)
return make_error<InstrProfError>(instrprof_error::unsupported_version);
- switch (GET_VERSION(H.formatVersion())) {
+ switch (GET_VERSION(H.Version)) {
// When a new field is added in the header add a case statement here to
// populate it.
static_assert(
@@ -1680,7 +1676,7 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
}
size_t Header::size() const {
- switch (GET_VERSION(formatVersion())) {
+ switch (GET_VERSION(Version)) {
// When a new field is added to the header add a case statement here to
// compute the size as offset of the new field + size of the new field. This
// relies on the field being added to the end of the list.
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index ba21e01abfbac..2a87a386ea67f 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -1311,43 +1311,33 @@ Error IndexedInstrProfReader::readHeader() {
const IndexedInstrProf::Header *Header = &HeaderOr.get();
Cur += Header->size();
- Cur = readSummary((IndexedInstrProf::ProfVersion)Header->formatVersion(), Cur,
+ Cur = readSummary((IndexedInstrProf::ProfVersion)Header->Version, Cur,
/* UseCS */ false);
- if (Header->formatVersion() & VARIANT_MASK_CSIR_PROF)
- Cur =
- readSummary((IndexedInstrProf::ProfVersion)Header->formatVersion(), Cur,
- /* UseCS */ true);
+ if (Header->Version & VARIANT_MASK_CSIR_PROF)
+ Cur = readSummary((IndexedInstrProf::ProfVersion)Header->Version, Cur,
+ /* UseCS */ true);
// Read the hash type and start offset.
- IndexedInstrProf::HashT HashType = static_cast<IndexedInstrProf::HashT>(
- endian::byte_swap<uint64_t, llvm::endianness::little>(Header->HashType));
+ IndexedInstrProf::HashT HashType =
+ static_cast<IndexedInstrProf::HashT>(Header->HashType);
if (HashType > IndexedInstrProf::HashT::Last)
return error(instrprof_error::unsupported_hash_type);
- uint64_t HashOffset =
- endian::byte_swap<uint64_t, llvm::endianness::little>(Header->HashOffset);
-
// The hash table with profile counts comes next.
auto IndexPtr = std::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
- Start + HashOffset, Cur, Start, HashType, Header->formatVersion());
+ Start + Header->HashOffset, Cur, Start, HashType, Header->Version);
// The MemProfOffset field in the header is only valid when the format
// version is higher than 8 (when it was introduced).
- if (GET_VERSION(Header->formatVersion()) >= 8 &&
- Header->formatVersion() & VARIANT_MASK_MEMPROF) {
- uint64_t MemProfOffset =
- endian::byte_swap<uint64_t, llvm::endianness::little>(
- Header->MemProfOffset);
- if (Error E = MemProfReader.deserialize(Start, MemProfOffset))
+ if (GET_VERSION(Header->Version) >= 8 &&
+ Header->Version & VARIANT_MASK_MEMPROF) {
+ if (Error E = MemProfReader.deserialize(Start, Header->MemProfOffset))
return E;
}
// BinaryIdOffset field in the header is only valid when the format version
// is higher than 9 (when it was introduced).
- if (GET_VERSION(Header->formatVersion()) >= 9) {
- uint64_t BinaryIdOffset =
- endian::byte_swap<uint64_t, llvm::endianness::little>(
- Header->BinaryIdOffset);
- const unsigned char *Ptr = Start + BinaryIdOffset;
+ if (GET_VERSION(Header->Version) >= 9) {
+ const unsigned char *Ptr = Start + Header->BinaryIdOffset;
// Read binary ids size.
BinaryIdsSize =
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
@@ -1360,11 +1350,8 @@ Error IndexedInstrProfReader::readHeader() {
"corrupted binary ids");
}
- if (GET_VERSION(Header->formatVersion()) >= 12) {
- uint64_t VTableNamesOffset =
- endian::byte_swap<uint64_t, llvm::endianness::little>(
- Header->VTableNamesOffset);
- const unsigned char *Ptr = Start + VTableNamesOffset;
+ if (GET_VERSION(Header->Version) >= 12) {
+ const unsigned char *Ptr = Start + Header->VTableNamesOffset;
CompressedVTableNamesLen =
support::endian::readNext<uint64_t, llvm::endianness::little>(Ptr);
@@ -1376,12 +1363,9 @@ Error IndexedInstrProfReader::readHeader() {
return make_error<InstrProfError>(instrprof_error::truncated);
}
- if (GET_VERSION(Header->formatVersion()) >= 10 &&
- Header->formatVersion() & VARIANT_MASK_TEMPORAL_PROF) {
- uint64_t TemporalProfTracesOffset =
- endian::byte_swap<uint64_t, llvm::endianness::little>(
- Header->TemporalProfTracesOffset);
- const unsigned char *Ptr = Start + TemporalProfTracesOffset;
+ if (GET_VERSION(Header->Version) >= 10 &&
+ Header->Version & VARIANT_MASK_TEMPORAL_PROF) {
+ const unsigned char *Ptr = Start + Header->TemporalProfTracesOffset;
const auto *PtrEnd = (const unsigned char *)DataBuffer->getBufferEnd();
// Expect at least two 64 bit fields: NumTraces, and TraceStreamSize
if (Ptr + 2 * sizeof(uint64_t) > PtrEnd)
>From 89e808c00ab4982ed6bac8681b55499b715f8d24 Mon Sep 17 00:00:00 2001
From: Mingming Liu <minglotus6 at gmail.com>
Date: Tue, 21 May 2024 20:37:56 -0700
Subject: [PATCH 2/2] use unaligned endian read
Co-authored-by: Kazu Hirata <kazu at google.com>
---
llvm/lib/ProfileData/InstrProf.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 9a2e2273fdc40..d19ce075add2a 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1624,8 +1624,7 @@ inline size_t constexpr offsetOf(T1 T2::*Member) {
// native endianness if necessary.
static inline uint64_t read(const unsigned char *Buffer, size_t Offset) {
using namespace ::support;
- uint64_t Data = *reinterpret_cast<const uint64_t *>(Buffer + Offset);
- return endian::byte_swap<uint64_t, llvm::endianness::little>(Data);
+ return endian::read<uint64_t, llvm::endianness::little, unaligned>(Buffer + Offset);
}
Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
More information about the llvm-commits
mailing list