[PATCH] D157913: [WIP][Coverage] Allow Clang coverage to be used with debug info correlation.
zequanwu updated this revision to Diff 554048. zequanwu added a comment. __llvm_prf_names section in the binary could be non-zero because non-instrumented function names are store there to indicate execution of 0. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D157913/new/ https://reviews.llvm.org/D157913 Files: clang/lib/CodeGen/CoverageMappingGen.cpp clang/test/CodeGen/coverage-debug-info-correlate.c compiler-rt/lib/profile/InstrProfilingWriter.c compiler-rt/test/profile/Darwin/coverage-debug-info-correlate.cpp compiler-rt/test/profile/Linux/coverage-debug-info-correlate.cpp llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h llvm/include/llvm/ProfileData/InstrProf.h llvm/lib/ProfileData/Coverage/CoverageMapping.cpp llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp llvm/lib/ProfileData/InstrProfReader.cpp Index: llvm/lib/ProfileData/InstrProfReader.cpp === --- llvm/lib/ProfileData/InstrProfReader.cpp +++ llvm/lib/ProfileData/InstrProfReader.cpp @@ -574,8 +574,8 @@ if (Correlator) { // These sizes in the raw file are zero because we constructed them in the // Correlator. -assert(DataSize == 0 && NamesSize == 0); -assert(CountersDelta == 0 && NamesDelta == 0); +assert(DataSize == 0 && (!isIRLevelProfile() || NamesSize == 0)); +assert(CountersDelta == 0 && (!isIRLevelProfile() || NamesDelta == 0)); Data = Correlator->getDataPointer(); DataEnd = Data + Correlator->getDataSize(); NamesStart = Correlator->getNamesPointer(); Index: llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp === --- llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ 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" @@ -981,7 +982,8 @@ } static Expected> -loadBinaryFormat(std::unique_ptr Bin, StringRef Arch, +loadBinaryFormat(std::unique_ptr Bin, + IndexedInstrProfReader , StringRef Arch, StringRef CompilationDir = "", object::BuildIDRef *BinaryID = nullptr) { std::unique_ptr OF; @@ -1010,11 +1012,21 @@ // 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); + if (auto E = NamesSection.takeError()) { +if (ProfileNames.isEmpty()) + return std::move(E); +consumeError(std::move(E)); + } else { +std::vector NamesSectionRefs = *NamesSection; +if (NamesSectionRefs.size() != 1) + return make_error(coveragemap_error::malformed); +if (Error E = ProfileNames.create(NamesSectionRefs.back())) + return std::move(E); + } auto CoverageSection = lookupSections(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)); @@ -1028,13 +1040,6 @@ return CoverageMappingOrErr.takeError(); StringRef CoverageMapping = CoverageMappingOrErr.get(); - InstrProfSymtab ProfileNames; - std::vector NamesSectionRefs = *NamesSection; - if (NamesSectionRefs.size() != 1) -return make_error(coveragemap_error::malformed); - 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, @@ -1104,7 +1109,8 @@ Expected>> BinaryCoverageReader::create( -MemoryBufferRef ObjectBuffer, StringRef Arch, +MemoryBufferRef ObjectBuffer, IndexedInstrProfReader , +StringRef Arch, SmallVectorImpl> , StringRef CompilationDir, SmallVectorImpl *BinaryIDs) { std::vector> Readers; @@ -1150,8 +1156,8 @@ } return BinaryCoverageReader::create( - ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers, - CompilationDir, BinaryIDs); + ArchiveOrErr.get()->getMemoryBufferRef(), ProfileReader, Arch, + ObjectFileBuffers, CompilationDir, BinaryIDs); } } @@ -1164,8 +1170,8 @@ return ChildBufOrErr.takeError(); auto ChildReadersOrErr = BinaryCoverageReader::create( - ChildBufOrErr.get(), Arch, ObjectFileBuffers, CompilationDir, - BinaryIDs); + ChildBufOrErr.get(),
[PATCH] D157913: [WIP][Coverage] Allow Clang coverage to be used with debug info correlation.
zequanwu updated this revision to Diff 551219. zequanwu added a comment. Update. Binary may still contains __llvm_prf_names sections for functions that are not emitted. Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D157913/new/ https://reviews.llvm.org/D157913 Files: clang/lib/CodeGen/CoverageMappingGen.cpp clang/test/CodeGen/coverage-debug-info-correlate.c compiler-rt/test/profile/Darwin/coverage-debug-info-correlate.c compiler-rt/test/profile/Linux/coverage-debug-info-correlate.c llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h llvm/lib/ProfileData/Coverage/CoverageMapping.cpp llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp Index: llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp === --- llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ 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" @@ -953,7 +954,8 @@ } static Expected> -loadBinaryFormat(std::unique_ptr Bin, StringRef Arch, +loadBinaryFormat(std::unique_ptr Bin, + IndexedInstrProfReader , StringRef Arch, StringRef CompilationDir = "", object::BuildIDRef *BinaryID = nullptr) { std::unique_ptr OF; @@ -982,11 +984,21 @@ // 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); + if (auto E = NamesSection.takeError()) { +if (ProfileNames.getNameData().empty()) + return std::move(E); +consumeError(std::move(E)); + } else { +std::vector NamesSectionRefs = *NamesSection; +if (NamesSectionRefs.size() != 1) + return make_error(coveragemap_error::malformed); +if (Error E = ProfileNames.create(NamesSectionRefs.back())) + return std::move(E); + } auto CoverageSection = lookupSections(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)); @@ -1000,13 +1012,6 @@ return CoverageMappingOrErr.takeError(); StringRef CoverageMapping = CoverageMappingOrErr.get(); - InstrProfSymtab ProfileNames; - std::vector NamesSectionRefs = *NamesSection; - if (NamesSectionRefs.size() != 1) -return make_error(coveragemap_error::malformed); - 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, @@ -1076,7 +1081,8 @@ Expected>> BinaryCoverageReader::create( -MemoryBufferRef ObjectBuffer, StringRef Arch, +MemoryBufferRef ObjectBuffer, IndexedInstrProfReader , +StringRef Arch, SmallVectorImpl> , StringRef CompilationDir, SmallVectorImpl *BinaryIDs) { std::vector> Readers; @@ -1117,8 +1123,8 @@ } return BinaryCoverageReader::create( - ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers, - CompilationDir, BinaryIDs); + ArchiveOrErr.get()->getMemoryBufferRef(), ProfileReader, Arch, + ObjectFileBuffers, CompilationDir, BinaryIDs); } } @@ -1131,8 +1137,8 @@ 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 : ChildReadersOrErr.get()) @@ -1152,8 +1158,9 @@ } object::BuildIDRef BinaryID; - auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir, - BinaryIDs ? : nullptr); + auto ReaderOrErr = + loadBinaryFormat(std::move(Bin), ProfileReader, Arch, CompilationDir, + BinaryIDs ? : nullptr); if (!ReaderOrErr) return ReaderOrErr.takeError(); Readers.push_back(std::move(ReaderOrErr.get())); Index: llvm/lib/ProfileData/Coverage/CoverageMapping.cpp === --- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -360,7 +360,7 @@
[PATCH] D157913: [WIP][Coverage] Allow Clang coverage to be used with debug info correlation.
zequanwu created this revision. Herald added subscribers: Enna1, hiraditya. Herald added a project: All. zequanwu requested review of this revision. Herald added projects: clang, Sanitizers, LLVM. Herald added subscribers: llvm-commits, Sanitizers, cfe-commits. 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. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D157913 Files: clang/lib/CodeGen/CoverageMappingGen.cpp clang/test/CodeGen/coverage-debug-info-correlate.c compiler-rt/test/profile/Darwin/coverage-debug-info-correlate.c compiler-rt/test/profile/Linux/coverage-debug-info-correlate.c llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h llvm/lib/ProfileData/Coverage/CoverageMapping.cpp llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp Index: llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp === --- llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ 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" @@ -953,7 +954,8 @@ } static Expected> -loadBinaryFormat(std::unique_ptr Bin, StringRef Arch, +loadBinaryFormat(std::unique_ptr Bin, + IndexedInstrProfReader , StringRef Arch, StringRef CompilationDir = "", object::BuildIDRef *BinaryID = nullptr) { std::unique_ptr OF; @@ -982,11 +984,20 @@ // Look for the sections that we are interested in. auto ObjFormat = OF->getTripleObjectFormat(); + InstrProfSymtab ProfileNames; auto NamesSection = lookupSections(*OF, getInstrProfSectionName(IPSK_name, ObjFormat, /*AddSegmentInfo=*/false)); - if (auto E = NamesSection.takeError()) -return std::move(E); + if (auto E = NamesSection.takeError()) { +consumeError(std::move(E)); +ProfileNames = ProfileReader.getSymtab(); + } else { +std::vector NamesSectionRefs = *NamesSection; +if (NamesSectionRefs.size() != 1) + return make_error(coveragemap_error::malformed); +if (Error E = ProfileNames.create(NamesSectionRefs.back())) + return std::move(E); + } auto CoverageSection = lookupSections(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat, /*AddSegmentInfo=*/false)); @@ -1000,13 +1011,6 @@ return CoverageMappingOrErr.takeError(); StringRef CoverageMapping = CoverageMappingOrErr.get(); - InstrProfSymtab ProfileNames; - std::vector NamesSectionRefs = *NamesSection; - if (NamesSectionRefs.size() != 1) -return make_error(coveragemap_error::malformed); - 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, @@ -1076,7 +1080,8 @@ Expected>> BinaryCoverageReader::create( -MemoryBufferRef ObjectBuffer, StringRef Arch, +MemoryBufferRef ObjectBuffer, IndexedInstrProfReader , +StringRef Arch, SmallVectorImpl> , StringRef CompilationDir, SmallVectorImpl *BinaryIDs) { std::vector> Readers; @@ -1117,8 +1122,8 @@ } return BinaryCoverageReader::create( - ArchiveOrErr.get()->getMemoryBufferRef(), Arch, ObjectFileBuffers, - CompilationDir, BinaryIDs); + ArchiveOrErr.get()->getMemoryBufferRef(), ProfileReader, Arch, + ObjectFileBuffers, CompilationDir, BinaryIDs); } } @@ -1131,8 +1136,8 @@ 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 : ChildReadersOrErr.get()) @@ -1152,8 +1157,9 @@ } object::BuildIDRef BinaryID; - auto ReaderOrErr = loadBinaryFormat(std::move(Bin), Arch, CompilationDir, - BinaryIDs ? : nullptr); + auto ReaderOrErr = + loadBinaryFormat(std::move(Bin), ProfileReader, Arch, CompilationDir, + BinaryIDs ? : nullptr); if (!ReaderOrErr) return ReaderOrErr.takeError(); Readers.push_back(std::move(ReaderOrErr.get())); Index: llvm/lib/ProfileData/Coverage/CoverageMapping.cpp