[llvm] [compiler-rt] [Profile] Allow profile merging with multiple correlate files. (PR #75957)

via llvm-commits llvm-commits at lists.llvm.org
Tue Dec 19 09:52:54 PST 2023


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-pgo

Author: Zequan Wu (ZequanWu)

<details>
<summary>Changes</summary>

This allows llvm-profdata to merge lightweight raw profiles with multiple correlate files and associate lightweight raw profiles with correlate files using binary id. For correlate files without binary id, it will be used for lightweight raw profiles without binary id as well.

This doesn't support the following:
1. Merging raw profile that is generated by a binary which linked with objects with mixed correlation modes. This is because the binary has only one binary id and it can only be used either for debug info correlation or binary correlation, not both.
2. Merging raw profile that is generated by a statically linked binary which has some objects compiled with correlation and some without correlation. This is because it will generate a raw profile with data and name info for some counters but not all. The rest counters need data and name info from correlation files, which is hard to differentiate those two kinds of counter.

---

Patch is 46.84 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/75957.diff


8 Files Affected:

- (added) compiler-rt/test/profile/Linux/instrprof-correlation-mixed.test (+33) 
- (modified) compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c (+19) 
- (modified) llvm/include/llvm/ProfileData/InstrProfCorrelator.h (+98-26) 
- (modified) llvm/include/llvm/ProfileData/InstrProfReader.h (+8-9) 
- (modified) llvm/lib/Object/BuildID.cpp (+18) 
- (modified) llvm/lib/ProfileData/InstrProfCorrelator.cpp (+119-45) 
- (modified) llvm/lib/ProfileData/InstrProfReader.cpp (+17-9) 
- (modified) llvm/tools/llvm-profdata/llvm-profdata.cpp (+46-38) 


``````````diff
diff --git a/compiler-rt/test/profile/Linux/instrprof-correlation-mixed.test b/compiler-rt/test/profile/Linux/instrprof-correlation-mixed.test
new file mode 100644
index 00000000000000..8cc4611eec4f0b
--- /dev/null
+++ b/compiler-rt/test/profile/Linux/instrprof-correlation-mixed.test
@@ -0,0 +1,33 @@
+// REQUIRES: lld-available
+// Test llvm-profdata merging with multiple correlation files mixing different correlation modes.
+
+// RUN: %clang_pgogen -o %t.normal -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp %S/../Inputs/instrprof-debug-info-correlate-foo.cpp
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t.normal
+// RUN: llvm-profdata merge -o %t.normal.profdata %t.profraw
+
+// Compiling with differnt configs.
+// RUN: %clang_pgogen -o %t -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp -c -o %t-main.o
+// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp -c -o %t-main.debug.o
+// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-foo.cpp -fpic -shared -Wl,--build-id -o %t-libfoo.debug.so
+// RUN: %clang_pgogen -o %t -mllvm -profile-correlate=binary -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-foo.cpp -fpic -shared -Wl,--build-id -o %t-libfoo.binary.so
+
+// Test mixing default raw profile and lightweight raw profile generated with debug info correlate.
+// The raw profiles are mixed in %t.proflite.
+// RUN: %clang_pgogen -o %t %t-main.o %t-libfoo.debug.so -Wl,--build-id -o %t
+// RUN: env LLVM_PROFILE_FILE=%t.proflite %run %t
+// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t-libfoo.debug.so %t.proflite
+// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata)
+// Two separate raw profiles.
+// RUN: rm -rf %t.dir && mkdir %t.dir
+// RUN: env LLVM_PROFILE_FILE=%t.dir/raw%m.proflite %run %t
+// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t-libfoo.debug.so %t.dir
+// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata)
+
+// Test lightweight raw profiles generated with debug info correlate and binary correlate.
+// Note we can not mix different correlation modes in static linking because when merging, the same correlate file can not be used for more than one correaltion mode.
+// Two separate lightweight raw profiles.
+// RUN: %clang_pgogen -o %t -g %t-main.debug.o %t-libfoo.binary.so -Wl,--build-id -o %t
+// RUN: rm -rf %t.dir && mkdir %t.dir
+// RUN: env LLVM_PROFILE_FILE=%t.dir/raw%m.proflite %run %t
+// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t --binary-file=%t-libfoo.binary.so %t.dir
+// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata)
diff --git a/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c b/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c
index a918d7b6299005..af19101f91a2f1 100644
--- a/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c
+++ b/compiler-rt/test/profile/Linux/instrprof-debug-info-correlate.c
@@ -25,6 +25,25 @@
 
 // RUN: diff <(llvm-profdata show --all-functions --counts %t.cov.normal.profdata) <(llvm-profdata show --all-functions --counts %t.cov.profdata)
 
+// Test debug info correlate with build id.
+
+// Both binaries are built with build id.
+// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-foo.cpp -c -fpic -shared -Wl,--build-id -o %t-libfoo.so
+// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp %t-libfoo.so -Wl,--build-id -o %t
+// RUN: env LLVM_PROFILE_FILE=%t.proflite %run %t
+// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t,%t-libfoo.so %t.proflite
+// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata)
+
+// One binary is built without build id.
+// RUN: %clang_pgogen -o %t -g -mllvm --debug-info-correlate -mllvm --disable-vp=true %S/../Inputs/instrprof-debug-info-correlate-main.cpp %t-libfoo.so -o %t
+// RUN: env LLVM_PROFILE_FILE=%t.proflite %run %t
+// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t,%t-libfoo.so %t.proflite
+// RUN: diff <(llvm-profdata show --all-functions --counts %t.normal.profdata) <(llvm-profdata show --all-functions --counts %t.profdata)
+
+// Warning about multiple correlate files have the same build id.
+// RUN: llvm-profdata merge -o %t.profdata --debug-info=%t,%t,%t-libfoo.o %t.proflite 2>&1 >/dev/null | FileCheck %s --check-prefix=WARN
+// WARN: Duplicate build id ({{.*}}) found for {{.*}} and {{.*}}
+
 // Test debug info correlate with online merging.
 
 // RUN: env LLVM_PROFILE_FILE=%t-1.profraw %run %t.normal
diff --git a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
index c07c67d287e2ce..1b579e0ac2fd24 100644
--- a/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
+++ b/llvm/include/llvm/ProfileData/InstrProfCorrelator.h
@@ -13,6 +13,7 @@
 #define LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
 
 #include "llvm/ADT/DenseSet.h"
+#include "llvm/Object/BuildID.h"
 #include "llvm/ProfileData/InstrProf.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -35,20 +36,33 @@ class InstrProfCorrelator {
   /// correlate.
   enum ProfCorrelatorKind { NONE, DEBUG_INFO, BINARY };
 
+  struct AtomicWarningCounter {
+    AtomicWarningCounter(uint64_t MaxWarnings)
+        : MaxWarnings(MaxWarnings), WarningCount(0){};
+    bool shouldEmitWarning();
+    ~AtomicWarningCounter();
+
+  private:
+    const uint64_t MaxWarnings;
+    std::atomic<uint64_t> WarningCount;
+  };
+
   static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
-  get(StringRef Filename, ProfCorrelatorKind FileKind);
+  get(StringRef Filename, ProfCorrelatorKind FileKind,
+      std::mutex &CorrelateLock, std::mutex &WarnLock,
+      AtomicWarningCounter *WarnCounter);
 
   /// Construct a ProfileData vector used to correlate raw instrumentation data
   /// to their functions.
-  /// \param MaxWarnings the maximum number of warnings to emit (0 = no limit)
-  virtual Error correlateProfileData(int MaxWarnings) = 0;
+  virtual Error correlateProfileData() = 0;
 
   /// Process debug info and dump the correlation data.
-  /// \param MaxWarnings the maximum number of warnings to emit (0 = no limit)
-  virtual Error dumpYaml(int MaxWarnings, raw_ostream &OS) = 0;
+  virtual Error dumpYaml(raw_ostream &OS) = 0;
+
+  virtual const char *getDataPointer() const = 0;
 
   /// Return the number of ProfileData elements.
-  std::optional<size_t> getDataSize() const;
+  size_t getDataSize() const;
 
   /// Return a pointer to the names string that this class constructs.
   const char *getNamesPointer() const { return Names.c_str(); }
@@ -61,6 +75,8 @@ class InstrProfCorrelator {
     return Ctx->CountersSectionEnd - Ctx->CountersSectionStart;
   }
 
+  object::BuildIDRef getBuildID() const { return Ctx->BuildID; }
+
   static const char *FunctionNameAttributeName;
   static const char *CFGHashAttributeName;
   static const char *NumCountersAttributeName;
@@ -84,16 +100,25 @@ class InstrProfCorrelator {
     const char *DataEnd;
     const char *NameStart;
     size_t NameSize;
+    object::BuildIDRef BuildID;
     /// True if target and host have different endian orders.
     bool ShouldSwapBytes;
   };
   const std::unique_ptr<Context> Ctx;
 
-  InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr<Context> Ctx)
-      : Ctx(std::move(Ctx)), Kind(K) {}
+  InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr<Context> Ctx,
+                      std::mutex &CorrelateLock, std::mutex &WarnLock,
+                      AtomicWarningCounter *WarnCounter)
+      : Ctx(std::move(Ctx)), IsCorrelated(false), CorrelateLock(CorrelateLock),
+        WarnLock(WarnLock), WarnCounter(WarnCounter), Kind(K) {}
 
   std::string Names;
-  std::vector<std::string> NamesVec;
+  /// True if correlation is already done.
+  bool IsCorrelated;
+  std::mutex &CorrelateLock;
+  std::mutex &WarnLock;
+
+  bool shouldEmitWarning();
 
   struct Probe {
     std::string FunctionName;
@@ -115,8 +140,11 @@ class InstrProfCorrelator {
 
 private:
   static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
-  get(std::unique_ptr<MemoryBuffer> Buffer, ProfCorrelatorKind FileKind);
+  get(std::unique_ptr<MemoryBuffer> Buffer, ProfCorrelatorKind FileKind,
+      std::mutex &CorrelateLock, std::mutex &WarnLock,
+      AtomicWarningCounter *WarnCounter);
 
+  AtomicWarningCounter *WarnCounter;
   const InstrProfCorrelatorKind Kind;
 };
 
@@ -125,13 +153,15 @@ class InstrProfCorrelator {
 template <class IntPtrT>
 class InstrProfCorrelatorImpl : public InstrProfCorrelator {
 public:
-  InstrProfCorrelatorImpl(std::unique_ptr<InstrProfCorrelator::Context> Ctx);
+  InstrProfCorrelatorImpl(std::unique_ptr<InstrProfCorrelator::Context> Ctx,
+                          std::mutex &CorrelateLock, std::mutex &WarnLock,
+                          AtomicWarningCounter *WarnCounter);
   static bool classof(const InstrProfCorrelator *C);
 
   /// Return a pointer to the underlying ProfileData vector that this class
   /// constructs.
-  const RawInstrProf::ProfileData<IntPtrT> *getDataPointer() const {
-    return Data.empty() ? nullptr : Data.data();
+  const char *getDataPointer() const override {
+    return Data.empty() ? nullptr : (const char *)Data.data();
   }
 
   /// Return the number of ProfileData elements.
@@ -139,19 +169,20 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
 
   static llvm::Expected<std::unique_ptr<InstrProfCorrelatorImpl<IntPtrT>>>
   get(std::unique_ptr<InstrProfCorrelator::Context> Ctx,
-      const object::ObjectFile &Obj, ProfCorrelatorKind FileKind);
+      const object::ObjectFile &Obj, ProfCorrelatorKind FileKind,
+      std::mutex &CorrelateLock, std::mutex &WarnLock,
+      AtomicWarningCounter *WarnCounter);
 
 protected:
   std::vector<RawInstrProf::ProfileData<IntPtrT>> Data;
 
-  Error correlateProfileData(int MaxWarnings) override;
+  Error correlateProfileData() override;
   virtual void correlateProfileDataImpl(
-      int MaxWarnings,
       InstrProfCorrelator::CorrelationData *Data = nullptr) = 0;
 
   virtual Error correlateProfileNameImpl() = 0;
 
-  Error dumpYaml(int MaxWarnings, raw_ostream &OS) override;
+  Error dumpYaml(raw_ostream &OS) override;
 
   void addDataProbe(uint64_t FunctionName, uint64_t CFGHash,
                     IntPtrT CounterOffset, IntPtrT FunctionPtr,
@@ -164,8 +195,11 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
 
 private:
   InstrProfCorrelatorImpl(InstrProfCorrelatorKind Kind,
-                          std::unique_ptr<InstrProfCorrelator::Context> Ctx)
-      : InstrProfCorrelator(Kind, std::move(Ctx)){};
+                          std::unique_ptr<InstrProfCorrelator::Context> Ctx,
+                          std::mutex &CorrelateLock, std::mutex &WarnLock,
+                          AtomicWarningCounter *WarnCounter)
+      : InstrProfCorrelator(Kind, std::move(Ctx), CorrelateLock, WarnLock,
+                            WarnCounter){};
   llvm::DenseSet<IntPtrT> CounterOffsets;
 };
 
@@ -174,13 +208,18 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
 template <class IntPtrT>
 class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
 public:
-  DwarfInstrProfCorrelator(std::unique_ptr<DWARFContext> DICtx,
-                           std::unique_ptr<InstrProfCorrelator::Context> Ctx)
-      : InstrProfCorrelatorImpl<IntPtrT>(std::move(Ctx)),
+  DwarfInstrProfCorrelator(
+      std::unique_ptr<DWARFContext> DICtx,
+      std::unique_ptr<InstrProfCorrelator::Context> Ctx,
+      std::mutex &CorrelateLock, std::mutex &WarnLock,
+      InstrProfCorrelator::AtomicWarningCounter *WarnCounter)
+      : InstrProfCorrelatorImpl<IntPtrT>(std::move(Ctx), CorrelateLock,
+                                         WarnLock, WarnCounter),
         DICtx(std::move(DICtx)) {}
 
 private:
   std::unique_ptr<DWARFContext> DICtx;
+  std::vector<std::string> NamesVec;
 
   /// Return the address of the object that the provided DIE symbolizes.
   std::optional<uint64_t> getLocation(const DWARFDie &Die) const;
@@ -217,7 +256,6 @@ class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
   /// \param MaxWarnings the maximum number of warnings to emit (0 = no limit)
   /// \param Data if provided, populate with the correlation data found
   void correlateProfileDataImpl(
-      int MaxWarnings,
       InstrProfCorrelator::CorrelationData *Data = nullptr) override;
 
   Error correlateProfileNameImpl() override;
@@ -228,8 +266,12 @@ class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
 template <class IntPtrT>
 class BinaryInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
 public:
-  BinaryInstrProfCorrelator(std::unique_ptr<InstrProfCorrelator::Context> Ctx)
-      : InstrProfCorrelatorImpl<IntPtrT>(std::move(Ctx)) {}
+  BinaryInstrProfCorrelator(
+      std::unique_ptr<InstrProfCorrelator::Context> Ctx,
+      std::mutex &CorrelateLock, std::mutex &WarnLock,
+      InstrProfCorrelator::AtomicWarningCounter *WarnCounter)
+      : InstrProfCorrelatorImpl<IntPtrT>(std::move(Ctx), CorrelateLock,
+                                         WarnLock, WarnCounter) {}
 
   /// Return a pointer to the names string that this class constructs.
   const char *getNamesPointer() const { return this->Ctx.NameStart; }
@@ -239,12 +281,42 @@ class BinaryInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
 
 private:
   void correlateProfileDataImpl(
-      int MaxWarnings,
       InstrProfCorrelator::CorrelationData *Data = nullptr) override;
 
   Error correlateProfileNameImpl() override;
 };
 
+// InstrProfCorrelators contains a map from BuildID to InstrProfCorrelator and
+// correlate profile on-demand when users call getCorrelator.
+class InstrProfCorrelators {
+public:
+  static llvm::Expected<std::unique_ptr<InstrProfCorrelators>>
+  get(ArrayRef<std::pair<StringRef, InstrProfCorrelator::ProfCorrelatorKind>>
+          CorrelateInputs,
+      uint32_t MaxWarnings);
+
+  InstrProfCorrelators(
+      StringMap<std::unique_ptr<InstrProfCorrelator>> &&CorrelatorMap,
+      std::unique_ptr<std::mutex> CorrelateLock,
+      std::unique_ptr<std::mutex> WarnLock,
+      std::unique_ptr<InstrProfCorrelator::AtomicWarningCounter> WarnCounter)
+      : CorrelatorMap(std::move(CorrelatorMap)),
+        CorrelateLock(std::move(CorrelateLock)), WarnLock(std::move(WarnLock)),
+        WarnCounter(std::move(WarnCounter)) {}
+
+  llvm::Expected<const InstrProfCorrelator *>
+  getCorrelator(object::BuildIDRef BuildID) const;
+
+  bool empty() const { return CorrelatorMap.empty(); }
+  Error dumpYaml(raw_ostream &OS);
+
+private:
+  // A map from BuildID to correlator.
+  const StringMap<std::unique_ptr<InstrProfCorrelator>> CorrelatorMap;
+  std::unique_ptr<std::mutex> CorrelateLock;
+  std::unique_ptr<std::mutex> WarnLock;
+  std::unique_ptr<InstrProfCorrelator::AtomicWarningCounter> WarnCounter;
+};
 } // end namespace llvm
 
 #endif // LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h
index ff50dfde0e7938..c7810c8b1af50c 100644
--- a/llvm/include/llvm/ProfileData/InstrProfReader.h
+++ b/llvm/include/llvm/ProfileData/InstrProfReader.h
@@ -199,12 +199,12 @@ class InstrProfReader {
   /// instrprof file.
   static Expected<std::unique_ptr<InstrProfReader>>
   create(const Twine &Path, vfs::FileSystem &FS,
-         const InstrProfCorrelator *Correlator = nullptr,
+         const InstrProfCorrelators *Correlators = nullptr,
          std::function<void(Error)> Warn = nullptr);
 
   static Expected<std::unique_ptr<InstrProfReader>>
   create(std::unique_ptr<MemoryBuffer> Buffer,
-         const InstrProfCorrelator *Correlator = nullptr,
+         const InstrProfCorrelators *Correlators = nullptr,
          std::function<void(Error)> Warn = nullptr);
 
   /// \param Weight for raw profiles use this as the temporal profile trace
@@ -313,7 +313,8 @@ class RawInstrProfReader : public InstrProfReader {
   std::unique_ptr<MemoryBuffer> DataBuffer;
   /// If available, this hold the ProfileData array used to correlate raw
   /// instrumentation data to their functions.
-  const InstrProfCorrelatorImpl<IntPtrT> *Correlator;
+  const InstrProfCorrelators *Correlators;
+  bool IsCorrelatorUsed;
   /// A list of timestamps paired with a function name reference.
   std::vector<std::pair<uint64_t, uint64_t>> TemporalProfTimestamps;
   bool ShouldSwapBytes;
@@ -346,11 +347,9 @@ class RawInstrProfReader : public InstrProfReader {
 
 public:
   RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer,
-                     const InstrProfCorrelator *Correlator,
+                     const InstrProfCorrelators *Correlator,
                      std::function<void(Error)> Warn)
-      : DataBuffer(std::move(DataBuffer)),
-        Correlator(dyn_cast_or_null<const InstrProfCorrelatorImpl<IntPtrT>>(
-            Correlator)),
+      : DataBuffer(std::move(DataBuffer)), Correlators((Correlator)),
         Warn(Warn) {}
   RawInstrProfReader(const RawInstrProfReader &) = delete;
   RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;
@@ -434,8 +433,8 @@ class RawInstrProfReader : public InstrProfReader {
   bool atEnd() const { return Data == DataEnd; }
 
   void advanceData() {
-    // `CountersDelta` is a constant zero when using debug info correlation.
-    if (!Correlator) {
+    // `CountersDelta` is a constant zero when using correlation.
+    if (!IsCorrelatorUsed) {
       // The initial CountersDelta is the in-memory address difference between
       // the data and counts sections:
       // start(__llvm_prf_cnts) - start(__llvm_prf_data)
diff --git a/llvm/lib/Object/BuildID.cpp b/llvm/lib/Object/BuildID.cpp
index ef21458060abd6..363d2d379e9aa3 100644
--- a/llvm/lib/Object/BuildID.cpp
+++ b/llvm/lib/Object/BuildID.cpp
@@ -14,6 +14,7 @@
 
 #include "llvm/Object/BuildID.h"
 
+#include "llvm/Object/COFF.h"
 #include "llvm/Object/ELFObjectFile.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/Path.h"
@@ -42,6 +43,21 @@ template <typename ELFT> BuildIDRef getBuildID(const ELFFile<ELFT> &Obj) {
   return {};
 }
 
+BuildIDRef getBuildID(const COFFObjectFile *Obj) {
+  for (const debug_directory &D : Obj->debug_directories()) {
+    if (D.AddressOfRawData == 0 || D.Type != COFF::IMAGE_DEBUG_TYPE_CODEVIEW)
+      continue;
+    const codeview::DebugInfo *DebugInfo;
+    StringRef PDBFileName;
+    if (Error E = Obj->getDebugPDBInfo(&D, DebugInfo, PDBFileName))
+      consumeError(std::move(E));
+    if (DebugInfo->Signature.CVSignature == OMF::Signature::PDB70)
+      return ArrayRef(DebugInfo->PDB70.Signature,
+                      sizeof(DebugInfo->PDB70.Signature));
+  }
+  return {};
+}
+
 } // namespace
 
 BuildID llvm::object::parseBuildID(StringRef Str) {
@@ -62,6 +78,8 @@ BuildIDRef llvm::object::getBuildID(const ObjectFile *Obj) {
     return ::getBuildID(O->getELFFile());
   if (auto *O = dyn_cast<ELFObjectFile<ELF64BE>>(Obj))
     return ::getBuildID(O->getELFFile());
+  if (auto *O = dyn_cast<COFFObjectFile>(Obj))
+    return ::getBuildID(O);
   return std::nullopt;
 }
 
diff --git a/llvm/lib/ProfileData/InstrProfCorrelator.cpp b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
index cf80a58f43bd90..edd38fdcf9c446 100644
--- a/llvm/lib/ProfileData/InstrProfCorrelator.cpp
+++ b/llvm/lib/ProfileData/InstrProfCorrelator.cpp
@@ -52,6 +52,18 @@ const char *InstrProfCorrelator::FunctionNameAttributeName = "Function Name";
 const char *InstrProfCorrelator::CFGHashAttributeName = "CFG Hash";
 const char *InstrProfCorrelator::NumCountersAttributeName = "Num Counters";
 
+bool InstrProfCorrelator::AtomicWarningCounter::shouldEmitWarning() {
+  return MaxWarnings == 0 ||
+         WarningCount.fetch_add(1, std::memory_order_relaxe...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/75957


More information about the llvm-commits mailing list