@@ -1627,66 +1627,43 @@ void OverlapStats::dump(raw_fd_ostream &OS) const {
1627
1627
}
1628
1628
1629
1629
namespace IndexedInstrProf {
1630
- // A C++14 compatible version of the offsetof macro.
1631
- template <typename T1, typename T2>
1632
- inline size_t constexpr offsetOf (T1 T2::*Member) {
1633
- constexpr T2 Object{};
1634
- return size_t (&(Object.*Member)) - size_t (&Object);
1635
- }
1636
-
1637
- // Read a uint64_t from the specified buffer offset, and swap the bytes in
1638
- // native endianness if necessary.
1639
- static inline uint64_t read (const unsigned char *Buffer, size_t Offset) {
1640
- using namespace ::support;
1641
- return endian::read<uint64_t , llvm::endianness::little, unaligned>(Buffer +
1642
- Offset);
1643
- }
1644
-
1645
1630
Expected<Header> Header::readFromBuffer (const unsigned char *Buffer) {
1646
1631
using namespace support ;
1647
1632
static_assert (std::is_standard_layout_v<Header>,
1648
- " The header should be standard layout type since we use offset "
1649
- " of fields to read." );
1633
+ " Use standard layout for Header for simplicity" );
1650
1634
Header H;
1651
1635
1652
- H.Magic = read (Buffer, offsetOf (&Header::Magic) );
1636
+ H.Magic = endian::readNext< uint64_t , llvm::endianness::little>(Buffer );
1653
1637
// Check the magic number.
1654
1638
if (H.Magic != IndexedInstrProf::Magic)
1655
1639
return make_error<InstrProfError>(instrprof_error::bad_magic);
1656
1640
1657
1641
// Read the version.
1658
- H.Version = read (Buffer, offsetOf (&Header::Version) );
1642
+ H.Version = endian::readNext< uint64_t , llvm::endianness::little>(Buffer );
1659
1643
if (H.getIndexedProfileVersion () >
1660
1644
IndexedInstrProf::ProfVersion::CurrentVersion)
1661
1645
return make_error<InstrProfError>(instrprof_error::unsupported_version);
1662
1646
1663
- switch (H.getIndexedProfileVersion ()) {
1664
- // When a new field is added in the header add a case statement here to
1665
- // populate it.
1666
- static_assert (
1667
- IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
1668
- " Please update the reading code below if a new field has been added, "
1669
- " if not add a case statement to fall through to the latest version." );
1670
- case 12ull :
1671
- H.VTableNamesOffset = read (Buffer, offsetOf (&Header::VTableNamesOffset));
1672
- [[fallthrough]];
1673
- case 11ull :
1674
- [[fallthrough]];
1675
- case 10ull :
1647
+ static_assert (IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
1648
+ " Please update the reader as needed when a new field is added "
1649
+ " or when indexed profile version gets bumped." );
1650
+
1651
+ Buffer += sizeof (uint64_t ); // Skip Header.Unused field.
1652
+ H.HashType = endian::readNext<uint64_t , llvm::endianness::little>(Buffer);
1653
+ H.HashOffset = endian::readNext<uint64_t , llvm::endianness::little>(Buffer);
1654
+ if (H.getIndexedProfileVersion () >= 8 )
1655
+ H.MemProfOffset =
1656
+ endian::readNext<uint64_t , llvm::endianness::little>(Buffer);
1657
+ if (H.getIndexedProfileVersion () >= 9 )
1658
+ H.BinaryIdOffset =
1659
+ endian::readNext<uint64_t , llvm::endianness::little>(Buffer);
1660
+ // Version 11 is handled by this condition.
1661
+ if (H.getIndexedProfileVersion () >= 10 )
1676
1662
H.TemporalProfTracesOffset =
1677
- read (Buffer, offsetOf (&Header::TemporalProfTracesOffset));
1678
- [[fallthrough]];
1679
- case 9ull :
1680
- H.BinaryIdOffset = read (Buffer, offsetOf (&Header::BinaryIdOffset));
1681
- [[fallthrough]];
1682
- case 8ull :
1683
- H.MemProfOffset = read (Buffer, offsetOf (&Header::MemProfOffset));
1684
- [[fallthrough]];
1685
- default : // Version7 (when the backwards compatible header was introduced).
1686
- H.HashType = read (Buffer, offsetOf (&Header::HashType));
1687
- H.HashOffset = read (Buffer, offsetOf (&Header::HashOffset));
1688
- }
1689
-
1663
+ endian::readNext<uint64_t , llvm::endianness::little>(Buffer);
1664
+ if (H.getIndexedProfileVersion () >= 12 )
1665
+ H.VTableNamesOffset =
1666
+ endian::readNext<uint64_t , llvm::endianness::little>(Buffer);
1690
1667
return H;
1691
1668
}
1692
1669
@@ -1696,27 +1673,26 @@ uint64_t Header::getIndexedProfileVersion() const {
1696
1673
1697
1674
size_t Header::size () const {
1698
1675
switch (getIndexedProfileVersion ()) {
1699
- // When a new field is added to the header add a case statement here to
1700
- // compute the size as offset of the new field + size of the new field. This
1701
- // relies on the field being added to the end of the list.
1702
- static_assert (IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
1703
- " Please update the size computation below if a new field has "
1704
- " been added to the header, if not add a case statement to "
1705
- " fall through to the latest version." );
1676
+ // To retain backward compatibility, new fields must be appended to the end
1677
+ // of the header, and byte offset of existing fields shouldn't change when
1678
+ // indexed profile version gets incremented.
1679
+ static_assert (
1680
+ IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
1681
+ " Please update the size computation below if a new field has "
1682
+ " been added to the header; for a version bump without new "
1683
+ " fields, add a case statement to fall through to the latest version." );
1706
1684
case 12ull :
1707
- return offsetOf (&Header::VTableNamesOffset) +
1708
- sizeof (Header::VTableNamesOffset);
1685
+ return 72 ;
1709
1686
case 11ull :
1710
1687
[[fallthrough]];
1711
1688
case 10ull :
1712
- return offsetOf (&Header::TemporalProfTracesOffset) +
1713
- sizeof (Header::TemporalProfTracesOffset);
1689
+ return 64 ;
1714
1690
case 9ull :
1715
- return offsetOf (&Header::BinaryIdOffset) + sizeof (Header::BinaryIdOffset) ;
1691
+ return 56 ;
1716
1692
case 8ull :
1717
- return offsetOf (&Header::MemProfOffset) + sizeof (Header::MemProfOffset) ;
1693
+ return 48 ;
1718
1694
default : // Version7 (when the backwards compatible header was introduced).
1719
- return offsetOf (&Header::HashOffset) + sizeof (Header::HashOffset) ;
1695
+ return 40 ;
1720
1696
}
1721
1697
}
1722
1698
0 commit comments