Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- InstrProfCorrelator.h ------------------------------------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. // This file defines InstrProfCorrelator used to generate PGO profiles from
  9. // raw profile data and debug info.
  10. //===----------------------------------------------------------------------===//
  11.  
  12. #ifndef LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
  13. #define LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
  14.  
  15. #include "llvm/ADT/DenseSet.h"
  16. #include "llvm/ProfileData/InstrProf.h"
  17. #include "llvm/Support/Error.h"
  18. #include "llvm/Support/MemoryBuffer.h"
  19. #include "llvm/Support/YAMLTraits.h"
  20. #include <optional>
  21. #include <vector>
  22.  
  23. namespace llvm {
  24. class DWARFContext;
  25. class DWARFDie;
  26. namespace object {
  27. class ObjectFile;
  28. }
  29.  
  30. /// InstrProfCorrelator - A base class used to create raw instrumentation data
  31. /// to their functions.
  32. class InstrProfCorrelator {
  33. public:
  34.   static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
  35.   get(StringRef DebugInfoFilename);
  36.  
  37.   /// Construct a ProfileData vector used to correlate raw instrumentation data
  38.   /// to their functions.
  39.   virtual Error correlateProfileData() = 0;
  40.  
  41.   /// Process debug info and dump the correlation data.
  42.   virtual Error dumpYaml(raw_ostream &OS) = 0;
  43.  
  44.   /// Return the number of ProfileData elements.
  45.   std::optional<size_t> getDataSize() const;
  46.  
  47.   /// Return a pointer to the names string that this class constructs.
  48.   const char *getNamesPointer() const { return Names.c_str(); }
  49.  
  50.   /// Return the number of bytes in the names string.
  51.   size_t getNamesSize() const { return Names.size(); }
  52.  
  53.   /// Return the size of the counters section in bytes.
  54.   uint64_t getCountersSectionSize() const {
  55.     return Ctx->CountersSectionEnd - Ctx->CountersSectionStart;
  56.   }
  57.  
  58.   static const char *FunctionNameAttributeName;
  59.   static const char *CFGHashAttributeName;
  60.   static const char *NumCountersAttributeName;
  61.  
  62.   enum InstrProfCorrelatorKind { CK_32Bit, CK_64Bit };
  63.   InstrProfCorrelatorKind getKind() const { return Kind; }
  64.   virtual ~InstrProfCorrelator() = default;
  65.  
  66. protected:
  67.   struct Context {
  68.     static llvm::Expected<std::unique_ptr<Context>>
  69.     get(std::unique_ptr<MemoryBuffer> Buffer, const object::ObjectFile &Obj);
  70.     std::unique_ptr<MemoryBuffer> Buffer;
  71.     /// The address range of the __llvm_prf_cnts section.
  72.     uint64_t CountersSectionStart;
  73.     uint64_t CountersSectionEnd;
  74.     /// True if target and host have different endian orders.
  75.     bool ShouldSwapBytes;
  76.   };
  77.   const std::unique_ptr<Context> Ctx;
  78.  
  79.   InstrProfCorrelator(InstrProfCorrelatorKind K, std::unique_ptr<Context> Ctx)
  80.       : Ctx(std::move(Ctx)), Kind(K) {}
  81.  
  82.   std::string Names;
  83.   std::vector<std::string> NamesVec;
  84.  
  85.   struct Probe {
  86.     std::string FunctionName;
  87.     std::optional<std::string> LinkageName;
  88.     yaml::Hex64 CFGHash;
  89.     yaml::Hex64 CounterOffset;
  90.     uint32_t NumCounters;
  91.     std::optional<std::string> FilePath;
  92.     std::optional<int> LineNumber;
  93.   };
  94.  
  95.   struct CorrelationData {
  96.     std::vector<Probe> Probes;
  97.   };
  98.  
  99.   friend struct yaml::MappingTraits<Probe>;
  100.   friend struct yaml::SequenceElementTraits<Probe>;
  101.   friend struct yaml::MappingTraits<CorrelationData>;
  102.  
  103. private:
  104.   static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
  105.   get(std::unique_ptr<MemoryBuffer> Buffer);
  106.  
  107.   const InstrProfCorrelatorKind Kind;
  108. };
  109.  
  110. /// InstrProfCorrelatorImpl - A child of InstrProfCorrelator with a template
  111. /// pointer type so that the ProfileData vector can be materialized.
  112. template <class IntPtrT>
  113. class InstrProfCorrelatorImpl : public InstrProfCorrelator {
  114. public:
  115.   InstrProfCorrelatorImpl(std::unique_ptr<InstrProfCorrelator::Context> Ctx);
  116.   static bool classof(const InstrProfCorrelator *C);
  117.  
  118.   /// Return a pointer to the underlying ProfileData vector that this class
  119.   /// constructs.
  120.   const RawInstrProf::ProfileData<IntPtrT> *getDataPointer() const {
  121.     return Data.empty() ? nullptr : Data.data();
  122.   }
  123.  
  124.   /// Return the number of ProfileData elements.
  125.   size_t getDataSize() const { return Data.size(); }
  126.  
  127.   static llvm::Expected<std::unique_ptr<InstrProfCorrelatorImpl<IntPtrT>>>
  128.   get(std::unique_ptr<InstrProfCorrelator::Context> Ctx,
  129.       const object::ObjectFile &Obj);
  130.  
  131. protected:
  132.   std::vector<RawInstrProf::ProfileData<IntPtrT>> Data;
  133.  
  134.   Error correlateProfileData() override;
  135.   virtual void correlateProfileDataImpl(
  136.       InstrProfCorrelator::CorrelationData *Data = nullptr) = 0;
  137.  
  138.   Error dumpYaml(raw_ostream &OS) override;
  139.  
  140.   void addProbe(StringRef FunctionName, uint64_t CFGHash, IntPtrT CounterOffset,
  141.                 IntPtrT FunctionPtr, uint32_t NumCounters);
  142.  
  143. private:
  144.   InstrProfCorrelatorImpl(InstrProfCorrelatorKind Kind,
  145.                           std::unique_ptr<InstrProfCorrelator::Context> Ctx)
  146.       : InstrProfCorrelator(Kind, std::move(Ctx)){};
  147.   llvm::DenseSet<IntPtrT> CounterOffsets;
  148.  
  149.   // Byte-swap the value if necessary.
  150.   template <class T> T maybeSwap(T Value) const {
  151.     return Ctx->ShouldSwapBytes ? sys::getSwappedBytes(Value) : Value;
  152.   }
  153. };
  154.  
  155. /// DwarfInstrProfCorrelator - A child of InstrProfCorrelatorImpl that takes
  156. /// DWARF debug info as input to correlate profiles.
  157. template <class IntPtrT>
  158. class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
  159. public:
  160.   DwarfInstrProfCorrelator(std::unique_ptr<DWARFContext> DICtx,
  161.                            std::unique_ptr<InstrProfCorrelator::Context> Ctx)
  162.       : InstrProfCorrelatorImpl<IntPtrT>(std::move(Ctx)),
  163.         DICtx(std::move(DICtx)) {}
  164.  
  165. private:
  166.   std::unique_ptr<DWARFContext> DICtx;
  167.  
  168.   /// Return the address of the object that the provided DIE symbolizes.
  169.   std::optional<uint64_t> getLocation(const DWARFDie &Die) const;
  170.  
  171.   /// Returns true if the provided DIE symbolizes an instrumentation probe
  172.   /// symbol.
  173.   static bool isDIEOfProbe(const DWARFDie &Die);
  174.  
  175.   /// Iterate over DWARF DIEs to find those that symbolize instrumentation
  176.   /// probes and construct the ProfileData vector and Names string.
  177.   ///
  178.   /// Here is some example DWARF for an instrumentation probe we are looking
  179.   /// for:
  180.   /// \code
  181.   ///   DW_TAG_subprogram
  182.   ///   DW_AT_low_pc    (0x0000000000000000)
  183.   ///   DW_AT_high_pc   (0x0000000000000014)
  184.   ///   DW_AT_name      ("foo")
  185.   ///     DW_TAG_variable
  186.   ///       DW_AT_name  ("__profc_foo")
  187.   ///       DW_AT_location      (DW_OP_addr 0x0)
  188.   ///       DW_TAG_LLVM_annotation
  189.   ///         DW_AT_name        ("Function Name")
  190.   ///         DW_AT_const_value ("foo")
  191.   ///       DW_TAG_LLVM_annotation
  192.   ///         DW_AT_name        ("CFG Hash")
  193.   ///         DW_AT_const_value (12345678)
  194.   ///       DW_TAG_LLVM_annotation
  195.   ///         DW_AT_name        ("Num Counters")
  196.   ///         DW_AT_const_value (2)
  197.   ///       NULL
  198.   ///     NULL
  199.   /// \endcode
  200.   void correlateProfileDataImpl(
  201.       InstrProfCorrelator::CorrelationData *Data = nullptr) override;
  202. };
  203.  
  204. } // end namespace llvm
  205.  
  206. #endif // LLVM_PROFILEDATA_INSTRPROFCORRELATOR_H
  207.