From 2c77694774b1f4b2bdbf4cd8bd21b3adba0af01a Mon Sep 17 00:00:00 2001 From: Xinliang David Li Date: Wed, 13 Jan 2016 00:53:46 +0000 Subject: [PATCH] [Coverage] Refactor coverage mapping reader code /NFC (Resubmit after fixing build bot failures) In this refactoring, member functions are introduced to access CovMap header/func record members and hide layout details. This will enable further code restructuring to support reading multiple versions of coverage mapping data with shared/templatized code. (When coveremap format version changes, backward compatibtility should be preserved). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@257551 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ProfileData/CoverageMapping.h | 78 ++++++++++++++++------ lib/ProfileData/CoverageMappingReader.cpp | 30 ++++----- 2 files changed, 72 insertions(+), 36 deletions(-) diff --git a/include/llvm/ProfileData/CoverageMapping.h b/include/llvm/ProfileData/CoverageMapping.h index 2386442d28b..84c4c9dd640 100644 --- a/include/llvm/ProfileData/CoverageMapping.h +++ b/include/llvm/ProfileData/CoverageMapping.h @@ -20,13 +20,33 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/iterator.h" -#include "llvm/ProfileData/InstrProfData.inc" +#include "llvm/ProfileData/InstrProf.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/raw_ostream.h" #include #include +namespace llvm { +namespace coverage { +enum class coveragemap_error { + success = 0, + eof, + no_data_found, + unsupported_version, + truncated, + malformed +}; +} // end of coverage namespace. +} + +namespace std { +template <> +struct is_error_code_enum : std::true_type { +}; +} + namespace llvm { class IndexedInstrProfReader; namespace coverage { @@ -455,20 +475,10 @@ public: const std::error_category &coveragemap_category(); -enum class coveragemap_error { - success = 0, - eof, - no_data_found, - unsupported_version, - truncated, - malformed -}; - inline std::error_code make_error_code(coveragemap_error E) { return std::error_code(static_cast(E), coveragemap_category()); } - // Profile coverage map has the following layout: // [CoverageMapFileHeader] // [ArrayStart] @@ -479,14 +489,50 @@ inline std::error_code make_error_code(coveragemap_error E) { // [Encoded Region Mapping Data] LLVM_PACKED_START template struct CovMapFunctionRecord { - #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name; - #include "llvm/ProfileData/InstrProfData.inc" +#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name; +#include "llvm/ProfileData/InstrProfData.inc" + + // Return the structural hash associated with the function. + template uint64_t getFuncHash() const { + return support::endian::byte_swap(FuncHash); + } + // Return the coverage map data size for the funciton. + template uint32_t getDataSize() const { + return support::endian::byte_swap(DataSize); + } + // Return function lookup key. The value is consider opaque. + template IntPtrT getFuncNameRef() const { + return support::endian::byte_swap(NamePtr); + } + // Return the PGO name of the function */ + template + std::error_code getFuncName(InstrProfSymtab &ProfileNames, + StringRef &FuncName) const { + IntPtrT NameRef = getFuncNameRef(); + uint32_t NameS = support::endian::byte_swap(NameSize); + FuncName = ProfileNames.getFuncName(NameRef, NameS); + if (NameS && FuncName.empty()) + return coveragemap_error::malformed; + return std::error_code(); + } }; // Per module coverage mapping data header, i.e. CoverageMapFileHeader // documented above. struct CovMapHeader { #define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name; #include "llvm/ProfileData/InstrProfData.inc" + template uint32_t getNRecords() const { + return support::endian::byte_swap(NRecords); + } + template uint32_t getFilenamesSize() const { + return support::endian::byte_swap(FilenamesSize); + } + template uint32_t getCoverageSize() const { + return support::endian::byte_swap(CoverageSize); + } + template uint32_t getVersion() const { + return support::endian::byte_swap(Version); + } }; LLVM_PACKED_END @@ -529,10 +575,4 @@ template<> struct DenseMapInfo { } // end namespace llvm -namespace std { -template <> -struct is_error_code_enum : std::true_type {}; -} - - #endif // LLVM_PROFILEDATA_COVERAGEMAPPING_H_ diff --git a/lib/ProfileData/CoverageMappingReader.cpp b/lib/ProfileData/CoverageMappingReader.cpp index af6c616fa03..89e1cf42c57 100644 --- a/lib/ProfileData/CoverageMappingReader.cpp +++ b/lib/ProfileData/CoverageMappingReader.cpp @@ -319,13 +319,10 @@ static std::error_code readCoverageMappingData( if (Buf + sizeof(CovMapHeader) > End) return coveragemap_error::malformed; auto CovHeader = reinterpret_cast(Buf); - uint32_t NRecords = - endian::byte_swap(CovHeader->NRecords); - uint32_t FilenamesSize = - endian::byte_swap(CovHeader->FilenamesSize); - uint32_t CoverageSize = - endian::byte_swap(CovHeader->CoverageSize); - uint32_t Version = endian::byte_swap(CovHeader->Version); + uint32_t NRecords = CovHeader->getNRecords(); + uint32_t FilenamesSize = CovHeader->getFilenamesSize(); + uint32_t CoverageSize = CovHeader->getCoverageSize(); + uint32_t Version = CovHeader->getVersion(); Buf = reinterpret_cast(++CovHeader); if (Version > coverage::CoverageMappingCurrentVersion) @@ -360,11 +357,8 @@ static std::error_code readCoverageMappingData( reinterpret_cast *>(FunBuf); while ((const char *)CFR < FunEnd) { // Read the function information - T NamePtr = endian::byte_swap(CFR->NamePtr); - uint32_t NameSize = endian::byte_swap(CFR->NameSize); - uint32_t DataSize = endian::byte_swap(CFR->DataSize); - uint64_t FuncHash = endian::byte_swap(CFR->FuncHash); - CFR++; + uint32_t DataSize = CFR->template getDataSize(); + uint64_t FuncHash = CFR->template getFuncHash(); // Now use that to read the coverage data. if (CovBuf + DataSize > CovEnd) @@ -375,16 +369,18 @@ static std::error_code readCoverageMappingData( // Ignore this record if we already have a record that points to the same // function name. This is useful to ignore the redundant records for the // functions with ODR linkage. - if (!UniqueFunctionMappingData.insert(NamePtr).second) + T NameRef = CFR->template getFuncNameRef(); + if (!UniqueFunctionMappingData.insert(NameRef).second) continue; - // Finally, grab the name and create a record. - StringRef FuncName = ProfileNames.getFuncName(NamePtr, NameSize); - if (NameSize && FuncName.empty()) - return coveragemap_error::malformed; + StringRef FuncName; + if (std::error_code EC = + CFR->template getFuncName(ProfileNames, FuncName)) + return EC; Records.push_back(BinaryCoverageReader::ProfileMappingRecord( CoverageMappingVersion(Version), FuncName, FuncHash, Mapping, FilenamesBegin, Filenames.size() - FilenamesBegin)); + CFR++; } } -- 2.34.1