diff options
Diffstat (limited to 'llvm/include')
| -rw-r--r-- | llvm/include/llvm/ProfileData/InstrProf.h | 102 | ||||
| -rw-r--r-- | llvm/include/llvm/ProfileData/InstrProfReader.h | 22 |
2 files changed, 105 insertions, 19 deletions
diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 668e6d3663d..f425c6e13ed 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -16,8 +16,11 @@ #ifndef LLVM_PROFILEDATA_INSTRPROF_H_ #define LLVM_PROFILEDATA_INSTRPROF_H_ +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MD5.h" #include <cstdint> #include <list> #include <system_error> @@ -132,6 +135,105 @@ struct InstrProfRecord { } }; +namespace IndexedInstrProf { +enum class HashT : uint32_t { + MD5, + + Last = MD5 +}; + +static inline uint64_t MD5Hash(StringRef Str) { + MD5 Hash; + Hash.update(Str); + llvm::MD5::MD5Result Result; + Hash.final(Result); + // Return the least significant 8 bytes. Our MD5 implementation returns the + // result in little endian, so we may need to swap bytes. + using namespace llvm::support; + return endian::read<uint64_t, little, unaligned>(Result); +} + +static inline uint64_t ComputeHash(HashT Type, StringRef K) { + switch (Type) { + case HashT::MD5: + return IndexedInstrProf::MD5Hash(K); + } + llvm_unreachable("Unhandled hash type"); +} + +const uint64_t Magic = 0x8169666f72706cff; // "\xfflprofi\x81" +const uint64_t Version = 3; +const HashT HashType = HashT::MD5; + +struct Header { + uint64_t Magic; + uint64_t Version; + uint64_t MaxFunctionCount; + uint64_t HashType; + uint64_t HashOffset; +}; + +} // end namespace IndexedInstrProf + +namespace RawInstrProf { + +const uint64_t Version = 1; + +// Magic number to detect file format and endianness. +// Use 255 at one end, since no UTF-8 file can use that character. Avoid 0, +// so that utilities, like strings, don't grab it as a string. 129 is also +// invalid UTF-8, and high enough to be interesting. +// Use "lprofr" in the centre to stand for "LLVM Profile Raw", or "lprofR" +// for 32-bit platforms. +// The magic and version need to be kept in sync with +// projects/compiler-rt/lib/profile/InstrProfiling.c + +template <class IntPtrT> +inline uint64_t getMagic(); +template <> +inline uint64_t getMagic<uint64_t>() { + return uint64_t(255) << 56 | uint64_t('l') << 48 | uint64_t('p') << 40 | + uint64_t('r') << 32 | uint64_t('o') << 24 | uint64_t('f') << 16 | + uint64_t('r') << 8 | uint64_t(129); +} + +template <> +inline uint64_t getMagic<uint32_t>() { + return uint64_t(255) << 56 | uint64_t('l') << 48 | uint64_t('p') << 40 | + uint64_t('r') << 32 | uint64_t('o') << 24 | uint64_t('f') << 16 | + uint64_t('R') << 8 | uint64_t(129); +} + +// The definition should match the structure defined in +// compiler-rt/lib/profile/InstrProfiling.h. +// It should also match the synthesized type in +// Transforms/Instrumentation/InstrProfiling.cpp:getOrCreateRegionCounters. + +template <class IntPtrT> +struct ProfileData { + const uint32_t NameSize; + const uint32_t NumCounters; + const uint64_t FuncHash; + const IntPtrT NamePtr; + const IntPtrT CounterPtr; +}; + +// The definition should match the header referenced in +// compiler-rt/lib/profile/InstrProfilingFile.c and +// InstrProfilingBuffer.c. + +struct Header { + const uint64_t Magic; + const uint64_t Version; + const uint64_t DataSize; + const uint64_t CountersSize; + const uint64_t NamesSize; + const uint64_t CountersDelta; + const uint64_t NamesDelta; +}; + +} // end namespace RawInstrProf + } // end namespace llvm namespace std { diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h index c0585d6f6d2..cdead0f112d 100644 --- a/llvm/include/llvm/ProfileData/InstrProfReader.h +++ b/llvm/include/llvm/ProfileData/InstrProfReader.h @@ -132,28 +132,12 @@ class RawInstrProfReader : public InstrProfReader { private: /// The profile data file contents. std::unique_ptr<MemoryBuffer> DataBuffer; - struct ProfileData { - const uint32_t NameSize; - const uint32_t NumCounters; - const uint64_t FuncHash; - const IntPtrT NamePtr; - const IntPtrT CounterPtr; - }; - struct RawHeader { - const uint64_t Magic; - const uint64_t Version; - const uint64_t DataSize; - const uint64_t CountersSize; - const uint64_t NamesSize; - const uint64_t CountersDelta; - const uint64_t NamesDelta; - }; bool ShouldSwapBytes; uint64_t CountersDelta; uint64_t NamesDelta; - const ProfileData *Data; - const ProfileData *DataEnd; + const RawInstrProf::ProfileData<IntPtrT> *Data; + const RawInstrProf::ProfileData<IntPtrT> *DataEnd; const uint64_t *CountersStart; const char *NamesStart; const char *ProfileEnd; @@ -170,7 +154,7 @@ public: private: std::error_code readNextHeader(const char *CurrentPos); - std::error_code readHeader(const RawHeader &Header); + std::error_code readHeader(const RawInstrProf::Header &Header); template <class IntT> IntT swap(IntT Int) const { return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int; |

