diff options
Diffstat (limited to 'contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp')
-rw-r--r-- | contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 129 |
1 files changed, 79 insertions, 50 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)); } |