[llvm] [nfc][InstrProf]Remove 'offsetOf' when parsing indexed profiles (PR #93346)
Mingming Liu via llvm-commits
llvm-commits at lists.llvm.org
Thu May 30 09:00:39 PDT 2024
https://github.com/minglotus-6 updated https://github.com/llvm/llvm-project/pull/93346
>From 61b98217b25f1c414615382d1f5c5e73f9214ab9 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Fri, 24 May 2024 11:00:08 -0700
Subject: [PATCH 01/10] [nfc][InstrProf]Simplify instrumentation profile reader
and writer code
Changes include:
1. In InstrProfReader.cpp, compute ProfileVersion once, rather than
repeatedly use macro `GET_VERSION(H.Version)`.
2. In InstrProfWriter.cpp, store back-patched header fields in a vector
and patch once.
3. In InstrProf.cpp, remove offsetOf and use a helper function
read_and_decrement.
llvm/Support/Endian.h has `readNext` method which increments the
buffer. For `Header::readFromBuffer`, switch statements allow
code sharing by fall-through, and it's not very straightforward to
use 'readNext'.
---
llvm/lib/ProfileData/InstrProf.cpp | 45 ++++++++---------
llvm/lib/ProfileData/InstrProfReader.cpp | 11 ++--
llvm/lib/ProfileData/InstrProfWriter.cpp | 64 +++++++-----------------
3 files changed, 45 insertions(+), 75 deletions(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index f9cd71b37002f..2eaffe84f10c7 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1627,13 +1627,6 @@ void OverlapStats::dump(raw_fd_ostream &OS) const {
}
namespace IndexedInstrProf {
-// A C++14 compatible version of the offsetof macro.
-template <typename T1, typename T2>
-inline size_t constexpr offsetOf(T1 T2::*Member) {
- constexpr T2 Object{};
- 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) {
@@ -1642,6 +1635,14 @@ static inline uint64_t read(const unsigned char *Buffer, size_t Offset) {
Offset);
}
+// Read a uint64_t from the specified `Buffer`, and points `Buffer` to the
+// address of previous uint64_t.
+static inline uint64_t read_and_decrement(const unsigned char *&Buffer) {
+ uint64_t Val = read(Buffer, 0);
+ Buffer -= sizeof(uint64_t);
+ return Val;
+}
+
Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
using namespace support;
static_assert(std::is_standard_layout_v<Header>,
@@ -1649,16 +1650,17 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
"of fields to read.");
Header H;
- H.Magic = read(Buffer, offsetOf(&Header::Magic));
+ H.Magic = read(Buffer, 0);
// Check the magic number.
if (H.Magic != IndexedInstrProf::Magic)
return make_error<InstrProfError>(instrprof_error::bad_magic);
// Read the version.
- H.Version = read(Buffer, offsetOf(&Header::Version));
+ H.Version = read(Buffer, 8);
if (GET_VERSION(H.Version) > IndexedInstrProf::ProfVersion::CurrentVersion)
return make_error<InstrProfError>(instrprof_error::unsupported_version);
+ const unsigned char *NextHeader = Buffer + H.size() - sizeof(uint64_t);
switch (GET_VERSION(H.Version)) {
// When a new field is added in the header add a case statement here to
// populate it.
@@ -1667,23 +1669,22 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
"Please update the reading code below if a new field has been added, "
"if not add a case statement to fall through to the latest version.");
case 12ull:
- H.VTableNamesOffset = read(Buffer, offsetOf(&Header::VTableNamesOffset));
+ H.VTableNamesOffset = read_and_decrement(NextHeader);
[[fallthrough]];
case 11ull:
[[fallthrough]];
case 10ull:
- H.TemporalProfTracesOffset =
- read(Buffer, offsetOf(&Header::TemporalProfTracesOffset));
+ H.TemporalProfTracesOffset = read_and_decrement(NextHeader);
[[fallthrough]];
case 9ull:
- H.BinaryIdOffset = read(Buffer, offsetOf(&Header::BinaryIdOffset));
+ H.BinaryIdOffset = read_and_decrement(NextHeader);
[[fallthrough]];
case 8ull:
- H.MemProfOffset = read(Buffer, offsetOf(&Header::MemProfOffset));
+ H.MemProfOffset = read_and_decrement(NextHeader);
[[fallthrough]];
default: // Version7 (when the backwards compatible header was introduced).
- H.HashType = read(Buffer, offsetOf(&Header::HashType));
- H.HashOffset = read(Buffer, offsetOf(&Header::HashOffset));
+ H.HashOffset = read_and_decrement(NextHeader);
+ H.HashType = read_and_decrement(NextHeader);
}
return H;
@@ -1699,19 +1700,17 @@ size_t Header::size() const {
"been added to the header, if not add a case statement to "
"fall through to the latest version.");
case 12ull:
- return offsetOf(&Header::VTableNamesOffset) +
- sizeof(Header::VTableNamesOffset);
+ return 72;
case 11ull:
[[fallthrough]];
case 10ull:
- return offsetOf(&Header::TemporalProfTracesOffset) +
- sizeof(Header::TemporalProfTracesOffset);
+ return 64;
case 9ull:
- return offsetOf(&Header::BinaryIdOffset) + sizeof(Header::BinaryIdOffset);
+ return 56;
case 8ull:
- return offsetOf(&Header::MemProfOffset) + sizeof(Header::MemProfOffset);
+ return 48;
default: // Version7 (when the backwards compatible header was introduced).
- return offsetOf(&Header::HashOffset) + sizeof(Header::HashOffset);
+ return 40;
}
}
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index 836206a4fd86e..af603285343f8 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -1325,17 +1325,17 @@ Error IndexedInstrProfReader::readHeader() {
auto IndexPtr = std::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
Start + Header->HashOffset, Cur, Start, HashType, Header->Version);
+ const uint64_t ProfileVersion = GET_VERSION(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->Version) >= 8 &&
- Header->Version & VARIANT_MASK_MEMPROF) {
+ if (ProfileVersion >= 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->Version) >= 9) {
+ if (ProfileVersion >= 9) {
const unsigned char *Ptr = Start + Header->BinaryIdOffset;
// Read binary ids size.
BinaryIdsSize =
@@ -1349,7 +1349,7 @@ Error IndexedInstrProfReader::readHeader() {
"corrupted binary ids");
}
- if (GET_VERSION(Header->Version) >= 12) {
+ if (ProfileVersion >= 12) {
const unsigned char *Ptr = Start + Header->VTableNamesOffset;
CompressedVTableNamesLen =
@@ -1362,8 +1362,7 @@ Error IndexedInstrProfReader::readHeader() {
return make_error<InstrProfError>(instrprof_error::truncated);
}
- if (GET_VERSION(Header->Version) >= 10 &&
- Header->Version & VARIANT_MASK_TEMPORAL_PROF) {
+ if (ProfileVersion >= 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
diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp
index b67a9700b680a..f72df98444007 100644
--- a/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -841,52 +841,24 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
}
InfoObj->CSSummaryBuilder = nullptr;
- const size_t MemProfOffset = BackPatchStartOffset + sizeof(uint64_t);
- const size_t BinaryIdOffset = MemProfOffset + sizeof(uint64_t);
- const size_t TemporalProfTracesOffset = BinaryIdOffset + sizeof(uint64_t);
- const size_t VTableNamesOffset = TemporalProfTracesOffset + sizeof(uint64_t);
- if (!WritePrevVersion) {
- // Now do the final patch:
- PatchItem PatchItems[] = {
- // Patch the Header.HashOffset field.
- {BackPatchStartOffset, &HashTableStart, 1},
- // Patch the Header.MemProfOffset (=0 for profiles without MemProf
- // data).
- {MemProfOffset, &MemProfSectionStart, 1},
- // Patch the Header.BinaryIdSectionOffset.
- {BinaryIdOffset, &BinaryIdSectionStart, 1},
- // Patch the Header.TemporalProfTracesOffset (=0 for profiles without
- // traces).
- {TemporalProfTracesOffset, &TemporalProfTracesSectionStart, 1},
- {VTableNamesOffset, &VTableNamesSectionStart, 1},
- // Patch the summary data.
- {SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
- (int)(SummarySize / sizeof(uint64_t))},
- {CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
- (int)CSSummarySize}};
-
- OS.patch(PatchItems);
- } else {
- // Now do the final patch:
- PatchItem PatchItems[] = {
- // Patch the Header.HashOffset field.
- {BackPatchStartOffset, &HashTableStart, 1},
- // Patch the Header.MemProfOffset (=0 for profiles without MemProf
- // data).
- {MemProfOffset, &MemProfSectionStart, 1},
- // Patch the Header.BinaryIdSectionOffset.
- {BinaryIdOffset, &BinaryIdSectionStart, 1},
- // Patch the Header.TemporalProfTracesOffset (=0 for profiles without
- // traces).
- {TemporalProfTracesOffset, &TemporalProfTracesSectionStart, 1},
- // Patch the summary data.
- {SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
- (int)(SummarySize / sizeof(uint64_t))},
- {CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
- (int)CSSummarySize}};
-
- OS.patch(PatchItems);
- }
+ SmallVector<uint64_t, 8> HeaderOffsets = {HashTableStart, MemProfSectionStart,
+ BinaryIdSectionStart,
+ TemporalProfTracesSectionStart};
+
+ if (!WritePrevVersion)
+ HeaderOffsets.push_back(VTableNamesSectionStart);
+
+ // Now do the final patch.
+ PatchItem PatchItems[] = {
+ // Patch the Header fields
+ {BackPatchStartOffset, HeaderOffsets.data(), HeaderOffsets.size()},
+ // Patch the summary data.
+ {SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
+ (int)(SummarySize / sizeof(uint64_t))},
+ {CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
+ (int)CSSummarySize}};
+
+ OS.patch(PatchItems);
for (const auto &I : FunctionData)
for (const auto &F : I.getValue())
>From bb60ded148dcacf55f313fb3a28a2293d0a67381 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Fri, 24 May 2024 13:53:04 -0700
Subject: [PATCH 02/10] cast size_t to int to fix compile error in
https://buildkite.com/llvm-project/github-pull-requests/builds/67098#018fac5e-811d-46e4-8ba4-62c8b57f28e3
---
llvm/lib/ProfileData/InstrProfWriter.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp
index f72df98444007..93eb0043bf32e 100644
--- a/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -851,7 +851,7 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
// Now do the final patch.
PatchItem PatchItems[] = {
// Patch the Header fields
- {BackPatchStartOffset, HeaderOffsets.data(), HeaderOffsets.size()},
+ {BackPatchStartOffset, HeaderOffsets.data(), (int)HeaderOffsets.size()},
// Patch the summary data.
{SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
(int)(SummarySize / sizeof(uint64_t))},
>From 3852e32dc04094d1481ba42f875a26bbd5efaa71 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Tue, 28 May 2024 15:12:54 -0700
Subject: [PATCH 03/10] Read the buffer in the forward direction and remove
'offset_of'
---
llvm/lib/ProfileData/InstrProf.cpp | 45 +++++++++++++++---------------
1 file changed, 23 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 2eaffe84f10c7..f9cd71b37002f 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1627,6 +1627,13 @@ void OverlapStats::dump(raw_fd_ostream &OS) const {
}
namespace IndexedInstrProf {
+// A C++14 compatible version of the offsetof macro.
+template <typename T1, typename T2>
+inline size_t constexpr offsetOf(T1 T2::*Member) {
+ constexpr T2 Object{};
+ 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) {
@@ -1635,14 +1642,6 @@ static inline uint64_t read(const unsigned char *Buffer, size_t Offset) {
Offset);
}
-// Read a uint64_t from the specified `Buffer`, and points `Buffer` to the
-// address of previous uint64_t.
-static inline uint64_t read_and_decrement(const unsigned char *&Buffer) {
- uint64_t Val = read(Buffer, 0);
- Buffer -= sizeof(uint64_t);
- return Val;
-}
-
Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
using namespace support;
static_assert(std::is_standard_layout_v<Header>,
@@ -1650,17 +1649,16 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
"of fields to read.");
Header H;
- H.Magic = read(Buffer, 0);
+ H.Magic = read(Buffer, offsetOf(&Header::Magic));
// Check the magic number.
if (H.Magic != IndexedInstrProf::Magic)
return make_error<InstrProfError>(instrprof_error::bad_magic);
// Read the version.
- H.Version = read(Buffer, 8);
+ H.Version = read(Buffer, offsetOf(&Header::Version));
if (GET_VERSION(H.Version) > IndexedInstrProf::ProfVersion::CurrentVersion)
return make_error<InstrProfError>(instrprof_error::unsupported_version);
- const unsigned char *NextHeader = Buffer + H.size() - sizeof(uint64_t);
switch (GET_VERSION(H.Version)) {
// When a new field is added in the header add a case statement here to
// populate it.
@@ -1669,22 +1667,23 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
"Please update the reading code below if a new field has been added, "
"if not add a case statement to fall through to the latest version.");
case 12ull:
- H.VTableNamesOffset = read_and_decrement(NextHeader);
+ H.VTableNamesOffset = read(Buffer, offsetOf(&Header::VTableNamesOffset));
[[fallthrough]];
case 11ull:
[[fallthrough]];
case 10ull:
- H.TemporalProfTracesOffset = read_and_decrement(NextHeader);
+ H.TemporalProfTracesOffset =
+ read(Buffer, offsetOf(&Header::TemporalProfTracesOffset));
[[fallthrough]];
case 9ull:
- H.BinaryIdOffset = read_and_decrement(NextHeader);
+ H.BinaryIdOffset = read(Buffer, offsetOf(&Header::BinaryIdOffset));
[[fallthrough]];
case 8ull:
- H.MemProfOffset = read_and_decrement(NextHeader);
+ H.MemProfOffset = read(Buffer, offsetOf(&Header::MemProfOffset));
[[fallthrough]];
default: // Version7 (when the backwards compatible header was introduced).
- H.HashOffset = read_and_decrement(NextHeader);
- H.HashType = read_and_decrement(NextHeader);
+ H.HashType = read(Buffer, offsetOf(&Header::HashType));
+ H.HashOffset = read(Buffer, offsetOf(&Header::HashOffset));
}
return H;
@@ -1700,17 +1699,19 @@ size_t Header::size() const {
"been added to the header, if not add a case statement to "
"fall through to the latest version.");
case 12ull:
- return 72;
+ return offsetOf(&Header::VTableNamesOffset) +
+ sizeof(Header::VTableNamesOffset);
case 11ull:
[[fallthrough]];
case 10ull:
- return 64;
+ return offsetOf(&Header::TemporalProfTracesOffset) +
+ sizeof(Header::TemporalProfTracesOffset);
case 9ull:
- return 56;
+ return offsetOf(&Header::BinaryIdOffset) + sizeof(Header::BinaryIdOffset);
case 8ull:
- return 48;
+ return offsetOf(&Header::MemProfOffset) + sizeof(Header::MemProfOffset);
default: // Version7 (when the backwards compatible header was introduced).
- return 40;
+ return offsetOf(&Header::HashOffset) + sizeof(Header::HashOffset);
}
}
>From 987c105207a4186da9eed7bb2f32738ed7080cf7 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Tue, 28 May 2024 15:22:52 -0700
Subject: [PATCH 04/10] Correct the push in previous commit
---
llvm/lib/ProfileData/InstrProf.cpp | 74 +++++++++---------------
llvm/lib/ProfileData/InstrProfReader.cpp | 11 ++--
llvm/lib/ProfileData/InstrProfWriter.cpp | 64 ++++++++++++++------
3 files changed, 79 insertions(+), 70 deletions(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index f9cd71b37002f..ac8bb44b4c8ef 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1627,19 +1627,12 @@ void OverlapStats::dump(raw_fd_ostream &OS) const {
}
namespace IndexedInstrProf {
-// A C++14 compatible version of the offsetof macro.
-template <typename T1, typename T2>
-inline size_t constexpr offsetOf(T1 T2::*Member) {
- constexpr T2 Object{};
- 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) {
+// native endianness if necessary. Increment the buffer past the read value.
+static inline uint64_t readNext(const unsigned char *&Buffer) {
using namespace ::support;
- return endian::read<uint64_t, llvm::endianness::little, unaligned>(Buffer +
- Offset);
+ return endian::readNext<uint64_t, llvm::endianness::little, unaligned>(
+ Buffer);
}
Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
@@ -1649,43 +1642,32 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
"of fields to read.");
Header H;
- H.Magic = read(Buffer, offsetOf(&Header::Magic));
+ H.Magic = readNext(Buffer);
// Check the magic number.
if (H.Magic != IndexedInstrProf::Magic)
return make_error<InstrProfError>(instrprof_error::bad_magic);
// Read the version.
- H.Version = read(Buffer, offsetOf(&Header::Version));
+ H.Version = readNext(Buffer);
if (GET_VERSION(H.Version) > IndexedInstrProf::ProfVersion::CurrentVersion)
return make_error<InstrProfError>(instrprof_error::unsupported_version);
- switch (GET_VERSION(H.Version)) {
- // When a new field is added in the header add a case statement here to
- // populate it.
- static_assert(
- IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
- "Please update the reading code below if a new field has been added, "
- "if not add a case statement to fall through to the latest version.");
- case 12ull:
- H.VTableNamesOffset = read(Buffer, offsetOf(&Header::VTableNamesOffset));
- [[fallthrough]];
- case 11ull:
- [[fallthrough]];
- case 10ull:
- H.TemporalProfTracesOffset =
- read(Buffer, offsetOf(&Header::TemporalProfTracesOffset));
- [[fallthrough]];
- case 9ull:
- H.BinaryIdOffset = read(Buffer, offsetOf(&Header::BinaryIdOffset));
- [[fallthrough]];
- case 8ull:
- H.MemProfOffset = read(Buffer, offsetOf(&Header::MemProfOffset));
- [[fallthrough]];
- default: // Version7 (when the backwards compatible header was introduced).
- H.HashType = read(Buffer, offsetOf(&Header::HashType));
- H.HashOffset = read(Buffer, offsetOf(&Header::HashOffset));
- }
-
+ static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
+ "Please update the reading as needed when a new field is added "
+ "or when indexed profile version gets bumped.");
+
+ Buffer += sizeof(uint64_t); // Skip Header.Unused field.
+ H.HashType = readNext(Buffer);
+ H.HashOffset = readNext(Buffer);
+ const uint64_t ProfileVersion = GET_VERSION(H.Version);
+ if (ProfileVersion >= 8)
+ H.MemProfOffset = readNext(Buffer);
+ if (ProfileVersion >= 9)
+ H.BinaryIdOffset = readNext(Buffer);
+ if (ProfileVersion >= 10)
+ H.TemporalProfTracesOffset = readNext(Buffer);
+ if (ProfileVersion >= 12)
+ H.VTableNamesOffset = readNext(Buffer);
return H;
}
@@ -1699,19 +1681,17 @@ size_t Header::size() const {
"been added to the header, if not add a case statement to "
"fall through to the latest version.");
case 12ull:
- return offsetOf(&Header::VTableNamesOffset) +
- sizeof(Header::VTableNamesOffset);
+ return 72;
case 11ull:
[[fallthrough]];
case 10ull:
- return offsetOf(&Header::TemporalProfTracesOffset) +
- sizeof(Header::TemporalProfTracesOffset);
+ return 64;
case 9ull:
- return offsetOf(&Header::BinaryIdOffset) + sizeof(Header::BinaryIdOffset);
+ return 56;
case 8ull:
- return offsetOf(&Header::MemProfOffset) + sizeof(Header::MemProfOffset);
+ return 48;
default: // Version7 (when the backwards compatible header was introduced).
- return offsetOf(&Header::HashOffset) + sizeof(Header::HashOffset);
+ return 40;
}
}
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index af603285343f8..836206a4fd86e 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -1325,17 +1325,17 @@ Error IndexedInstrProfReader::readHeader() {
auto IndexPtr = std::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
Start + Header->HashOffset, Cur, Start, HashType, Header->Version);
- const uint64_t ProfileVersion = GET_VERSION(Header->Version);
// The MemProfOffset field in the header is only valid when the format
// version is higher than 8 (when it was introduced).
- if (ProfileVersion >= 8 && Header->Version & VARIANT_MASK_MEMPROF) {
+ 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 (ProfileVersion >= 9) {
+ if (GET_VERSION(Header->Version) >= 9) {
const unsigned char *Ptr = Start + Header->BinaryIdOffset;
// Read binary ids size.
BinaryIdsSize =
@@ -1349,7 +1349,7 @@ Error IndexedInstrProfReader::readHeader() {
"corrupted binary ids");
}
- if (ProfileVersion >= 12) {
+ if (GET_VERSION(Header->Version) >= 12) {
const unsigned char *Ptr = Start + Header->VTableNamesOffset;
CompressedVTableNamesLen =
@@ -1362,7 +1362,8 @@ Error IndexedInstrProfReader::readHeader() {
return make_error<InstrProfError>(instrprof_error::truncated);
}
- if (ProfileVersion >= 10 && Header->Version & VARIANT_MASK_TEMPORAL_PROF) {
+ 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
diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp
index 93eb0043bf32e..b67a9700b680a 100644
--- a/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -841,24 +841,52 @@ Error InstrProfWriter::writeImpl(ProfOStream &OS) {
}
InfoObj->CSSummaryBuilder = nullptr;
- SmallVector<uint64_t, 8> HeaderOffsets = {HashTableStart, MemProfSectionStart,
- BinaryIdSectionStart,
- TemporalProfTracesSectionStart};
-
- if (!WritePrevVersion)
- HeaderOffsets.push_back(VTableNamesSectionStart);
-
- // Now do the final patch.
- PatchItem PatchItems[] = {
- // Patch the Header fields
- {BackPatchStartOffset, HeaderOffsets.data(), (int)HeaderOffsets.size()},
- // Patch the summary data.
- {SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
- (int)(SummarySize / sizeof(uint64_t))},
- {CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
- (int)CSSummarySize}};
-
- OS.patch(PatchItems);
+ const size_t MemProfOffset = BackPatchStartOffset + sizeof(uint64_t);
+ const size_t BinaryIdOffset = MemProfOffset + sizeof(uint64_t);
+ const size_t TemporalProfTracesOffset = BinaryIdOffset + sizeof(uint64_t);
+ const size_t VTableNamesOffset = TemporalProfTracesOffset + sizeof(uint64_t);
+ if (!WritePrevVersion) {
+ // Now do the final patch:
+ PatchItem PatchItems[] = {
+ // Patch the Header.HashOffset field.
+ {BackPatchStartOffset, &HashTableStart, 1},
+ // Patch the Header.MemProfOffset (=0 for profiles without MemProf
+ // data).
+ {MemProfOffset, &MemProfSectionStart, 1},
+ // Patch the Header.BinaryIdSectionOffset.
+ {BinaryIdOffset, &BinaryIdSectionStart, 1},
+ // Patch the Header.TemporalProfTracesOffset (=0 for profiles without
+ // traces).
+ {TemporalProfTracesOffset, &TemporalProfTracesSectionStart, 1},
+ {VTableNamesOffset, &VTableNamesSectionStart, 1},
+ // Patch the summary data.
+ {SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
+ (int)(SummarySize / sizeof(uint64_t))},
+ {CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
+ (int)CSSummarySize}};
+
+ OS.patch(PatchItems);
+ } else {
+ // Now do the final patch:
+ PatchItem PatchItems[] = {
+ // Patch the Header.HashOffset field.
+ {BackPatchStartOffset, &HashTableStart, 1},
+ // Patch the Header.MemProfOffset (=0 for profiles without MemProf
+ // data).
+ {MemProfOffset, &MemProfSectionStart, 1},
+ // Patch the Header.BinaryIdSectionOffset.
+ {BinaryIdOffset, &BinaryIdSectionStart, 1},
+ // Patch the Header.TemporalProfTracesOffset (=0 for profiles without
+ // traces).
+ {TemporalProfTracesOffset, &TemporalProfTracesSectionStart, 1},
+ // Patch the summary data.
+ {SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
+ (int)(SummarySize / sizeof(uint64_t))},
+ {CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
+ (int)CSSummarySize}};
+
+ OS.patch(PatchItems);
+ }
for (const auto &I : FunctionData)
for (const auto &F : I.getValue())
>From 737a7a9f54669143e5598533e72b16d598f632aa Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Wed, 29 May 2024 11:04:01 -0700
Subject: [PATCH 05/10] call Header.getIndexedProfileVersion()
---
llvm/lib/ProfileData/InstrProf.cpp | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index bcb892f3b0f8a..f074f7703be2f 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1659,14 +1659,13 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
Buffer += sizeof(uint64_t); // Skip Header.Unused field.
H.HashType = readNext(Buffer);
H.HashOffset = readNext(Buffer);
- const uint64_t ProfileVersion = GET_VERSION(H.Version);
- if (ProfileVersion >= 8)
+ if (H.getIndexedProfileVersion() >= 8)
H.MemProfOffset = readNext(Buffer);
- if (ProfileVersion >= 9)
+ if (H.getIndexedProfileVersion() >= 9)
H.BinaryIdOffset = readNext(Buffer);
- if (ProfileVersion >= 10)
+ if (H.getIndexedProfileVersion() >= 10)
H.TemporalProfTracesOffset = readNext(Buffer);
- if (ProfileVersion >= 12)
+ if (H.getIndexedProfileVersion() >= 12)
H.VTableNamesOffset = readNext(Buffer);
return H;
}
>From f40dc7b69ba51b5f91b11c0370e32bd5c9d27975 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Wed, 29 May 2024 12:29:37 -0700
Subject: [PATCH 06/10] clang-format
---
llvm/lib/ProfileData/InstrProf.cpp | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index f074f7703be2f..5d5f7e3dbe677 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1649,7 +1649,8 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
// Read the version.
H.Version = readNext(Buffer);
- if (H.getIndexedProfileVersion() > IndexedInstrProf::ProfVersion::CurrentVersion)
+ if (H.getIndexedProfileVersion() >
+ IndexedInstrProf::ProfVersion::CurrentVersion)
return make_error<InstrProfError>(instrprof_error::unsupported_version);
static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
>From 1ada31d283a1ee851c7bc73b00ad563d55d09d12 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Wed, 29 May 2024 13:22:58 -0700
Subject: [PATCH 07/10] resolve review comments
---
llvm/lib/ProfileData/InstrProf.cpp | 50 +++++++++++++++---------------
1 file changed, 25 insertions(+), 25 deletions(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 5d5f7e3dbe677..8fc5d8e2a0bba 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1627,28 +1627,21 @@ void OverlapStats::dump(raw_fd_ostream &OS) const {
}
namespace IndexedInstrProf {
-// Read a uint64_t from the specified buffer offset, and swap the bytes in
-// native endianness if necessary. Increment the buffer past the read value.
-static inline uint64_t readNext(const unsigned char *&Buffer) {
- using namespace ::support;
- return endian::readNext<uint64_t, llvm::endianness::little, unaligned>(
- Buffer);
-}
-
Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
using namespace support;
static_assert(std::is_standard_layout_v<Header>,
- "The header should be standard layout type since we use offset "
- "of fields to read.");
+ "Use standard layout for Header for simplicity");
Header H;
- H.Magic = readNext(Buffer);
+ H.Magic =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
// Check the magic number.
if (H.Magic != IndexedInstrProf::Magic)
return make_error<InstrProfError>(instrprof_error::bad_magic);
// Read the version.
- H.Version = readNext(Buffer);
+ H.Version =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
if (H.getIndexedProfileVersion() >
IndexedInstrProf::ProfVersion::CurrentVersion)
return make_error<InstrProfError>(instrprof_error::unsupported_version);
@@ -1658,16 +1651,22 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
"or when indexed profile version gets bumped.");
Buffer += sizeof(uint64_t); // Skip Header.Unused field.
- H.HashType = readNext(Buffer);
- H.HashOffset = readNext(Buffer);
+ H.HashType =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
+ H.HashOffset =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
if (H.getIndexedProfileVersion() >= 8)
- H.MemProfOffset = readNext(Buffer);
+ H.MemProfOffset =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
if (H.getIndexedProfileVersion() >= 9)
- H.BinaryIdOffset = readNext(Buffer);
+ H.BinaryIdOffset =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
if (H.getIndexedProfileVersion() >= 10)
- H.TemporalProfTracesOffset = readNext(Buffer);
+ H.TemporalProfTracesOffset =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
if (H.getIndexedProfileVersion() >= 12)
- H.VTableNamesOffset = readNext(Buffer);
+ H.VTableNamesOffset =
+ endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
return H;
}
@@ -1677,13 +1676,14 @@ uint64_t Header::getIndexedProfileVersion() const {
size_t Header::size() const {
switch (getIndexedProfileVersion()) {
- // 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.
- static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
- "Please update the size computation below if a new field has "
- "been added to the header, if not add a case statement to "
- "fall through to the latest version.");
+ // To retain backward compatibility, new fields must be appended to the end
+ // of the header, and byte offset of existing fields shouldn't change when
+ // indexed profile version gets incremented.
+ static_assert(
+ IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
+ "Please update the size computation below if a new field has "
+ "been added to the header; for a version bump without new "
+ "fields, add a case statement to fall through to the latest version.");
case 12ull:
return 72;
case 11ull:
>From 33ee4eba0b59bdf341ad85ef8f6a65a4b5264086 Mon Sep 17 00:00:00 2001
From: Mingming Liu <minglotus6 at gmail.com>
Date: Wed, 29 May 2024 15:47:13 -0700
Subject: [PATCH 08/10] apply suggestions
Co-authored-by: Kazu Hirata <kazu at google.com>
---
llvm/lib/ProfileData/InstrProf.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 8fc5d8e2a0bba..770f0842fe9fe 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1647,7 +1647,7 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
return make_error<InstrProfError>(instrprof_error::unsupported_version);
static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
- "Please update the reading as needed when a new field is added "
+ "Please update the reader as needed when a new field is added "
"or when indexed profile version gets bumped.");
Buffer += sizeof(uint64_t); // Skip Header.Unused field.
>From 1f440a15061c0f1129fdb5648e3cff6a2331e693 Mon Sep 17 00:00:00 2001
From: Mingming Liu <minglotus6 at gmail.com>
Date: Wed, 29 May 2024 15:51:01 -0700
Subject: [PATCH 09/10] apply suggestion
Co-authored-by: Kazu Hirata <kazu at google.com>
---
llvm/lib/ProfileData/InstrProf.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index 770f0842fe9fe..f2cb076048a62 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1634,7 +1634,7 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
Header H;
H.Magic =
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
+ endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
// Check the magic number.
if (H.Magic != IndexedInstrProf::Magic)
return make_error<InstrProfError>(instrprof_error::bad_magic);
>From 344bd9634440727e6ddec0b8574302471ee8d880 Mon Sep 17 00:00:00 2001
From: mingmingl <mingmingl at google.com>
Date: Wed, 29 May 2024 15:52:55 -0700
Subject: [PATCH 10/10] resolve feedback
---
llvm/lib/ProfileData/InstrProf.cpp | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp
index f2cb076048a62..026006b363e7e 100644
--- a/llvm/lib/ProfileData/InstrProf.cpp
+++ b/llvm/lib/ProfileData/InstrProf.cpp
@@ -1640,8 +1640,7 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
return make_error<InstrProfError>(instrprof_error::bad_magic);
// Read the version.
- H.Version =
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
+ H.Version = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
if (H.getIndexedProfileVersion() >
IndexedInstrProf::ProfVersion::CurrentVersion)
return make_error<InstrProfError>(instrprof_error::unsupported_version);
@@ -1651,22 +1650,21 @@ Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
"or when indexed profile version gets bumped.");
Buffer += sizeof(uint64_t); // Skip Header.Unused field.
- H.HashType =
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
- H.HashOffset =
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
+ H.HashType = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
+ H.HashOffset = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
if (H.getIndexedProfileVersion() >= 8)
H.MemProfOffset =
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
+ endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
if (H.getIndexedProfileVersion() >= 9)
H.BinaryIdOffset =
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
+ endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
+ // Version 11 is handled by this condition.
if (H.getIndexedProfileVersion() >= 10)
H.TemporalProfTracesOffset =
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
+ endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
if (H.getIndexedProfileVersion() >= 12)
H.VTableNamesOffset =
- endian::readNext<uint64_t, llvm::endianness::little, unaligned>(Buffer);
+ endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
return H;
}
More information about the llvm-commits
mailing list