aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/Coverage
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ProfileData/Coverage')
-rw-r--r--llvm/lib/ProfileData/Coverage/CoverageMapping.cpp110
-rw-r--r--llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp19
2 files changed, 98 insertions, 31 deletions
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 6113f78aeb4e..ce71eebd4fd3 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/SmallBitVector.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/BuildID.h"
#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/Debug.h"
@@ -342,10 +343,49 @@ static Error handleMaybeNoDataFoundError(Error E) {
});
}
+Error CoverageMapping::loadFromFile(
+ StringRef Filename, StringRef Arch, StringRef CompilationDir,
+ IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
+ bool &DataFound, SmallVectorImpl<object::BuildID> *FoundBinaryIDs) {
+ auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(
+ Filename, /*IsText=*/false, /*RequiresNullTerminator=*/false);
+ if (std::error_code EC = CovMappingBufOrErr.getError())
+ return createFileError(Filename, errorCodeToError(EC));
+ MemoryBufferRef CovMappingBufRef =
+ CovMappingBufOrErr.get()->getMemBufferRef();
+ SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
+
+ SmallVector<object::BuildIDRef> BinaryIDs;
+ auto CoverageReadersOrErr = BinaryCoverageReader::create(
+ CovMappingBufRef, Arch, Buffers, CompilationDir,
+ FoundBinaryIDs ? &BinaryIDs : nullptr);
+ if (Error E = CoverageReadersOrErr.takeError()) {
+ E = handleMaybeNoDataFoundError(std::move(E));
+ if (E)
+ return createFileError(Filename, std::move(E));
+ return E;
+ }
+
+ SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
+ for (auto &Reader : CoverageReadersOrErr.get())
+ Readers.push_back(std::move(Reader));
+ if (FoundBinaryIDs && !Readers.empty()) {
+ llvm::append_range(*FoundBinaryIDs,
+ llvm::map_range(BinaryIDs, [](object::BuildIDRef BID) {
+ return object::BuildID(BID);
+ }));
+ }
+ DataFound |= !Readers.empty();
+ if (Error E = loadFromReaders(Readers, ProfileReader, Coverage))
+ return createFileError(Filename, std::move(E));
+ return Error::success();
+}
+
Expected<std::unique_ptr<CoverageMapping>>
CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
StringRef ProfileFilename, ArrayRef<StringRef> Arches,
- StringRef CompilationDir) {
+ StringRef CompilationDir,
+ const object::BuildIDFetcher *BIDFetcher) {
auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename);
if (Error E = ProfileReaderOrErr.takeError())
return createFileError(ProfileFilename, std::move(E));
@@ -353,35 +393,53 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
bool DataFound = false;
+ auto GetArch = [&](size_t Idx) {
+ if (Arches.empty())
+ return StringRef();
+ if (Arches.size() == 1)
+ return Arches.front();
+ return Arches[Idx];
+ };
+
+ SmallVector<object::BuildID> FoundBinaryIDs;
for (const auto &File : llvm::enumerate(ObjectFilenames)) {
- auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(
- File.value(), /*IsText=*/false, /*RequiresNullTerminator=*/false);
- if (std::error_code EC = CovMappingBufOrErr.getError())
- return createFileError(File.value(), errorCodeToError(EC));
- StringRef Arch = Arches.empty() ? StringRef() : Arches[File.index()];
- MemoryBufferRef CovMappingBufRef =
- CovMappingBufOrErr.get()->getMemBufferRef();
- SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
- auto CoverageReadersOrErr = BinaryCoverageReader::create(
- CovMappingBufRef, Arch, Buffers, CompilationDir);
- if (Error E = CoverageReadersOrErr.takeError()) {
- E = handleMaybeNoDataFoundError(std::move(E));
- if (E)
- return createFileError(File.value(), std::move(E));
- // E == success (originally a no_data_found error).
- continue;
+ if (Error E =
+ loadFromFile(File.value(), GetArch(File.index()), CompilationDir,
+ *ProfileReader, *Coverage, DataFound, &FoundBinaryIDs))
+ return std::move(E);
+ }
+
+ if (BIDFetcher) {
+ std::vector<object::BuildID> ProfileBinaryIDs;
+ if (Error E = ProfileReader->readBinaryIds(ProfileBinaryIDs))
+ return createFileError(ProfileFilename, std::move(E));
+
+ SmallVector<object::BuildIDRef> BinaryIDsToFetch;
+ if (!ProfileBinaryIDs.empty()) {
+ const auto &Compare = [](object::BuildIDRef A, object::BuildIDRef B) {
+ return std::lexicographical_compare(A.begin(), A.end(), B.begin(),
+ B.end());
+ };
+ llvm::sort(FoundBinaryIDs, Compare);
+ std::set_difference(
+ ProfileBinaryIDs.begin(), ProfileBinaryIDs.end(),
+ FoundBinaryIDs.begin(), FoundBinaryIDs.end(),
+ std::inserter(BinaryIDsToFetch, BinaryIDsToFetch.end()), Compare);
}
- SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
- for (auto &Reader : CoverageReadersOrErr.get())
- Readers.push_back(std::move(Reader));
- DataFound |= !Readers.empty();
- if (Error E = loadFromReaders(Readers, *ProfileReader, *Coverage))
- return createFileError(File.value(), std::move(E));
+ for (object::BuildIDRef BinaryID : BinaryIDsToFetch) {
+ std::optional<std::string> PathOpt = BIDFetcher->fetch(BinaryID);
+ if (!PathOpt)
+ continue;
+ std::string Path = std::move(*PathOpt);
+ StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
+ if (Error E = loadFromFile(Path, Arch, CompilationDir, *ProfileReader,
+ *Coverage, DataFound))
+ 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 (!DataFound && !ObjectFilenames.empty())
+
+ if (!DataFound)
return createFileError(
join(ObjectFilenames.begin(), ObjectFilenames.end(), ", "),
make_error<CoverageMapError>(coveragemap_error::no_data_found));
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index 41962ab24ff9..d313864e2ddb 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -954,7 +954,8 @@ static Expected<std::vector<SectionRef>> lookupSections(ObjectFile &OF,
static Expected<std::unique_ptr<BinaryCoverageReader>>
loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
- StringRef CompilationDir = "") {
+ StringRef CompilationDir = "",
+ std::optional<object::BuildIDRef> *BinaryID = nullptr) {
std::unique_ptr<ObjectFile> OF;
if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
// If we have a universal binary, try to look up the object for the
@@ -1052,6 +1053,9 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
FuncRecords = std::move(WritableBuffer);
}
+ if (BinaryID)
+ *BinaryID = getBuildID(OF.get());
+
return BinaryCoverageReader::createCoverageReaderFromBuffer(
CoverageMapping, std::move(FuncRecords), std::move(ProfileNames),
BytesInAddress, Endian, CompilationDir);
@@ -1074,7 +1078,7 @@ Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
BinaryCoverageReader::create(
MemoryBufferRef ObjectBuffer, StringRef Arch,
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
- StringRef CompilationDir) {
+ StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
if (ObjectBuffer.getBuffer().startswith(TestingFormatMagic)) {
@@ -1114,7 +1118,7 @@ BinaryCoverageReader::create(
return BinaryCoverageReader::create(
ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
- CompilationDir);
+ CompilationDir, BinaryIDs);
}
}
@@ -1127,7 +1131,8 @@ BinaryCoverageReader::create(
return ChildBufOrErr.takeError();
auto ChildReadersOrErr = BinaryCoverageReader::create(
- ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir);
+ ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
+ BinaryIDs);
if (!ChildReadersOrErr)
return ChildReadersOrErr.takeError();
for (auto &Reader : ChildReadersOrErr.get())
@@ -1146,10 +1151,14 @@ BinaryCoverageReader::create(
return std::move(Readers);
}
- auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir);
+ std::optional<object::BuildIDRef> BinaryID;
+ auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
+ BinaryIDs ? &BinaryID : nullptr);
if (!ReaderOrErr)
return ReaderOrErr.takeError();
Readers.push_back(std::move(ReaderOrErr.get()));
+ if (BinaryID)
+ BinaryIDs->push_back(*BinaryID);
return std::move(Readers);
}