summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ProfileData/CoverageMappingReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ProfileData/CoverageMappingReader.cpp')
-rw-r--r--llvm/lib/ProfileData/CoverageMappingReader.cpp104
1 files changed, 82 insertions, 22 deletions
diff --git a/llvm/lib/ProfileData/CoverageMappingReader.cpp b/llvm/lib/ProfileData/CoverageMappingReader.cpp
index 89e1cf42c57..d251e8dcb81 100644
--- a/llvm/lib/ProfileData/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/CoverageMappingReader.cpp
@@ -306,31 +306,57 @@ StringRef InstrProfSymtab::getFuncName(uint64_t Pointer, size_t Size) {
return Data.substr(Pointer - Address, Size);
}
-template <typename T, support::endianness Endian>
-static std::error_code readCoverageMappingData(
- InstrProfSymtab &ProfileNames, StringRef Data,
- std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
- std::vector<StringRef> &Filenames) {
- using namespace support;
- llvm::DenseSet<T> UniqueFunctionMappingData;
-
- // Read the records in the coverage data section.
- for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
+struct CovMapFuncRecordReader {
+ // The interface to read coverage mapping function records for
+ // a module. \p Buf is a reference to the buffer pointer pointing
+ // to the \c CovHeader of coverage mapping data associated with
+ // the module.
+ virtual std::error_code readFunctionRecords(const char *&Buf,
+ const char *End) = 0;
+ template <class IntPtrT, support::endianness Endian>
+ static std::unique_ptr<CovMapFuncRecordReader>
+ get(coverage::CoverageMappingVersion Version, InstrProfSymtab &P,
+ std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
+ std::vector<StringRef> &F);
+};
+
+// A class for reading coverage mapping function records for a module.
+template <coverage::CoverageMappingVersion CovMapVersion, class IntPtrT,
+ support::endianness Endian>
+class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
+ typedef typename coverage::CovMapTraits<
+ CovMapVersion, IntPtrT>::CovMapFuncRecordType FuncRecordType;
+ typedef typename coverage::CovMapTraits<CovMapVersion, IntPtrT>::NameRefType
+ NameRefType;
+
+ llvm::DenseSet<NameRefType> UniqueFunctionMappingData;
+ InstrProfSymtab &ProfileNames;
+ std::vector<StringRef> &Filenames;
+ std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
+
+public:
+ VersionedCovMapFuncRecordReader(
+ InstrProfSymtab &P,
+ std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
+ std::vector<StringRef> &F)
+ : ProfileNames(P), Filenames(F), Records(R) {}
+
+ std::error_code readFunctionRecords(const char *&Buf,
+ const char *End) override {
+ using namespace support;
if (Buf + sizeof(CovMapHeader) > End)
return coveragemap_error::malformed;
auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
uint32_t NRecords = CovHeader->getNRecords<Endian>();
uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
- uint32_t Version = CovHeader->getVersion<Endian>();
- Buf = reinterpret_cast<const char *>(++CovHeader);
-
- if (Version > coverage::CoverageMappingCurrentVersion)
- return coveragemap_error::unsupported_version;
+ assert((CoverageMappingVersion)CovHeader->getVersion<Endian>() ==
+ CovMapVersion);
+ Buf = reinterpret_cast<const char *>(CovHeader + 1);
// Skip past the function records, saving the start and end for later.
const char *FunBuf = Buf;
- Buf += NRecords * sizeof(coverage::CovMapFunctionRecord<T>);
+ Buf += NRecords * sizeof(FuncRecordType);
const char *FunEnd = Buf;
// Get the filenames.
@@ -353,8 +379,7 @@ static std::error_code readCoverageMappingData(
// before reading the next map.
Buf += alignmentAdjustment(Buf, 8);
- auto CFR =
- reinterpret_cast<const coverage::CovMapFunctionRecord<T> *>(FunBuf);
+ auto CFR = reinterpret_cast<const FuncRecordType *>(FunBuf);
while ((const char *)CFR < FunEnd) {
// Read the function information
uint32_t DataSize = CFR->template getDataSize<Endian>();
@@ -369,7 +394,7 @@ 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.
- T NameRef = CFR->template getFuncNameRef<Endian>();
+ NameRefType NameRef = CFR->template getFuncNameRef<Endian>();
if (!UniqueFunctionMappingData.insert(NameRef).second)
continue;
@@ -378,15 +403,50 @@ static std::error_code readCoverageMappingData(
CFR->template getFuncName<Endian>(ProfileNames, FuncName))
return EC;
Records.push_back(BinaryCoverageReader::ProfileMappingRecord(
- CoverageMappingVersion(Version), FuncName, FuncHash, Mapping,
- FilenamesBegin, Filenames.size() - FilenamesBegin));
+ CovMapVersion, FuncName, FuncHash, Mapping, FilenamesBegin,
+ Filenames.size() - FilenamesBegin));
CFR++;
}
+ return std::error_code();
+ }
+};
+
+template <class IntPtrT, support::endianness Endian>
+std::unique_ptr<CovMapFuncRecordReader> CovMapFuncRecordReader::get(
+ coverage::CoverageMappingVersion Version, InstrProfSymtab &P,
+ std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
+ std::vector<StringRef> &F) {
+ using namespace coverage;
+ switch (Version) {
+ case CoverageMappingVersion1:
+ return llvm::make_unique<VersionedCovMapFuncRecordReader<
+ CoverageMappingVersion1, IntPtrT, Endian>>(P, R, F);
}
+ llvm_unreachable("Unsupported version");
+}
+template <typename T, support::endianness Endian>
+static std::error_code readCoverageMappingData(
+ InstrProfSymtab &ProfileNames, StringRef Data,
+ std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
+ std::vector<StringRef> &Filenames) {
+ using namespace coverage;
+ // Read the records in the coverage data section.
+ auto CovHeader =
+ reinterpret_cast<const coverage::CovMapHeader *>(Data.data());
+ CoverageMappingVersion Version =
+ (CoverageMappingVersion)CovHeader->getVersion<Endian>();
+ if (Version > coverage::CoverageMappingCurrentVersion)
+ return coveragemap_error::unsupported_version;
+ std::unique_ptr<CovMapFuncRecordReader> Reader =
+ CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
+ Filenames);
+ for (const char *Buf = Data.data(), *End = Buf + Data.size(); Buf < End;) {
+ if (std::error_code EC = Reader->readFunctionRecords(Buf, End))
+ return EC;
+ }
return std::error_code();
}
-
static const char *TestingFormatMagic = "llvmcovmtestdata";
static std::error_code loadTestingFormat(StringRef Data,
OpenPOWER on IntegriCloud