aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
diff options
context:
space:
mode:
authorZequan Wu <zequanwu@google.com>2023-08-14 15:36:47 -0400
committerZequan Wu <zequanwu@google.com>2023-09-15 13:47:23 -0400
commit32db121b29f78e4c41116b2a8f1c730f9522b202 (patch)
tree4c66df9c85ffa13db1352f8a3087aff895c73389 /llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
parent79e96b2457fe4e1586effc36aab657c508c122cf (diff)
downloadllvm-32db121b29f78e4c41116b2a8f1c730f9522b202.zip
llvm-32db121b29f78e4c41116b2a8f1c730f9522b202.tar.gz
llvm-32db121b29f78e4c41116b2a8f1c730f9522b202.tar.bz2
[Coverage] Allow Clang coverage to be used with debug info correlation.
Debug info correlation is an option in InstrProfiling pass, which is used by both IR instrumentation and front-end instrumentation. So, Clang coverage can also benefits the binary size saving from it. Reviewed By: ellis Differential Revision: https://reviews.llvm.org/D157913
Diffstat (limited to 'llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp')
-rw-r--r--llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp62
1 files changed, 42 insertions, 20 deletions
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index e468fbf..40ce0eb 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -25,6 +25,7 @@
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Debug.h"
@@ -1021,8 +1022,23 @@ static Expected<std::vector<SectionRef>> lookupSections(ObjectFile &OF,
return Sections;
}
+static Error getProfileNamesFromDebugInfo(StringRef FileName,
+ InstrProfSymtab &ProfileNames) {
+ std::unique_ptr<InstrProfCorrelator> Correlator;
+ if (auto E = InstrProfCorrelator::get(FileName).moveInto(Correlator))
+ return E;
+ if (auto E = Correlator->correlateCovUnusedFuncNames(0))
+ return E;
+ if (auto E = ProfileNames.create(
+ StringRef(Correlator->getCovUnusedFuncNamesPointer(),
+ Correlator->getCovUnusedFuncNamesSize())))
+ return E;
+ return Error::success();
+}
+
static Expected<std::unique_ptr<BinaryCoverageReader>>
-loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
+loadBinaryFormat(std::unique_ptr<Binary> Bin,
+ IndexedInstrProfReader &ProfileReader, StringRef Arch,
StringRef CompilationDir = "",
object::BuildIDRef *BinaryID = nullptr) {
std::unique_ptr<ObjectFile> OF;
@@ -1052,11 +1068,24 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
// Look for the sections that we are interested in.
auto ObjFormat = OF->getTripleObjectFormat();
+ InstrProfSymtab ProfileNames = ProfileReader.getSymtab();
auto NamesSection =
lookupSections(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
- /*AddSegmentInfo=*/false));
- if (auto E = NamesSection.takeError())
- return std::move(E);
+ /*AddSegmentInfo=*/false));
+ if (auto E = NamesSection.takeError()) {
+ if (OF->hasDebugInfo()) {
+ if (auto E =
+ getProfileNamesFromDebugInfo(OF->getFileName(), ProfileNames))
+ return make_error<CoverageMapError>(coveragemap_error::malformed);
+ }
+ consumeError(std::move(E));
+ } else {
+ std::vector<SectionRef> NamesSectionRefs = *NamesSection;
+ if (NamesSectionRefs.size() != 1)
+ return make_error<CoverageMapError>(coveragemap_error::malformed);
+ if (Error E = ProfileNames.create(NamesSectionRefs.back()))
+ return std::move(E);
+ }
auto CoverageSection =
lookupSections(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
/*AddSegmentInfo=*/false));
@@ -1071,15 +1100,6 @@ loadBinaryFormat(std::unique_ptr<Binary> Bin, StringRef Arch,
return CoverageMappingOrErr.takeError();
StringRef CoverageMapping = CoverageMappingOrErr.get();
- InstrProfSymtab ProfileNames;
- std::vector<SectionRef> NamesSectionRefs = *NamesSection;
- if (NamesSectionRefs.size() != 1)
- return make_error<CoverageMapError>(
- coveragemap_error::malformed,
- "the size of coverage mapping section is not one");
- if (Error E = ProfileNames.create(NamesSectionRefs.back()))
- return std::move(E);
-
// Look for the coverage records section (Version4 only).
auto CoverageRecordsSections =
lookupSections(*OF, getInstrProfSectionName(IPSK_covfun, ObjFormat,
@@ -1149,7 +1169,8 @@ static bool isArchSpecifierInvalidOrMissing(Binary *Bin, StringRef Arch) {
Expected<std::vector<std::unique_ptr<BinaryCoverageReader>>>
BinaryCoverageReader::create(
- MemoryBufferRef ObjectBuffer, StringRef Arch,
+ MemoryBufferRef ObjectBuffer, IndexedInstrProfReader &ProfileReader,
+ StringRef Arch,
SmallVectorImpl<std::unique_ptr<MemoryBuffer>> &ObjectFileBuffers,
StringRef CompilationDir, SmallVectorImpl<object::BuildIDRef> *BinaryIDs) {
std::vector<std::unique_ptr<BinaryCoverageReader>> Readers;
@@ -1195,8 +1216,8 @@ BinaryCoverageReader::create(
}
return BinaryCoverageReader::create(
- ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers,
- CompilationDir, BinaryIDs);
+ ArchiveOrErr.get()->getMemoryBufferRef(), ProfileReader, Arch,
+ ObjectFileBuffers, CompilationDir, BinaryIDs);
}
}
@@ -1209,8 +1230,8 @@ BinaryCoverageReader::create(
return ChildBufOrErr.takeError();
auto ChildReadersOrErr = BinaryCoverageReader::create(
- ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir,
- BinaryIDs);
+ ChildBufOrErr.get(), ProfileReader, Arch, ObjectFileBuffers,
+ CompilationDir, BinaryIDs);
if (!ChildReadersOrErr)
return ChildReadersOrErr.takeError();
for (auto &Reader : ChildReadersOrErr.get())
@@ -1230,8 +1251,9 @@ BinaryCoverageReader::create(
}
object::BuildIDRef BinaryID;
- auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir,
- BinaryIDs ? &BinaryID : nullptr);
+ auto ReaderOrErr =
+ loadBinaryFormat(std::move(Bin), ProfileReader, Arch, CompilationDir,
+ BinaryIDs ? &BinaryID : nullptr);
if (!ReaderOrErr)
return ReaderOrErr.takeError();
Readers.push_back(std::move(ReaderOrErr.get()));