diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -571,8 +571,6 @@ DenseMap> FilenameHash2RecordIndices; std::vector> FuncHashMismatches; - CoverageMapping() = default; - /// Add a function record corresponding to \p Record. Error loadFunctionRecord(const CoverageMappingRecord &Record, IndexedInstrProfReader &ProfileReader); @@ -585,13 +583,13 @@ getImpreciseRecordIndicesForFilename(StringRef Filename) const; public: + CoverageMapping() = default; CoverageMapping(const CoverageMapping &) = delete; CoverageMapping &operator=(const CoverageMapping &) = delete; - /// Load the coverage mapping using the given readers. - static Expected> + static Error load(ArrayRef> CoverageReaders, - IndexedInstrProfReader &ProfileReader); + IndexedInstrProfReader &ProfileReader, CoverageMapping *Coverage); /// Load the coverage mapping from the given object files and profile. If /// \p Arches is non-empty, it must specify an architecture for each object. diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -196,8 +196,7 @@ BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete; static Expected>> - create(MemoryBufferRef ObjectBuffer, StringRef Arch, - SmallVectorImpl> &ObjectFileBuffers); + create(MemoryBufferRef ObjectBuffer, StringRef Arch); static Expected> createCoverageReaderFromBuffer(StringRef Coverage, std::string &&FuncRecords, diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -281,11 +281,9 @@ return Error::success(); } -Expected> CoverageMapping::load( +Error CoverageMapping::load( ArrayRef> CoverageReaders, - IndexedInstrProfReader &ProfileReader) { - auto Coverage = std::unique_ptr(new CoverageMapping()); - + IndexedInstrProfReader &ProfileReader, CoverageMapping *Coverage) { for (const auto &CoverageReader : CoverageReaders) { for (auto RecordOrErr : *CoverageReader) { if (Error E = RecordOrErr.takeError()) @@ -296,7 +294,7 @@ } } - return std::move(Coverage); + return Error::success(); } // If E is a no_data_found error, returns success. Otherwise returns E. @@ -315,10 +313,11 @@ auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename); if (Error E = ProfileReaderOrErr.takeError()) return std::move(E); + auto ProfileReader = std::move(ProfileReaderOrErr.get()); + auto Coverage = std::unique_ptr(new CoverageMapping()); + bool DataFound = false; - SmallVector, 4> Readers; - SmallVector, 4> Buffers; for (const auto &File : llvm::enumerate(ObjectFilenames)) { auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(File.value()); if (std::error_code EC = CovMappingBufOrErr.getError()) @@ -327,7 +326,7 @@ MemoryBufferRef CovMappingBufRef = CovMappingBufOrErr.get()->getMemBufferRef(); auto CoverageReadersOrErr = - BinaryCoverageReader::create(CovMappingBufRef, Arch, Buffers); + BinaryCoverageReader::create(CovMappingBufRef, Arch); if (Error E = CoverageReadersOrErr.takeError()) { E = handleMaybeNoDataFoundError(std::move(E)); if (E) @@ -335,15 +334,19 @@ // E == success (originally a no_data_found error). continue; } + + SmallVector, 4> Readers; for (auto &Reader : CoverageReadersOrErr.get()) Readers.push_back(std::move(Reader)); - Buffers.push_back(std::move(CovMappingBufOrErr.get())); + DataFound |= !Readers.empty(); + if (Error E = load(Readers, *ProfileReader, Coverage.get())) + return std::move(E); } // If no readers were created, either no objects were provided or none of them // had coverage data. Return an error in the latter case. - if (Readers.empty() && !ObjectFilenames.empty()) + if (!DataFound && !ObjectFilenames.empty()) return make_error(coveragemap_error::no_data_found); - return load(Readers, *ProfileReader); + return std::move(Coverage); } namespace { diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -1002,9 +1002,7 @@ } Expected>> -BinaryCoverageReader::create( - MemoryBufferRef ObjectBuffer, StringRef Arch, - SmallVectorImpl> &ObjectFileBuffers) { +BinaryCoverageReader::create(MemoryBufferRef ObjectBuffer, StringRef Arch) { std::vector> Readers; if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) { @@ -1042,7 +1040,7 @@ } return BinaryCoverageReader::create( - ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers); + ArchiveOrErr.get()->getMemoryBufferRef(), Arch); } } @@ -1054,8 +1052,8 @@ if (!ChildBufOrErr) return ChildBufOrErr.takeError(); - auto ChildReadersOrErr = BinaryCoverageReader::create( - ChildBufOrErr.get(), Arch, ObjectFileBuffers); + auto ChildReadersOrErr = + BinaryCoverageReader::create(ChildBufOrErr.get(), Arch); if (!ChildReadersOrErr) return ChildReadersOrErr.takeError(); for (auto &Reader : ChildReadersOrErr.get()) @@ -1064,13 +1062,6 @@ if (Err) return std::move(Err); - // Thin archives reference object files outside of the archive file, i.e. - // files which reside in memory not owned by the caller. Transfer ownership - // to the caller. - if (Ar->isThin()) - for (auto &Buffer : Ar->takeThinBuffers()) - ObjectFileBuffers.push_back(std::move(Buffer)); - return std::move(Readers); } diff --git a/llvm/unittests/ProfileData/CoverageMappingTest.cpp b/llvm/unittests/ProfileData/CoverageMappingTest.cpp --- a/llvm/unittests/ProfileData/CoverageMappingTest.cpp +++ b/llvm/unittests/ProfileData/CoverageMappingTest.cpp @@ -235,6 +235,7 @@ Expected> readOutputFunctions() { std::vector> CoverageReaders; + auto Coverage = std::unique_ptr(new CoverageMapping()); if (UseMultipleReaders) { for (const auto &OF : OutputFunctions) { ArrayRef Funcs(OF); @@ -246,7 +247,10 @@ CoverageReaders.push_back( std::make_unique(Funcs)); } - return CoverageMapping::load(CoverageReaders, *ProfileReader); + if (Error E = CoverageMapping::load(CoverageReaders, *ProfileReader, + Coverage.get())) + return std::move(E); + return std::move(Coverage); } Error loadCoverageMapping(bool EmitFilenames = true) {