summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/ProfileData/Coverage
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/ProfileData/Coverage')
-rw-r--r--contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp129
-rw-r--r--contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp2
-rw-r--r--contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp12
3 files changed, 90 insertions, 53 deletions
diff --git a/contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index fcd4e24..6d907c7 100644
--- a/contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -183,72 +183,101 @@ void FunctionRecordIterator::skipOtherFiles() {
*this = FunctionRecordIterator();
}
+Error CoverageMapping::loadFunctionRecord(
+ const CoverageMappingRecord &Record,
+ IndexedInstrProfReader &ProfileReader) {
+ StringRef OrigFuncName = Record.FunctionName;
+ if (Record.Filenames.empty())
+ OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName);
+ else
+ OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
+
+ // Don't load records for functions we've already seen.
+ if (!FunctionNames.insert(OrigFuncName).second)
+ return Error::success();
+
+ CounterMappingContext Ctx(Record.Expressions);
+
+ std::vector<uint64_t> Counts;
+ if (Error E = ProfileReader.getFunctionCounts(Record.FunctionName,
+ Record.FunctionHash, Counts)) {
+ instrprof_error IPE = InstrProfError::take(std::move(E));
+ if (IPE == instrprof_error::hash_mismatch) {
+ MismatchedFunctionCount++;
+ return Error::success();
+ } else if (IPE != instrprof_error::unknown_function)
+ return make_error<InstrProfError>(IPE);
+ Counts.assign(Record.MappingRegions.size(), 0);
+ }
+ Ctx.setCounts(Counts);
+
+ assert(!Record.MappingRegions.empty() && "Function has no regions");
+
+ FunctionRecord Function(OrigFuncName, Record.Filenames);
+ for (const auto &Region : Record.MappingRegions) {
+ Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
+ if (auto E = ExecutionCount.takeError()) {
+ llvm::consumeError(std::move(E));
+ return Error::success();
+ }
+ Function.pushRegion(Region, *ExecutionCount);
+ }
+ if (Function.CountedRegions.size() != Record.MappingRegions.size()) {
+ MismatchedFunctionCount++;
+ return Error::success();
+ }
+
+ Functions.push_back(std::move(Function));
+ return Error::success();
+}
+
Expected<std::unique_ptr<CoverageMapping>>
CoverageMapping::load(CoverageMappingReader &CoverageReader,
IndexedInstrProfReader &ProfileReader) {
auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
- std::vector<uint64_t> Counts;
- for (const auto &Record : CoverageReader) {
- CounterMappingContext Ctx(Record.Expressions);
-
- Counts.clear();
- if (Error E = ProfileReader.getFunctionCounts(
- Record.FunctionName, Record.FunctionHash, Counts)) {
- instrprof_error IPE = InstrProfError::take(std::move(E));
- if (IPE == instrprof_error::hash_mismatch) {
- Coverage->MismatchedFunctionCount++;
- continue;
- } else if (IPE != instrprof_error::unknown_function)
- return make_error<InstrProfError>(IPE);
- Counts.assign(Record.MappingRegions.size(), 0);
- }
- Ctx.setCounts(Counts);
+ for (const auto &Record : CoverageReader)
+ if (Error E = Coverage->loadFunctionRecord(Record, ProfileReader))
+ return std::move(E);
- assert(!Record.MappingRegions.empty() && "Function has no regions");
+ return std::move(Coverage);
+}
- StringRef OrigFuncName = Record.FunctionName;
- if (Record.Filenames.empty())
- OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName);
- else
- OrigFuncName =
- getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
- FunctionRecord Function(OrigFuncName, Record.Filenames);
- for (const auto &Region : Record.MappingRegions) {
- Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
- if (auto E = ExecutionCount.takeError()) {
- llvm::consumeError(std::move(E));
- break;
- }
- Function.pushRegion(Region, *ExecutionCount);
- }
- if (Function.CountedRegions.size() != Record.MappingRegions.size()) {
- Coverage->MismatchedFunctionCount++;
- continue;
- }
+Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
+ ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
+ IndexedInstrProfReader &ProfileReader) {
+ auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
- Coverage->Functions.push_back(std::move(Function));
- }
+ for (const auto &CoverageReader : CoverageReaders)
+ for (const auto &Record : *CoverageReader)
+ if (Error E = Coverage->loadFunctionRecord(Record, ProfileReader))
+ return std::move(E);
return std::move(Coverage);
}
Expected<std::unique_ptr<CoverageMapping>>
-CoverageMapping::load(StringRef ObjectFilename, StringRef ProfileFilename,
- StringRef Arch) {
- auto CounterMappingBuff = MemoryBuffer::getFileOrSTDIN(ObjectFilename);
- if (std::error_code EC = CounterMappingBuff.getError())
- return errorCodeToError(EC);
- auto CoverageReaderOrErr =
- BinaryCoverageReader::create(CounterMappingBuff.get(), Arch);
- if (Error E = CoverageReaderOrErr.takeError())
- return std::move(E);
- auto CoverageReader = std::move(CoverageReaderOrErr.get());
+CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
+ StringRef ProfileFilename, StringRef Arch) {
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
if (Error E = ProfileReaderOrErr.takeError())
return std::move(E);
auto ProfileReader = std::move(ProfileReaderOrErr.get());
- return load(*CoverageReader, *ProfileReader);
+
+ SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
+ SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
+ for (StringRef ObjectFilename : ObjectFilenames) {
+ auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(ObjectFilename);
+ if (std::error_code EC = CovMappingBufOrErr.getError())
+ return errorCodeToError(EC);
+ auto CoverageReaderOrErr =
+ BinaryCoverageReader::create(CovMappingBufOrErr.get(), Arch);
+ if (Error E = CoverageReaderOrErr.takeError())
+ return std::move(E);
+ Readers.push_back(std::move(CoverageReaderOrErr.get()));
+ Buffers.push_back(std::move(CovMappingBufOrErr.get()));
+ }
+ return load(Readers, *ProfileReader);
}
namespace {
@@ -560,7 +589,7 @@ std::string getCoverageMapErrString(coveragemap_error Err) {
// will be removed once this transition is complete. Clients should prefer to
// deal with the Error value directly, rather than converting to error_code.
class CoverageMappingErrorCategoryType : public std::error_category {
- const char *name() const LLVM_NOEXCEPT override { return "llvm.coveragemap"; }
+ const char *name() const noexcept override { return "llvm.coveragemap"; }
std::string message(int IE) const override {
return getCoverageMapErrString(static_cast<coveragemap_error>(IE));
}
diff --git a/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index 1a4b4f5..a6c7031 100644
--- a/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -648,7 +648,7 @@ BinaryCoverageReader::create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,
StringRef Coverage;
uint8_t BytesInAddress;
support::endianness Endian;
- Error E;
+ Error E = Error::success();
consumeError(std::move(E));
if (ObjectBuffer->getBuffer().startswith(TestingFormatMagic))
// This is a special format used for testing.
diff --git a/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp b/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
index 8ff90d6..8235633 100644
--- a/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
+++ b/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
@@ -108,8 +108,16 @@ static void writeCounter(ArrayRef<CounterExpression> Expressions, Counter C,
void CoverageMappingWriter::write(raw_ostream &OS) {
// Sort the regions in an ascending order by the file id and the starting
- // location.
- std::stable_sort(MappingRegions.begin(), MappingRegions.end());
+ // location. Sort by region kinds to ensure stable order for tests.
+ std::stable_sort(
+ MappingRegions.begin(), MappingRegions.end(),
+ [](const CounterMappingRegion &LHS, const CounterMappingRegion &RHS) {
+ if (LHS.FileID != RHS.FileID)
+ return LHS.FileID < RHS.FileID;
+ if (LHS.startLoc() != RHS.startLoc())
+ return LHS.startLoc() < RHS.startLoc();
+ return LHS.Kind < RHS.Kind;
+ });
// Write out the fileid -> filename mapping.
encodeULEB128(VirtualFileMapping.size(), OS);
OpenPOWER on IntegriCloud