[llvm] 5e04432 - [PGO] Report number of counts being dropped when a hash-mismatch happens

Rong Xu via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 15 14:59:38 PDT 2022


Author: Rong Xu
Date: 2022-07-15T14:53:59-07:00
New Revision: 5e0443292bf0ee72bd17b41a8d5f85d1afecef36

URL: https://github.com/llvm/llvm-project/commit/5e0443292bf0ee72bd17b41a8d5f85d1afecef36
DIFF: https://github.com/llvm/llvm-project/commit/5e0443292bf0ee72bd17b41a8d5f85d1afecef36.diff

LOG: [PGO] Report number of counts being dropped when a hash-mismatch happens

This patch reports number of counts being dropped when a hash-mismatch
happens. This information will be helpful to the users -- if the dropped
counts are large, the user should redo the instrumentation build and
recollect the profile.

Differential Revision: https://reviews.llvm.org/D129001

Added: 
    

Modified: 
    llvm/include/llvm/ProfileData/InstrProfReader.h
    llvm/lib/ProfileData/InstrProfReader.cpp
    llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
    llvm/test/Transforms/PGOProfile/Inputs/diag.proftext
    llvm/test/Transforms/PGOProfile/diag_mismatch.ll

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h
index 3a25de05bbf1d..1d1b59bb6c469 100644
--- a/llvm/include/llvm/ProfileData/InstrProfReader.h
+++ b/llvm/include/llvm/ProfileData/InstrProfReader.h
@@ -619,9 +619,14 @@ class IndexedInstrProfReader : public InstrProfReader {
   /// Read a single record.
   Error readNextRecord(NamedInstrProfRecord &Record) override;
 
-  /// Return the NamedInstrProfRecord associated with FuncName and FuncHash
-  Expected<InstrProfRecord> getInstrProfRecord(StringRef FuncName,
-                                               uint64_t FuncHash);
+  /// Return the NamedInstrProfRecord associated with FuncName and FuncHash.
+  /// When return a hash_mismatch error and MismatchedFuncSum is not nullptr,
+  /// the sum of all counters in the mismatched function will be set to
+  /// MismatchedFuncSum. If there are multiple instances of mismatched
+  /// functions, MismatchedFuncSum returns the maximum.
+  Expected<InstrProfRecord>
+  getInstrProfRecord(StringRef FuncName, uint64_t FuncHash,
+                     uint64_t *MismatchedFuncSum = nullptr);
 
   /// Return the memprof record for the function identified by
   /// llvm::md5(Name).

diff  --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index 017b09e1c3881..23804ce604c49 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -1026,10 +1026,10 @@ InstrProfSymtab &IndexedInstrProfReader::getSymtab() {
   return *Symtab;
 }
 
-Expected<InstrProfRecord>
-IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName,
-                                           uint64_t FuncHash) {
+Expected<InstrProfRecord> IndexedInstrProfReader::getInstrProfRecord(
+    StringRef FuncName, uint64_t FuncHash, uint64_t *MismatchedFuncSum) {
   ArrayRef<NamedInstrProfRecord> Data;
+  uint64_t FuncSum = 0;
   Error Err = Remapper->getRecords(FuncName, Data);
   if (Err)
     return std::move(Err);
@@ -1038,6 +1038,19 @@ IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName,
   // A flag to indicate if the records are from the same type
   // of profile (i.e cs vs nocs).
   bool CSBitMatch = false;
+  auto getFuncSum = [](const std::vector<uint64_t> &Counts) {
+    uint64_t ValueSum = 0;
+    for (unsigned I = 0, S = Counts.size(); I < S; I++) {
+      uint64_t CountValue = Counts[I];
+      if (CountValue == (uint64_t)-1)
+        continue;
+      // Handle overflow -- if that happens, return max.
+      if (std::numeric_limits<uint64_t>::max() - CountValue <= ValueSum)
+        return std::numeric_limits<uint64_t>::max();
+      ValueSum += CountValue;
+    }
+    return ValueSum;
+  };
 
   for (const NamedInstrProfRecord &I : Data) {
     // Check for a match and fill the vector if there is one.
@@ -1046,9 +1059,14 @@ IndexedInstrProfReader::getInstrProfRecord(StringRef FuncName,
     if (NamedInstrProfRecord::hasCSFlagInHash(I.Hash) ==
         NamedInstrProfRecord::hasCSFlagInHash(FuncHash)) {
       CSBitMatch = true;
+      if (MismatchedFuncSum == nullptr)
+        continue;
+      FuncSum = std::max(FuncSum, getFuncSum(I.Counts));
     }
   }
   if (CSBitMatch) {
+    if (MismatchedFuncSum != nullptr)
+      *MismatchedFuncSum = FuncSum;
     return error(instrprof_error::hash_mismatch);
   }
   return error(instrprof_error::unknown_function);

diff  --git a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
index 751b4a413a58b..12da42da0b62e 100644
--- a/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
+++ b/llvm/lib/Transforms/Instrumentation/PGOInstrumentation.cpp
@@ -1224,8 +1224,9 @@ static void annotateFunctionWithHashMismatch(Function &F,
 bool PGOUseFunc::readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
                               bool &AllMinusOnes) {
   auto &Ctx = M->getContext();
-  Expected<InstrProfRecord> Result =
-      PGOReader->getInstrProfRecord(FuncInfo.FuncName, FuncInfo.FunctionHash);
+  uint64_t MismatchedFuncSum = 0;
+  Expected<InstrProfRecord> Result = PGOReader->getInstrProfRecord(
+      FuncInfo.FuncName, FuncInfo.FunctionHash, &MismatchedFuncSum);
   if (Error E = Result.takeError()) {
     handleAllErrors(std::move(E), [&](const InstrProfError &IPE) {
       auto Err = IPE.get();
@@ -1254,9 +1255,11 @@ bool PGOUseFunc::readCounters(IndexedInstrProfReader *PGOReader, bool &AllZeros,
       if (SkipWarning)
         return;
 
-      std::string Msg = IPE.message() + std::string(" ") + F.getName().str() +
-                        std::string(" Hash = ") +
-                        std::to_string(FuncInfo.FunctionHash);
+      std::string Msg =
+          IPE.message() + std::string(" ") + F.getName().str() +
+          std::string(" Hash = ") + std::to_string(FuncInfo.FunctionHash) +
+          std::string(" up to ") + std::to_string(MismatchedFuncSum) +
+          std::string(" count discarded");
 
       Ctx.diagnose(
           DiagnosticInfoPGOProfile(M->getName().data(), Msg, DS_Warning));

diff  --git a/llvm/test/Transforms/PGOProfile/Inputs/diag.proftext b/llvm/test/Transforms/PGOProfile/Inputs/diag.proftext
index a38d7939ebddf..40469098ad34e 100644
--- a/llvm/test/Transforms/PGOProfile/Inputs/diag.proftext
+++ b/llvm/test/Transforms/PGOProfile/Inputs/diag.proftext
@@ -5,3 +5,9 @@ foo
 1
 1
 
+foo
+12885999999
+2
+6000
+4000
+

diff  --git a/llvm/test/Transforms/PGOProfile/diag_mismatch.ll b/llvm/test/Transforms/PGOProfile/diag_mismatch.ll
index bad2a84ff269f..37648e9b5ca33 100644
--- a/llvm/test/Transforms/PGOProfile/diag_mismatch.ll
+++ b/llvm/test/Transforms/PGOProfile/diag_mismatch.ll
@@ -1,7 +1,7 @@
 ; RUN: llvm-profdata merge %S/Inputs/diag.proftext -o %t.profdata
 ; RUN: opt < %s -passes=pgo-instr-use -pgo-test-profile-file=%t.profdata -S 2>&1 | FileCheck %s
 
-; CHECK: warning: {{.+}}: function control flow change detected (hash mismatch) foo
+; CHECK: warning: {{.+}}: function control flow change detected (hash mismatch) foo Hash = 742261418966908927 up to 10000 count discarded
 
 target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"


        


More information about the llvm-commits mailing list