forked from OSchip/llvm-project
[Coverage] Refactor coverage mapping reader code /NFC
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). llvm-svn: 257547
This commit is contained in:
parent
359cab3bb3
commit
c3498b07db
|
@ -20,8 +20,9 @@
|
||||||
#include "llvm/ADT/Hashing.h"
|
#include "llvm/ADT/Hashing.h"
|
||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/ADT/iterator.h"
|
#include "llvm/ADT/iterator.h"
|
||||||
#include "llvm/ProfileData/InstrProfData.inc"
|
#include "llvm/ProfileData/InstrProf.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/Endian.h"
|
||||||
#include "llvm/Support/ErrorOr.h"
|
#include "llvm/Support/ErrorOr.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
|
@ -479,14 +480,50 @@ inline std::error_code make_error_code(coveragemap_error E) {
|
||||||
// [Encoded Region Mapping Data]
|
// [Encoded Region Mapping Data]
|
||||||
LLVM_PACKED_START
|
LLVM_PACKED_START
|
||||||
template <class IntPtrT> struct CovMapFunctionRecord {
|
template <class IntPtrT> struct CovMapFunctionRecord {
|
||||||
#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
|
#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
|
||||||
#include "llvm/ProfileData/InstrProfData.inc"
|
#include "llvm/ProfileData/InstrProfData.inc"
|
||||||
|
|
||||||
|
// Return the structural hash associated with the function.
|
||||||
|
template <support::endianness Endian> uint64_t getFuncHash() const {
|
||||||
|
return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
|
||||||
|
}
|
||||||
|
// Return the coverage map data size for the funciton.
|
||||||
|
template <support::endianness Endian> uint32_t getDataSize() const {
|
||||||
|
return support::endian::byte_swap<uint32_t, Endian>(DataSize);
|
||||||
|
}
|
||||||
|
// Return function lookup key. The value is consider opaque.
|
||||||
|
template <support::endianness Endian> IntPtrT getFuncNameRef() const {
|
||||||
|
return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
|
||||||
|
}
|
||||||
|
// Return the PGO name of the function */
|
||||||
|
template <support::endianness Endian>
|
||||||
|
std::error_code getFuncName(InstrProfSymtab &ProfileNames,
|
||||||
|
StringRef &FuncName) const {
|
||||||
|
IntPtrT NameRef = getFuncNameRef<Endian>();
|
||||||
|
uint32_t NameS = support::endian::byte_swap<IntPtrT, Endian>(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
|
// Per module coverage mapping data header, i.e. CoverageMapFileHeader
|
||||||
// documented above.
|
// documented above.
|
||||||
struct CovMapHeader {
|
struct CovMapHeader {
|
||||||
#define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
|
#define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
|
||||||
#include "llvm/ProfileData/InstrProfData.inc"
|
#include "llvm/ProfileData/InstrProfData.inc"
|
||||||
|
template <support::endianness Endian> uint32_t getNRecords() const {
|
||||||
|
return support::endian::byte_swap<uint32_t, Endian>(NRecords);
|
||||||
|
}
|
||||||
|
template <support::endianness Endian> uint32_t getFilenamesSize() const {
|
||||||
|
return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
|
||||||
|
}
|
||||||
|
template <support::endianness Endian> uint32_t getCoverageSize() const {
|
||||||
|
return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
|
||||||
|
}
|
||||||
|
template <support::endianness Endian> uint32_t getVersion() const {
|
||||||
|
return support::endian::byte_swap<uint32_t, Endian>(Version);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
LLVM_PACKED_END
|
LLVM_PACKED_END
|
||||||
|
|
|
@ -319,13 +319,10 @@ static std::error_code readCoverageMappingData(
|
||||||
if (Buf + sizeof(CovMapHeader) > End)
|
if (Buf + sizeof(CovMapHeader) > End)
|
||||||
return coveragemap_error::malformed;
|
return coveragemap_error::malformed;
|
||||||
auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
|
auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
|
||||||
uint32_t NRecords =
|
uint32_t NRecords = CovHeader->getNRecords<Endian>();
|
||||||
endian::byte_swap<uint32_t, Endian>(CovHeader->NRecords);
|
uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
|
||||||
uint32_t FilenamesSize =
|
uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
|
||||||
endian::byte_swap<uint32_t, Endian>(CovHeader->FilenamesSize);
|
uint32_t Version = CovHeader->getVersion<Endian>();
|
||||||
uint32_t CoverageSize =
|
|
||||||
endian::byte_swap<uint32_t, Endian>(CovHeader->CoverageSize);
|
|
||||||
uint32_t Version = endian::byte_swap<uint32_t, Endian>(CovHeader->Version);
|
|
||||||
Buf = reinterpret_cast<const char *>(++CovHeader);
|
Buf = reinterpret_cast<const char *>(++CovHeader);
|
||||||
|
|
||||||
if (Version > coverage::CoverageMappingCurrentVersion)
|
if (Version > coverage::CoverageMappingCurrentVersion)
|
||||||
|
@ -360,11 +357,8 @@ static std::error_code readCoverageMappingData(
|
||||||
reinterpret_cast<const coverage::CovMapFunctionRecord<T> *>(FunBuf);
|
reinterpret_cast<const coverage::CovMapFunctionRecord<T> *>(FunBuf);
|
||||||
while ((const char *)CFR < FunEnd) {
|
while ((const char *)CFR < FunEnd) {
|
||||||
// Read the function information
|
// Read the function information
|
||||||
T NamePtr = endian::byte_swap<T, Endian>(CFR->NamePtr);
|
uint32_t DataSize = CFR->template getDataSize<Endian>();
|
||||||
uint32_t NameSize = endian::byte_swap<uint32_t, Endian>(CFR->NameSize);
|
uint64_t FuncHash = CFR->template getFuncHash<Endian>();
|
||||||
uint32_t DataSize = endian::byte_swap<uint32_t, Endian>(CFR->DataSize);
|
|
||||||
uint64_t FuncHash = endian::byte_swap<uint64_t, Endian>(CFR->FuncHash);
|
|
||||||
CFR++;
|
|
||||||
|
|
||||||
// Now use that to read the coverage data.
|
// Now use that to read the coverage data.
|
||||||
if (CovBuf + DataSize > CovEnd)
|
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
|
// 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
|
// function name. This is useful to ignore the redundant records for the
|
||||||
// functions with ODR linkage.
|
// functions with ODR linkage.
|
||||||
if (!UniqueFunctionMappingData.insert(NamePtr).second)
|
T NameRef = CFR->template getFuncNameRef<Endian>();
|
||||||
|
if (!UniqueFunctionMappingData.insert(NameRef).second)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Finally, grab the name and create a record.
|
StringRef FuncName;
|
||||||
StringRef FuncName = ProfileNames.getFuncName(NamePtr, NameSize);
|
if (std::error_code EC =
|
||||||
if (NameSize && FuncName.empty())
|
CFR->template getFuncName<Endian>(ProfileNames, FuncName))
|
||||||
return coveragemap_error::malformed;
|
return EC;
|
||||||
Records.push_back(BinaryCoverageReader::ProfileMappingRecord(
|
Records.push_back(BinaryCoverageReader::ProfileMappingRecord(
|
||||||
CoverageMappingVersion(Version), FuncName, FuncHash, Mapping,
|
CoverageMappingVersion(Version), FuncName, FuncHash, Mapping,
|
||||||
FilenamesBegin, Filenames.size() - FilenamesBegin));
|
FilenamesBegin, Filenames.size() - FilenamesBegin));
|
||||||
|
CFR++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue