summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ProfileData/CoverageMappingReader.cpp
diff options
context:
space:
mode:
authorXinliang David Li <davidxl@google.com>2016-01-13 23:29:33 +0000
committerXinliang David Li <davidxl@google.com>2016-01-13 23:29:33 +0000
commita9d784666ec1849ac4730254f1308524f9dfa744 (patch)
treee155af7ba9eda40ad17bc192b1230670a95189f8 /llvm/lib/ProfileData/CoverageMappingReader.cpp
parent8dfe504bada0f2930eb7bf781471f9da01ceb1ca (diff)
downloadbcm5719-llvm-a9d784666ec1849ac4730254f1308524f9dfa744.tar.gz
bcm5719-llvm-a9d784666ec1849ac4730254f1308524f9dfa744.zip
[Coverage] introduce class hierarchy (funcRecordReader) to support multiple versions of coverage data
[resubmit after fixing build bot failures: qualify make_unique and eliminate -Wcovered-switch-default warning. With the planned size reduction change, the coverage format version is expected to be bumped up. This patch adds necessary support such that backward compatibility can be kept with maximal code sharing. Reading different versions of coverage data just requires instantiating the reader according to the version. No functional change is intended. Differiential Revision: http://reviews.llvm.org/D16133 llvm-svn: 257708
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