[llvm] [llvm-cov] Option to ignore hash mismatches for non-emitted symbols (PR #97574)

Aleksa Marković via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 3 06:28:07 PDT 2024


https://github.com/ntnx-aleksa created https://github.com/llvm/llvm-project/pull/97574

Potential workaround for #72786 and #32849 
See [discussion](https://discourse.llvm.org/t/llvm-cov-hash-mismatches-originating-from-class-methods-implemented-in-header-files/79832)

>From 02e7723948fb8a56558e8a6094400fa10e57deb9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Aleksa=20Markovi=C4=87?= <aleksa.markovic at nutanix.com>
Date: Tue, 2 Jul 2024 20:35:47 +0200
Subject: [PATCH] [llvm-cov] Introduce ignore-hash-mismatch in llvm-cov

---
 .../llvm/ProfileData/Coverage/CoverageMapping.h  |  3 ++-
 llvm/include/llvm/ProfileData/InstrProfReader.h  |  9 +++++++--
 .../lib/ProfileData/Coverage/CoverageMapping.cpp |  6 ++++--
 llvm/lib/ProfileData/InstrProfReader.cpp         | 16 +++++++++++++---
 llvm/tools/llvm-cov/CodeCoverage.cpp             |  9 ++++++++-
 5 files changed, 34 insertions(+), 9 deletions(-)

diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index 5fc497db8df54..c8008e3199a17 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -973,7 +973,8 @@ class CoverageMapping {
        vfs::FileSystem &FS, ArrayRef<StringRef> Arches = std::nullopt,
        StringRef CompilationDir = "",
        const object::BuildIDFetcher *BIDFetcher = nullptr,
-       bool CheckBinaryIDs = false);
+       bool CheckBinaryIDs = false,
+       bool IgnoreEmptyHashMismatches = false);
 
   /// The number of functions that couldn't have their profiles mapped.
   ///
diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h
index 3b307d0835998..b41f9fb3eb4b3 100644
--- a/llvm/include/llvm/ProfileData/InstrProfReader.h
+++ b/llvm/include/llvm/ProfileData/InstrProfReader.h
@@ -703,6 +703,9 @@ class IndexedInstrProfReader : public InstrProfReader {
   // Index to the current record in the record array.
   unsigned RecordIndex = 0;
 
+  // Flag to ignore empty (zero-hash) mismatches
+  bool IgnoreEmptyHashMismatches = false;
+
   // Read the profile summary. Return a pointer pointing to one byte past the
   // end of the summary data if it exists or the input \c Cur.
   // \c UseCS indicates whether to use the context-sensitive profile summary.
@@ -796,11 +799,13 @@ class IndexedInstrProfReader : public InstrProfReader {
   /// Factory method to create an indexed reader.
   static Expected<std::unique_ptr<IndexedInstrProfReader>>
   create(const Twine &Path, vfs::FileSystem &FS,
-         const Twine &RemappingPath = "");
+         const Twine &RemappingPath = "",
+         bool IgnoreEmptyHashMismatches = false);
 
   static Expected<std::unique_ptr<IndexedInstrProfReader>>
   create(std::unique_ptr<MemoryBuffer> Buffer,
-         std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr);
+         std::unique_ptr<MemoryBuffer> RemappingBuffer = nullptr,
+         bool IgnoreEmptyHashMismatches = false);
 
   // Used for testing purpose only.
   void setValueProfDataEndianness(llvm::endianness Endianness) {
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 21ce0ac17d618..558d21e739a7e 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -1008,8 +1008,10 @@ Error CoverageMapping::loadFromFile(
 Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
     ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
     vfs::FileSystem &FS, ArrayRef<StringRef> Arches, StringRef CompilationDir,
-    const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs) {
-  auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename, FS);
+    const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs,
+    bool IgnoreEmptyHashMismatches) {
+  auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename, FS,
+   "" /* RemappingPath */, IgnoreEmptyHashMismatches);
   if (Error E = ProfileReaderOrErr.takeError())
     return createFileError(ProfileFilename, std::move(E));
   auto ProfileReader = std::move(ProfileReaderOrErr.get());
diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index e18ce5d373d1c..157d4a3b5754a 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -191,7 +191,8 @@ InstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer,
 
 Expected<std::unique_ptr<IndexedInstrProfReader>>
 IndexedInstrProfReader::create(const Twine &Path, vfs::FileSystem &FS,
-                               const Twine &RemappingPath) {
+                               const Twine &RemappingPath,
+                               bool IgnoreEmptyHashMismatches) {
   // Set up the buffer to read.
   auto BufferOrError = setupMemoryBuffer(Path, FS);
   if (Error E = BufferOrError.takeError())
@@ -208,12 +209,14 @@ IndexedInstrProfReader::create(const Twine &Path, vfs::FileSystem &FS,
   }
 
   return IndexedInstrProfReader::create(std::move(BufferOrError.get()),
-                                        std::move(RemappingBuffer));
+                                        std::move(RemappingBuffer),
+                                        IgnoreEmptyHashMismatches);
 }
 
 Expected<std::unique_ptr<IndexedInstrProfReader>>
 IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer,
-                               std::unique_ptr<MemoryBuffer> RemappingBuffer) {
+                               std::unique_ptr<MemoryBuffer> RemappingBuffer,
+                               bool IgnoreEmptyHashMismatches) {
   // Create the reader.
   if (!IndexedInstrProfReader::hasFormat(*Buffer))
     return make_error<InstrProfError>(instrprof_error::bad_magic);
@@ -224,6 +227,8 @@ IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer,
   if (Error E = initializeReader(*Result))
     return std::move(E);
 
+  Result->IgnoreEmptyHashMismatches = IgnoreEmptyHashMismatches;
+
   return std::move(Result);
 }
 
@@ -1501,6 +1506,11 @@ Expected<InstrProfRecord> IndexedInstrProfReader::getInstrProfRecord(
   }
   // Found it. Look for counters with the right hash.
 
+  // Ignore possible hash mismatch if hash is 0.
+  if (IgnoreEmptyHashMismatches && FuncHash == 0x0 && Data.size() == 1) {
+    return std::move(Data.front());
+  }
+
   // A flag to indicate if the records are from the same type
   // of profile (i.e cs vs nocs).
   bool CSBitMatch = false;
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index 75028ac0bb505..a786d9be9f7fc 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -193,6 +193,8 @@ class CodeCoverageTool {
   std::unique_ptr<object::BuildIDFetcher> BIDFetcher;
 
   bool CheckBinaryIDs;
+
+  bool IgnoreHashMismatch;
 };
 }
 
@@ -482,7 +484,8 @@ std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
   auto FS = vfs::getRealFileSystem();
   auto CoverageOrErr = CoverageMapping::load(
       ObjectFilenames, PGOFilename, *FS, CoverageArches,
-      ViewOpts.CompilationDirectory, BIDFetcher.get(), CheckBinaryIDs);
+      ViewOpts.CompilationDirectory, BIDFetcher.get(), CheckBinaryIDs, 
+      IgnoreHashMismatch);
   if (Error E = CoverageOrErr.takeError()) {
     error("failed to load coverage: " + toString(std::move(E)));
     return nullptr;
@@ -815,6 +818,9 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
       "check-binary-ids", cl::desc("Fail if an object couldn't be found for a "
                                    "binary ID in the profile"));
 
+  cl::opt<bool> IgnoreHashMismatch(
+      "ignore-hash-mismatch", cl::desc("Ignore hash mismatches."));
+
   auto commandLineParser = [&, this](int argc, const char **argv) -> int {
     cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n");
     ViewOpts.Debug = DebugDump;
@@ -825,6 +831,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
       BIDFetcher = std::make_unique<object::BuildIDFetcher>(DebugFileDirectory);
     }
     this->CheckBinaryIDs = CheckBinaryIDs;
+    this->IgnoreHashMismatch = IgnoreHashMismatch;
 
     if (!CovFilename.empty())
       ObjectFilenames.emplace_back(CovFilename);



More information about the llvm-commits mailing list