aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
diff options
context:
space:
mode:
authorChoongwoo Han <choongwoo.han@microsoft.com>2021-03-23 15:59:45 -0700
committerVedant Kumar <vsk@apple.com>2021-03-23 16:25:20 -0700
commit772e1dd1ddc0cf138ab1a5e88d9614229e978491 (patch)
treed363d0998570eac332aa006f176d3c71e089de7e /llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
parent48d9b2fd8ea36f87b3fc57ddb101ed99d20f25bf (diff)
downloadllvm-772e1dd1ddc0cf138ab1a5e88d9614229e978491.zip
llvm-772e1dd1ddc0cf138ab1a5e88d9614229e978491.tar.gz
llvm-772e1dd1ddc0cf138ab1a5e88d9614229e978491.tar.bz2
[Coverage] Load records immediately
The current implementation keeps buffers generated for each object file until it completes loading of all files. This approach requires a lot of memory if there are a lot of huge object files. Thus, make it to load coverage records immediately rather than waiting for other binaries to be loaded. This reduces memory usage of llvm-cov from >128GB to 5GB when loading Chromium binaries in Windows. Additional testing: check-profile, check-llvm Differential Revision: https://reviews.llvm.org/D99110
Diffstat (limited to 'llvm/lib/ProfileData/Coverage/CoverageMapping.cpp')
-rw-r--r--llvm/lib/ProfileData/Coverage/CoverageMapping.cpp40
1 files changed, 27 insertions, 13 deletions
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index cdbcde5..1958e31 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -281,21 +281,29 @@ Error CoverageMapping::loadFunctionRecord(
return Error::success();
}
-Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
+// This function is for memory optimization by shortening the lifetimes
+// of CoverageMappingReader instances.
+Error CoverageMapping::loadFromReaders(
ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
- IndexedInstrProfReader &ProfileReader) {
- auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
-
+ IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage) {
for (const auto &CoverageReader : CoverageReaders) {
for (auto RecordOrErr : *CoverageReader) {
if (Error E = RecordOrErr.takeError())
- return std::move(E);
+ return E;
const auto &Record = *RecordOrErr;
- if (Error E = Coverage->loadFunctionRecord(Record, ProfileReader))
- return std::move(E);
+ if (Error E = Coverage.loadFunctionRecord(Record, ProfileReader))
+ return E;
}
}
+ return Error::success();
+}
+Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
+ ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
+ IndexedInstrProfReader &ProfileReader) {
+ auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
+ if (Error E = loadFromReaders(CoverageReaders, ProfileReader, *Coverage))
+ return std::move(E);
return std::move(Coverage);
}
@@ -316,16 +324,18 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
if (Error E = ProfileReaderOrErr.takeError())
return std::move(E);
auto ProfileReader = std::move(ProfileReaderOrErr.get());
+ auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
+ bool DataFound = false;
- SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
- SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
for (const auto &File : llvm::enumerate(ObjectFilenames)) {
- auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(File.value());
+ auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(
+ File.value(), /*FileSize=*/-1, /*RequiresNullTerminator=*/false);
if (std::error_code EC = CovMappingBufOrErr.getError())
return 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);
if (Error E = CoverageReadersOrErr.takeError()) {
@@ -335,15 +345,19 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
// E == success (originally a no_data_found error).
continue;
}
+
+ SmallVector<std::unique_ptr<CoverageMappingReader>, 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 = loadFromReaders(Readers, *ProfileReader, *Coverage))
+ 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<CoverageMapError>(coveragemap_error::no_data_found);
- return load(Readers, *ProfileReader);
+ return std::move(Coverage);
}
namespace {