diff options
Diffstat (limited to 'llvm')
19 files changed, 547 insertions, 277 deletions
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index d6051ffb3f8..b9a9f537769 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -1,4 +1,4 @@ -//=-- CoverageMapping.h - Code coverage mapping support ---------*- C++ -*-=// +//===- CoverageMapping.h - Code coverage mapping support --------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,25 +12,42 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_PROFILEDATA_COVERAGEMAPPING_H_ -#define LLVM_PROFILEDATA_COVERAGEMAPPING_H_ +#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H +#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H  #include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/Hashing.h" -#include "llvm/ADT/StringSet.h" -#include "llvm/ADT/Triple.h"  #include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/StringSet.h" +#include "llvm/ADT/StringRef.h"  #include "llvm/ProfileData/InstrProf.h" +#include "llvm/Support/Compiler.h"  #include "llvm/Support/Debug.h"  #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h"  #include "llvm/Support/raw_ostream.h" +#include <cassert> +#include <cstdint> +#include <iterator> +#include <memory> +#include <string>  #include <system_error>  #include <tuple> +#include <utility> +#include <vector>  namespace llvm { + +class IndexedInstrProfReader; +  namespace coverage { +class CoverageMappingReader; +struct CoverageMappingRecord; +  enum class coveragemap_error {    success = 0,    eof, @@ -68,19 +85,6 @@ private:    coveragemap_error Err;  }; -} // end of coverage namespace. -} // end of llvm namespace - -namespace llvm { -class IndexedInstrProfReader; -namespace coverage { - -class CoverageMappingReader; -struct CoverageMappingRecord; - -class CoverageMapping; -struct CounterExpressions; -  /// \brief A Counter is an abstract value that describes how to compute the  /// execution count for a region of code using the collected profile count data.  struct Counter { @@ -91,13 +95,13 @@ struct Counter {        EncodingTagBits + 1;  private: -  CounterKind Kind; -  unsigned ID; +  CounterKind Kind = Zero; +  unsigned ID = 0;    Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}  public: -  Counter() : Kind(Zero), ID(0) {} +  Counter() = default;    CounterKind getKind() const { return Kind; } @@ -153,8 +157,9 @@ struct CounterExpression {  class CounterExpressionBuilder {    /// \brief A list of all the counter expressions    std::vector<CounterExpression> Expressions; +    /// \brief A lookup table for the index of a given expression. -  llvm::DenseMap<CounterExpression, unsigned> ExpressionIndices; +  DenseMap<CounterExpression, unsigned> ExpressionIndices;    /// \brief Return the counter which corresponds to the given expression.    /// @@ -238,7 +243,6 @@ struct CounterMappingRegion {                                  LineEnd, ColumnEnd, SkippedRegion);    } -    inline std::pair<unsigned, unsigned> startLoc() const {      return std::pair<unsigned, unsigned>(LineStart, ColumnStart);    } @@ -269,7 +273,7 @@ public:    void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; } -  void dump(const Counter &C, llvm::raw_ostream &OS) const; +  void dump(const Counter &C, raw_ostream &OS) const;    void dump(const Counter &C) const { dump(C, dbgs()); }    /// \brief Return the number of times that a region of code associated with @@ -390,13 +394,14 @@ struct CoverageSegment {  /// provides a sequence of CoverageSegments to iterate through, as well as the  /// list of expansions that can be further processed.  class CoverageData { +  friend class CoverageMapping; +    std::string Filename;    std::vector<CoverageSegment> Segments;    std::vector<ExpansionRecord> Expansions; -  friend class CoverageMapping;  public: -  CoverageData() {} +  CoverageData() = default;    CoverageData(StringRef Filename) : Filename(Filename) {} @@ -422,18 +427,17 @@ public:  class CoverageMapping {    StringSet<> FunctionNames;    std::vector<FunctionRecord> Functions; -  unsigned MismatchedFunctionCount; - -  CoverageMapping() : MismatchedFunctionCount(0) {} - -  CoverageMapping(const CoverageMapping &) = delete; -  const CoverageMapping &operator=(const CoverageMapping &) = delete; +  unsigned MismatchedFunctionCount = 0; +  CoverageMapping() = default;    /// \brief Add a function record corresponding to \p Record.    Error loadFunctionRecord(const CoverageMappingRecord &Record,                             IndexedInstrProfReader &ProfileReader);  public: +  CoverageMapping(const CoverageMapping &) = delete; +  CoverageMapping &operator=(const CoverageMapping &) = delete; +    /// \brief Load the coverage mapping using the given readers.    static Expected<std::unique_ptr<CoverageMapping>>    load(CoverageMappingReader &CoverageReader, @@ -517,14 +521,17 @@ template <class IntPtrT> struct CovMapFunctionRecordV1 {    template <support::endianness Endian> uint64_t getFuncHash() const {      return support::endian::byte_swap<uint64_t, Endian>(FuncHash);    } +    // Return the coverage map data size for the funciton.    template <support::endianness Endian> uint32_t getDataSize() const {      return support::endian::byte_swap<uint32_t, Endian>(DataSize);    } +    // Return function lookup key. The value is consider opaque.    template <support::endianness Endian> IntPtrT getFuncNameRef() const {      return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);    } +    // Return the PGO name of the function */    template <support::endianness Endian>    Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const { @@ -545,14 +552,17 @@ struct CovMapFunctionRecord {    template <support::endianness Endian> uint64_t getFuncHash() const {      return support::endian::byte_swap<uint64_t, Endian>(FuncHash);    } +    // Return the coverage map data size for the funciton.    template <support::endianness Endian> uint32_t getDataSize() const {      return support::endian::byte_swap<uint32_t, Endian>(DataSize);    } +    // Return function lookup key. The value is consider opaque.    template <support::endianness Endian> uint64_t getFuncNameRef() const {      return support::endian::byte_swap<uint64_t, Endian>(NameRef);    } +    // Return the PGO name of the function */    template <support::endianness Endian>    Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const { @@ -570,12 +580,15 @@ struct CovMapHeader {    template <support::endianness Endian> uint32_t getNRecords() const {      return support::endian::byte_swap<uint32_t, Endian>(NRecords);    } +    template <support::endianness Endian> uint32_t getFilenamesSize() const {      return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);    } +    template <support::endianness Endian> uint32_t getCoverageSize() const {      return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);    } +    template <support::endianness Endian> uint32_t getVersion() const {      return support::endian::byte_swap<uint32_t, Endian>(Version);    } @@ -635,4 +648,4 @@ template<> struct DenseMapInfo<coverage::CounterExpression> {  } // end namespace llvm -#endif // LLVM_PROFILEDATA_COVERAGEMAPPING_H_ +#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h index db907f128d9..5b372252a9a 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h @@ -1,4 +1,4 @@ -//=-- CoverageMappingReader.h - Code coverage mapping reader ------*- C++ -*-=// +//===- CoverageMappingReader.h - Code coverage mapping reader ---*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,18 +12,20 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H -#define LLVM_PROFILEDATA_COVERAGEMAPPINGREADER_H +#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H +#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H  #include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Object/ObjectFile.h"  #include "llvm/ProfileData/Coverage/CoverageMapping.h"  #include "llvm/ProfileData/InstrProf.h" -#include "llvm/Support/FileSystem.h" +#include "llvm/Support/Error.h"  #include "llvm/Support/MemoryBuffer.h" +#include <cstddef> +#include <cstdint>  #include <iterator> +#include <memory> +#include <vector>  namespace llvm {  namespace coverage { @@ -42,13 +44,14 @@ struct CoverageMappingRecord {  /// \brief A file format agnostic iterator over coverage mapping data.  class CoverageMappingIterator      : public std::iterator<std::input_iterator_tag, CoverageMappingRecord> { -  CoverageMappingReader *Reader; +  CoverageMappingReader *Reader = nullptr;    CoverageMappingRecord Record;    void increment();  public: -  CoverageMappingIterator() : Reader(nullptr) {} +  CoverageMappingIterator() = default; +    CoverageMappingIterator(CoverageMappingReader *Reader) : Reader(Reader) {      increment();    } @@ -69,10 +72,11 @@ public:  class CoverageMappingReader {  public: +  virtual ~CoverageMappingReader() = default; +    virtual Error readNextRecord(CoverageMappingRecord &Record) = 0;    CoverageMappingIterator begin() { return CoverageMappingIterator(this); }    CoverageMappingIterator end() { return CoverageMappingIterator(); } -  virtual ~CoverageMappingReader() {}  };  /// \brief Base class for the raw coverage mapping and filenames data readers. @@ -92,13 +96,12 @@ protected:  class RawCoverageFilenamesReader : public RawCoverageReader {    std::vector<StringRef> &Filenames; -  RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete; -  RawCoverageFilenamesReader & -  operator=(const RawCoverageFilenamesReader &) = delete; -  public:    RawCoverageFilenamesReader(StringRef Data, std::vector<StringRef> &Filenames)        : RawCoverageReader(Data), Filenames(Filenames) {} +  RawCoverageFilenamesReader(const RawCoverageFilenamesReader &) = delete; +  RawCoverageFilenamesReader & +  operator=(const RawCoverageFilenamesReader &) = delete;    Error read();  }; @@ -120,10 +123,6 @@ class RawCoverageMappingReader : public RawCoverageReader {    std::vector<CounterExpression> &Expressions;    std::vector<CounterMappingRegion> &MappingRegions; -  RawCoverageMappingReader(const RawCoverageMappingReader &) = delete; -  RawCoverageMappingReader & -  operator=(const RawCoverageMappingReader &) = delete; -  public:    RawCoverageMappingReader(StringRef MappingData,                             ArrayRef<StringRef> TranslationUnitFilenames, @@ -134,6 +133,9 @@ public:          TranslationUnitFilenames(TranslationUnitFilenames),          Filenames(Filenames), Expressions(Expressions),          MappingRegions(MappingRegions) {} +  RawCoverageMappingReader(const RawCoverageMappingReader &) = delete; +  RawCoverageMappingReader & +  operator=(const RawCoverageMappingReader &) = delete;    Error read(); @@ -169,17 +171,17 @@ private:    std::vector<StringRef> Filenames;    std::vector<ProfileMappingRecord> MappingRecords;    InstrProfSymtab ProfileNames; -  size_t CurrentRecord; +  size_t CurrentRecord = 0;    std::vector<StringRef> FunctionsFilenames;    std::vector<CounterExpression> Expressions;    std::vector<CounterMappingRegion> MappingRegions; +  BinaryCoverageReader() = default; + +public:    BinaryCoverageReader(const BinaryCoverageReader &) = delete;    BinaryCoverageReader &operator=(const BinaryCoverageReader &) = delete; -  BinaryCoverageReader() : CurrentRecord(0) {} - -public:    static Expected<std::unique_ptr<BinaryCoverageReader>>    create(std::unique_ptr<MemoryBuffer> &ObjectBuffer,           StringRef Arch); @@ -190,4 +192,4 @@ public:  } // end namespace coverage  } // end namespace llvm -#endif +#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGREADER_H diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h index 24fb9464724..b6f864ab3de 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h @@ -1,4 +1,4 @@ -//=-- CoverageMappingWriter.h - Code coverage mapping writer ------*- C++ -*-=// +//===- CoverageMappingWriter.h - Code coverage mapping writer ---*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,15 +12,17 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_PROFILEDATA_COVERAGEMAPPINGWRITER_H -#define LLVM_PROFILEDATA_COVERAGEMAPPINGWRITER_H +#ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGWRITER_H +#define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGWRITER_H  #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h"  #include "llvm/ProfileData/Coverage/CoverageMapping.h" -#include "llvm/Support/raw_ostream.h"  namespace llvm { + +class raw_ostream; +  namespace coverage {  /// \brief Writer of the filenames section for the instrumentation @@ -54,6 +56,7 @@ public:  };  } // end namespace coverage +  } // end namespace llvm -#endif +#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPINGWRITER_H diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index c7e558efa3d..d48622ed881 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -1,4 +1,4 @@ -//===-- InstrProf.h - Instrumented profiling format support -----*- C++ -*-===// +//===- InstrProf.h - Instrumented profiling format support ------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -16,26 +16,41 @@  #ifndef LLVM_PROFILEDATA_INSTRPROF_H  #define LLVM_PROFILEDATA_INSTRPROF_H +#include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/StringRef.h"  #include "llvm/ADT/StringSet.h"  #include "llvm/IR/GlobalValue.h" -#include "llvm/IR/Metadata.h" +#include "llvm/IR/ProfileSummary.h"  #include "llvm/ProfileData/InstrProfData.inc" -#include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/Support/Compiler.h"  #include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h"  #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Host.h"  #include "llvm/Support/MD5.h"  #include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstddef>  #include <cstdint> +#include <cstring>  #include <list> +#include <memory> +#include <string>  #include <system_error> +#include <utility>  #include <vector>  namespace llvm {  class Function;  class GlobalVariable; +struct InstrProfRecord; +class InstrProfSymtab; +class Instruction; +class MDNode;  class Module;  /// Return the name of data section containing profile counter variables. @@ -201,6 +216,7 @@ GlobalVariable *createPGOFuncNameVar(Function &F, StringRef PGOFuncName);  GlobalVariable *createPGOFuncNameVar(Module &M,                                       GlobalValue::LinkageTypes Linkage,                                       StringRef PGOFuncName); +  /// Return the initializer in string of the PGO name var \c NameVar.  StringRef getPGOFuncNameVarInitializer(GlobalVariable *NameVar); @@ -220,11 +236,12 @@ StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName,  /// second field will have value zero.  Error collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,                                  bool doCompression, std::string &Result); +  /// Produce \c Result string with the same format described above. The input  /// is vector of PGO function name variables that are referenced.  Error collectPGOFuncNameStrings(const std::vector<GlobalVariable *> &NameVars,                                  std::string &Result, bool doCompression = true); -class InstrProfSymtab; +  /// \c NameStrings is a string composed of one of more sub-strings encoded in  /// the format described above. The substrings are separated by 0 or more zero  /// bytes. This method decodes the string and populates the \c Symtab. @@ -244,8 +261,6 @@ enum InstrProfValueKind : uint32_t {  #include "llvm/ProfileData/InstrProfData.inc"  }; -struct InstrProfRecord; -  /// Get the value profile data for value site \p SiteIdx from \p InstrProfR  /// and annotate the instruction \p Inst with the value profile meta data.  /// Annotate up to \p MaxMDCount (default 3) number of records per value site. @@ -253,6 +268,7 @@ void annotateValueSite(Module &M, Instruction &Inst,                         const InstrProfRecord &InstrProfR,                         InstrProfValueKind ValueKind, uint32_t SiteIndx,                         uint32_t MaxMDCount = 3); +  /// Same as the above interface but using an ArrayRef, as well as \p Sum.  void annotateValueSite(Module &M, Instruction &Inst,                         ArrayRef<InstrProfValueData> VDs, @@ -347,25 +363,22 @@ class SoftInstrProfErrors {    /// the first such error for reporting purposes.    /// The first soft error encountered. -  instrprof_error FirstError; +  instrprof_error FirstError = instrprof_error::success;    /// The number of hash mismatches. -  unsigned NumHashMismatches; +  unsigned NumHashMismatches = 0;    /// The number of count mismatches. -  unsigned NumCountMismatches; +  unsigned NumCountMismatches = 0;    /// The number of counter overflows. -  unsigned NumCounterOverflows; +  unsigned NumCounterOverflows = 0;    /// The number of value site count mismatches. -  unsigned NumValueSiteCountMismatches; +  unsigned NumValueSiteCountMismatches = 0;  public: -  SoftInstrProfErrors() -      : FirstError(instrprof_error::success), NumHashMismatches(0), -        NumCountMismatches(0), NumCounterOverflows(0), -        NumValueSiteCountMismatches(0) {} +  SoftInstrProfErrors() = default;    ~SoftInstrProfErrors() {      assert(FirstError == instrprof_error::success && @@ -401,12 +414,16 @@ public:  };  namespace object { +  class SectionRef; -} + +} // end namespace object  namespace IndexedInstrProf { +  uint64_t ComputeHash(StringRef K); -} + +} // end namespace IndexedInstrProf  /// A symbol table used for function PGO name look-up with keys  /// (such as pointers, md5hash values) to the function. A function's @@ -419,7 +436,7 @@ public:  private:    StringRef Data; -  uint64_t Address; +  uint64_t Address = 0;    // Unique name strings.    StringSet<> NameTab;    // A map from MD5 keys to function name strings. @@ -432,9 +449,7 @@ private:    AddrHashMap AddrToMD5Map;  public: -  InstrProfSymtab() -      : Data(), Address(0), NameTab(), MD5NameMap(), MD5FuncMap(), -      AddrToMD5Map() {} +  InstrProfSymtab() = default;     /// Create InstrProfSymtab from an object file section which    /// contains function PGO names. When section may contain raw @@ -443,26 +458,32 @@ public:    /// the section base address. The decompression will be delayed    /// until before it is used. See also \c create(StringRef) method.    Error create(object::SectionRef &Section); +    /// This interface is used by reader of CoverageMapping test    /// format.    inline Error create(StringRef D, uint64_t BaseAddr); +    /// \c NameStrings is a string composed of one of more sub-strings    ///  encoded in the format described in \c collectPGOFuncNameStrings.    /// This method is a wrapper to \c readPGOFuncNameStrings method.    inline Error create(StringRef NameStrings); +    /// A wrapper interface to populate the PGO symtab with functions    /// decls from module \c M. This interface is used by transformation    /// passes such as indirect function call promotion. Variable \c InLTO    /// indicates if this is called from LTO optimization passes.    void create(Module &M, bool InLTO = false); +    /// Create InstrProfSymtab from a set of names iteratable from    /// \p IterRange. This interface is used by IndexedProfReader.    template <typename NameIterRange> void create(const NameIterRange &IterRange); +    // If the symtab is created by a series of calls to \c addFuncName, \c    // finalizeSymtab needs to be called before looking up function names.    // This is required because the underlying map is a vector (for space    // efficiency) which needs to be sorted.    inline void finalizeSymtab(); +    /// Update the symtab by adding \p FuncName to the table. This interface    /// is used by the raw and text profile readers.    void addFuncName(StringRef FuncName) { @@ -471,25 +492,32 @@ public:        MD5NameMap.push_back(std::make_pair(            IndexedInstrProf::ComputeHash(FuncName), Ins.first->getKey()));    } +    /// Map a function address to its name's MD5 hash. This interface    /// is only used by the raw profiler reader.    void mapAddress(uint64_t Addr, uint64_t MD5Val) {      AddrToMD5Map.push_back(std::make_pair(Addr, MD5Val));    } +    AddrHashMap &getAddrHashMap() { return AddrToMD5Map; } +    /// Return function's PGO name from the function name's symbol    /// address in the object file. If an error occurs, return    /// an empty string.    StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize); +    /// Return function's PGO name from the name's md5 hash value.    /// If not found, return an empty string.    inline StringRef getFuncName(uint64_t FuncMD5Hash); +    /// Return function from the name's md5 hash. Return nullptr if not found.    inline Function *getFunction(uint64_t FuncMD5Hash); +    /// Return the function's original assembly name by stripping off    /// the prefix attached (to symbols with priviate linkage). For    /// global functions, it returns the same string as getFuncName.    inline StringRef getOrigFuncName(uint64_t FuncMD5Hash); +    /// Return the name section data.    inline StringRef getNameData() const { return Data; }  }; @@ -579,40 +607,48 @@ struct InstrProfValueSiteRecord {  /// Profiling information for a single function.  struct InstrProfRecord { -  InstrProfRecord() : SIPE() {} -  InstrProfRecord(StringRef Name, uint64_t Hash, std::vector<uint64_t> Counts) -      : Name(Name), Hash(Hash), Counts(std::move(Counts)), SIPE() {}    StringRef Name;    uint64_t Hash;    std::vector<uint64_t> Counts;    SoftInstrProfErrors SIPE; +  InstrProfRecord() = default; +  InstrProfRecord(StringRef Name, uint64_t Hash, std::vector<uint64_t> Counts) +      : Name(Name), Hash(Hash), Counts(std::move(Counts)) {} +    typedef std::vector<std::pair<uint64_t, uint64_t>> ValueMapType;    /// Return the number of value profile kinds with non-zero number    /// of profile sites.    inline uint32_t getNumValueKinds() const; +    /// Return the number of instrumented sites for ValueKind.    inline uint32_t getNumValueSites(uint32_t ValueKind) const; +    /// Return the total number of ValueData for ValueKind.    inline uint32_t getNumValueData(uint32_t ValueKind) const; +    /// Return the number of value data collected for ValueKind at profiling    /// site: Site.    inline uint32_t getNumValueDataForSite(uint32_t ValueKind,                                           uint32_t Site) const; +    /// Return the array of profiled values at \p Site. If \p TotalC    /// is not null, the total count of all target values at this site    /// will be stored in \c *TotalC.    inline std::unique_ptr<InstrProfValueData[]>    getValueForSite(uint32_t ValueKind, uint32_t Site, -                  uint64_t *TotalC = 0) const; +                  uint64_t *TotalC = nullptr) const; +    /// Get the target value/counts of kind \p ValueKind collected at site    /// \p Site and store the result in array \p Dest. Return the total    /// counts of all target values at this site.    inline uint64_t getValueForSite(InstrProfValueData Dest[], uint32_t ValueKind,                                    uint32_t Site) const; +    /// Reserve space for NumValueSites sites.    inline void reserveSites(uint32_t ValueKind, uint32_t NumValueSites); +    /// Add ValueData for ValueKind at value Site.    void addValueData(uint32_t ValueKind, uint32_t Site,                      InstrProfValueData *VData, uint32_t N, @@ -647,6 +683,7 @@ struct InstrProfRecord {  private:    std::vector<InstrProfValueSiteRecord> IndirectCallSites;    const std::vector<InstrProfValueSiteRecord> & +    getValueSitesForKind(uint32_t ValueKind) const {      switch (ValueKind) {      case IPVK_IndirectCallTarget: @@ -672,6 +709,7 @@ private:    // Scale merged value counts by \p Weight.    void mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src,                            uint64_t Weight); +    // Scale up value profile data count.    void scaleValueProfData(uint32_t ValueKind, uint64_t Weight);  }; @@ -706,7 +744,7 @@ std::unique_ptr<InstrProfValueData[]>  InstrProfRecord::getValueForSite(uint32_t ValueKind, uint32_t Site,                                   uint64_t *TotalC) const {    uint64_t Dummy; -  uint64_t &TotalCount = (TotalC == 0 ? Dummy : *TotalC); +  uint64_t &TotalCount = (TotalC == nullptr ? Dummy : *TotalC);    uint32_t N = getNumValueDataForSite(ValueKind, Site);    if (N == 0) {      TotalCount = 0; @@ -762,7 +800,6 @@ namespace IndexedInstrProf {  enum class HashT : uint32_t {    MD5, -    Last = MD5  }; @@ -816,7 +853,6 @@ struct Header {  // format. It is introduced in version 4. The summary data follows  // right after the profile file header.  struct Summary { -    struct Entry {      uint64_t Cutoff; ///< The required percentile of total execution count.      uint64_t @@ -857,13 +893,16 @@ struct Summary {    const uint64_t *getSummaryDataBase() const {      return reinterpret_cast<const uint64_t *>(this + 1);    } +    uint64_t *getSummaryDataBase() {      return reinterpret_cast<uint64_t *>(this + 1);    } +    const Entry *getCutoffEntryBase() const {      return reinterpret_cast<const Entry *>(          &getSummaryDataBase()[NumSummaryFields]);    } +    Entry *getCutoffEntryBase() {      return reinterpret_cast<Entry *>(&getSummaryDataBase()[NumSummaryFields]);    } @@ -877,6 +916,7 @@ struct Summary {    }    const Entry &getEntry(uint32_t I) const { return getCutoffEntryBase()[I]; } +    void setEntry(uint32_t I, const ProfileSummaryEntry &E) {      Entry &ER = getCutoffEntryBase()[I];      ER.Cutoff = E.Cutoff; @@ -894,6 +934,7 @@ inline std::unique_ptr<Summary> allocSummary(uint32_t TotalSize) {    return std::unique_ptr<Summary>(new (::operator new(TotalSize))                                        Summary(TotalSize));  } +  } // end namespace IndexedInstrProf  namespace RawInstrProf { diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h index 65b11f61d10..1d85a7149af 100644 --- a/llvm/include/llvm/ProfileData/InstrProfReader.h +++ b/llvm/include/llvm/ProfileData/InstrProfReader.h @@ -1,4 +1,4 @@ -//=-- InstrProfReader.h - Instrumented profiling readers ----------*- C++ -*-=// +//===- InstrProfReader.h - Instrumented profiling readers -------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -16,14 +16,23 @@  #define LLVM_PROFILEDATA_INSTRPROFREADER_H  #include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/ProfileSummary.h"  #include "llvm/ProfileData/InstrProf.h" -#include "llvm/Support/EndianStream.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h"  #include "llvm/Support/LineIterator.h"  #include "llvm/Support/MemoryBuffer.h"  #include "llvm/Support/OnDiskHashTable.h" -#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/SwapByteOrder.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint>  #include <iterator> +#include <memory> +#include <utility> +#include <vector>  namespace llvm { @@ -32,12 +41,13 @@ class InstrProfReader;  /// A file format agnostic iterator over profiling data.  class InstrProfIterator : public std::iterator<std::input_iterator_tag,                                                 InstrProfRecord> { -  InstrProfReader *Reader; +  InstrProfReader *Reader = nullptr;    InstrProfRecord Record;    void Increment(); +  public: -  InstrProfIterator() : Reader(nullptr) {} +  InstrProfIterator() = default;    InstrProfIterator(InstrProfReader *Reader) : Reader(Reader) { Increment(); }    InstrProfIterator &operator++() { Increment(); return *this; } @@ -50,19 +60,22 @@ public:  /// Base class and interface for reading profiling data of any known instrprof  /// format. Provides an iterator over InstrProfRecords.  class InstrProfReader { -  instrprof_error LastError; +  instrprof_error LastError = instrprof_error::success;  public: -  InstrProfReader() : LastError(instrprof_error::success), Symtab() {} -  virtual ~InstrProfReader() {} +  InstrProfReader() = default; +  virtual ~InstrProfReader() = default;    /// Read the header.  Required before reading first record.    virtual Error readHeader() = 0; +    /// Read a single record.    virtual Error readNextRecord(InstrProfRecord &Record) = 0; +    /// Iterator over profile data.    InstrProfIterator begin() { return InstrProfIterator(this); }    InstrProfIterator end() { return InstrProfIterator(); } +    virtual bool isIRLevelProfile() const = 0;    /// Return the PGO symtab. There are three different readers: @@ -86,6 +99,7 @@ protected:        return Error::success();      return make_error<InstrProfError>(Err);    } +    Error error(Error E) { return error(InstrProfError::take(std::move(E))); }    /// Clear the current error and return a successful one. @@ -94,8 +108,10 @@ protected:  public:    /// Return true if the reader has finished reading the profile data.    bool isEOF() { return LastError == instrprof_error::eof; } +    /// Return true if the reader encountered an error reading profiling data.    bool hasError() { return LastError != instrprof_error::success && !isEOF(); } +    /// Get the current error.    Error getError() {      if (hasError()) @@ -125,16 +141,15 @@ private:    std::unique_ptr<MemoryBuffer> DataBuffer;    /// Iterator over the profile data.    line_iterator Line; -  bool IsIRLevelProfile; +  bool IsIRLevelProfile = false; -  TextInstrProfReader(const TextInstrProfReader &) = delete; -  TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;    Error readValueProfileData(InstrProfRecord &Record);  public:    TextInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer_) -      : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#'), -        IsIRLevelProfile(false) {} +      : DataBuffer(std::move(DataBuffer_)), Line(*DataBuffer, true, '#') {} +  TextInstrProfReader(const TextInstrProfReader &) = delete; +  TextInstrProfReader &operator=(const TextInstrProfReader &) = delete;    /// Return true if the given buffer is in text instrprof format.    static bool hasFormat(const MemoryBuffer &Buffer); @@ -143,6 +158,7 @@ public:    /// Read the header.    Error readHeader() override; +    /// Read a single record.    Error readNextRecord(InstrProfRecord &Record) override; @@ -184,15 +200,16 @@ private:    InstrProfRecord::ValueMapType FunctionPtrToNameMap; -  RawInstrProfReader(const RawInstrProfReader &) = delete; -  RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;  public:    RawInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer)        : DataBuffer(std::move(DataBuffer)) { } +  RawInstrProfReader(const RawInstrProfReader &) = delete; +  RawInstrProfReader &operator=(const RawInstrProfReader &) = delete;    static bool hasFormat(const MemoryBuffer &DataBuffer);    Error readHeader() override;    Error readNextRecord(InstrProfRecord &Record) override; +    bool isIRLevelProfile() const override {      return (Version & VARIANT_MASK_IR_PROF) != 0;    } @@ -206,9 +223,11 @@ private:    Error createSymtab(InstrProfSymtab &Symtab);    Error readNextHeader(const char *CurrentPos);    Error readHeader(const RawInstrProf::Header &Header); +    template <class IntT> IntT swap(IntT Int) const {      return ShouldSwapBytes ? sys::getSwappedBytes(Int) : Int;    } +    support::endianness getDataEndianness() const {      support::endianness HostEndian = getHostEndianness();      if (!ShouldSwapBytes) @@ -222,15 +241,18 @@ private:    inline uint8_t getNumPaddingBytes(uint64_t SizeInBytes) {      return 7 & (sizeof(uint64_t) - SizeInBytes % sizeof(uint64_t));    } +    Error readName(InstrProfRecord &Record);    Error readFuncHash(InstrProfRecord &Record);    Error readRawCounts(InstrProfRecord &Record);    Error readValueProfilingData(InstrProfRecord &Record);    bool atEnd() const { return Data == DataEnd; } +    void advanceData() {      Data++;      ValueDataStart += CurValueDataSize;    } +    const char *getNextHeaderPos() const {        assert(atEnd());        return (const char *)ValueDataStart; @@ -240,6 +262,7 @@ private:      ptrdiff_t Offset = (swap(CounterPtr) - CountersDelta) / sizeof(uint64_t);      return CountersStart + Offset;    } +    StringRef getName(uint64_t NameRef) const {      return Symtab->getFuncName(swap(NameRef));    } @@ -249,8 +272,10 @@ typedef RawInstrProfReader<uint32_t> RawInstrProfReader32;  typedef RawInstrProfReader<uint64_t> RawInstrProfReader64;  namespace IndexedInstrProf { +  enum class HashT : uint32_t; -} + +} // end namespace IndexedInstrProf  /// Trait for lookups into the on-disk hash table for the binary instrprof  /// format. @@ -261,12 +286,11 @@ class InstrProfLookupTrait {    // Endianness of the input value profile data.    // It should be LE by default, but can be changed    // for testing purpose. -  support::endianness ValueProfDataEndianness; +  support::endianness ValueProfDataEndianness = support::little;  public:    InstrProfLookupTrait(IndexedInstrProf::HashT HashType, unsigned FormatVersion) -      : HashType(HashType), FormatVersion(FormatVersion), -        ValueProfDataEndianness(support::little) {} +      : HashType(HashType), FormatVersion(FormatVersion) {}    typedef ArrayRef<InstrProfRecord> data_type; @@ -284,6 +308,7 @@ public:    static std::pair<offset_type, offset_type>    ReadKeyDataLength(const unsigned char *&D) {      using namespace support; +      offset_type KeyLen = endian::readNext<offset_type, little, unaligned>(D);      offset_type DataLen = endian::readNext<offset_type, little, unaligned>(D);      return std::make_pair(KeyLen, DataLen); @@ -304,16 +329,18 @@ public:  };  struct InstrProfReaderIndexBase { +  virtual ~InstrProfReaderIndexBase() = default; +    // Read all the profile records with the same key pointed to the current    // iterator.    virtual Error getRecords(ArrayRef<InstrProfRecord> &Data) = 0; +    // Read all the profile records with the key equal to FuncName    virtual Error getRecords(StringRef FuncName,                                       ArrayRef<InstrProfRecord> &Data) = 0;    virtual void advanceToNextKey() = 0;    virtual bool atEnd() const = 0;    virtual void setValueProfDataEndianness(support::endianness Endianness) = 0; -  virtual ~InstrProfReaderIndexBase() {}    virtual uint64_t getVersion() const = 0;    virtual bool isIRLevelProfile() const = 0;    virtual void populateSymtab(InstrProfSymtab &) = 0; @@ -335,22 +362,27 @@ public:                         const unsigned char *const Payload,                         const unsigned char *const Base,                         IndexedInstrProf::HashT HashType, uint64_t Version); +  ~InstrProfReaderIndex() override = default;    Error getRecords(ArrayRef<InstrProfRecord> &Data) override;    Error getRecords(StringRef FuncName,                     ArrayRef<InstrProfRecord> &Data) override;    void advanceToNextKey() override { RecordIterator++; } +    bool atEnd() const override {      return RecordIterator == HashTable->data_end();    } +    void setValueProfDataEndianness(support::endianness Endianness) override {      HashTable->getInfoObj().setValueProfDataEndianness(Endianness);    } -  ~InstrProfReaderIndex() override {} +    uint64_t getVersion() const override { return GET_VERSION(FormatVersion); } +    bool isIRLevelProfile() const override {      return (FormatVersion & VARIANT_MASK_IR_PROF) != 0;    } +    void populateSymtab(InstrProfSymtab &Symtab) override {      Symtab.create(HashTable->keys());    } @@ -366,20 +398,20 @@ private:    /// Profile summary data.    std::unique_ptr<ProfileSummary> Summary; -  IndexedInstrProfReader(const IndexedInstrProfReader &) = delete; -  IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete; -    // 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.    const unsigned char *readSummary(IndexedInstrProf::ProfVersion Version,                                     const unsigned char *Cur);  public: +  IndexedInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer) +      : DataBuffer(std::move(DataBuffer)) {} +  IndexedInstrProfReader(const IndexedInstrProfReader &) = delete; +  IndexedInstrProfReader &operator=(const IndexedInstrProfReader &) = delete; +    /// Return the profile version.    uint64_t getVersion() const { return Index->getVersion(); }    bool isIRLevelProfile() const override { return Index->isIRLevelProfile(); } -  IndexedInstrProfReader(std::unique_ptr<MemoryBuffer> DataBuffer) -      : DataBuffer(std::move(DataBuffer)), Index(nullptr) {}    /// Return true if the given buffer is in an indexed instrprof format.    static bool hasFormat(const MemoryBuffer &DataBuffer); @@ -422,4 +454,4 @@ public:  } // end namespace llvm -#endif +#endif // LLVM_PROFILEDATA_INSTRPROFREADER_H diff --git a/llvm/include/llvm/ProfileData/InstrProfWriter.h b/llvm/include/llvm/ProfileData/InstrProfWriter.h index f7780fb4500..10742c0228e 100644 --- a/llvm/include/llvm/ProfileData/InstrProfWriter.h +++ b/llvm/include/llvm/ProfileData/InstrProfWriter.h @@ -1,4 +1,4 @@ -//=-- InstrProfWriter.h - Instrumented profiling writer -----------*- C++ -*-=// +//===- InstrProfWriter.h - Instrumented profiling writer --------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -16,16 +16,19 @@  #define LLVM_PROFILEDATA_INSTRPROFWRITER_H  #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h"  #include "llvm/ProfileData/InstrProf.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h"  #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" +#include <cstdint> +#include <memory>  namespace llvm {  /// Writer for instrumentation based profile data. -class ProfOStream;  class InstrProfRecordWriterTrait; +class ProfOStream;  class InstrProfWriter {  public: @@ -35,7 +38,7 @@ public:  private:    bool Sparse;    StringMap<ProfilingData> FunctionData; -  ProfKind ProfileKind; +  ProfKind ProfileKind = PF_Unknown;    // Use raw pointer here for the incomplete type object.    InstrProfRecordWriterTrait *InfoObj; @@ -47,15 +50,20 @@ public:    /// for this function and the hash and number of counts match, each counter is    /// summed. Optionally scale counts by \p Weight.    Error addRecord(InstrProfRecord &&I, uint64_t Weight = 1); +    /// Merge existing function counts from the given writer.    Error mergeRecordsFromWriter(InstrProfWriter &&IPW); +    /// Write the profile to \c OS    void write(raw_fd_ostream &OS); +    /// Write the profile in text format to \c OS    void writeText(raw_fd_ostream &OS); +    /// Write \c Record in text format to \c OS    static void writeRecordInText(const InstrProfRecord &Record,                                  InstrProfSymtab &Symtab, raw_fd_ostream &OS); +    /// Write the profile, returning the raw data. For testing.    std::unique_ptr<MemoryBuffer> writeBuffer(); @@ -82,4 +90,4 @@ private:  } // end namespace llvm -#endif +#endif // LLVM_PROFILEDATA_INSTRPROFWRITER_H diff --git a/llvm/include/llvm/ProfileData/ProfileCommon.h b/llvm/include/llvm/ProfileData/ProfileCommon.h index e955755e5c9..987e3160cca 100644 --- a/llvm/include/llvm/ProfileData/ProfileCommon.h +++ b/llvm/include/llvm/ProfileData/ProfileCommon.h @@ -1,4 +1,4 @@ -//===-- ProfileCommon.h - Common profiling APIs. ----------------*- C++ -*-===// +//===- ProfileCommon.h - Common profiling APIs. -----------------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,38 +12,33 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_PROFILEDATA_PROFILE_COMMON_H -#define LLVM_PROFILEDATA_PROFILE_COMMON_H +#ifndef LLVM_PROFILEDATA_PROFILECOMMON_H +#define LLVM_PROFILEDATA_PROFILECOMMON_H +#include "llvm/ADT/ArrayRef.h" +#include "llvm/IR/ProfileSummary.h" +#include "llvm/Support/Error.h" +#include <algorithm>  #include <cstdint>  #include <functional>  #include <map> -#include <utility> +#include <memory>  #include <vector> -#include "llvm/IR/ProfileSummary.h" -#include "llvm/Support/Error.h" -#include "llvm/ADT/ArrayRef.h" -  namespace llvm { -class Function; -namespace IndexedInstrProf { -struct Summary; -} + +struct InstrProfRecord; +  namespace sampleprof { +  class FunctionSamples; -} -struct InstrProfRecord; -class LLVMContext; -class Metadata; -class MDTuple; -class MDNode; + +} // end namespace sampleprof  inline const char *getHotSectionPrefix() { return ".hot"; }  inline const char *getUnlikelySectionPrefix() { return ".unlikely"; }  class ProfileSummaryBuilder { -  private:    /// We keep track of the number of times a count (block count or samples)    /// appears in the profile. The map is kept sorted in the descending order of @@ -53,13 +48,18 @@ private:  protected:    SummaryEntryVector DetailedSummary; +  uint64_t TotalCount = 0; +  uint64_t MaxCount = 0; +  uint64_t MaxFunctionCount = 0; +  uint32_t NumCounts = 0; +  uint32_t NumFunctions = 0; +    ProfileSummaryBuilder(std::vector<uint32_t> Cutoffs)        : DetailedSummaryCutoffs(std::move(Cutoffs)) {} -  inline void addCount(uint64_t Count);    ~ProfileSummaryBuilder() = default; + +  inline void addCount(uint64_t Count);    void computeDetailedSummary(); -  uint64_t TotalCount = 0, MaxCount = 0, MaxFunctionCount = 0; -  uint32_t NumCounts = 0, NumFunctions = 0;  public:    /// \brief A vector of useful cutoff values for detailed summary. @@ -68,22 +68,24 @@ public:  class InstrProfSummaryBuilder final : public ProfileSummaryBuilder {    uint64_t MaxInternalBlockCount = 0; +    inline void addEntryCount(uint64_t Count);    inline void addInternalCount(uint64_t Count);  public:    InstrProfSummaryBuilder(std::vector<uint32_t> Cutoffs)        : ProfileSummaryBuilder(std::move(Cutoffs)) {} +    void addRecord(const InstrProfRecord &);    std::unique_ptr<ProfileSummary> getSummary();  };  class SampleProfileSummaryBuilder final : public ProfileSummaryBuilder { -  public: -  void addRecord(const sampleprof::FunctionSamples &FS);    SampleProfileSummaryBuilder(std::vector<uint32_t> Cutoffs)        : ProfileSummaryBuilder(std::move(Cutoffs)) {} + +  void addRecord(const sampleprof::FunctionSamples &FS);    std::unique_ptr<ProfileSummary> getSummary();  }; @@ -96,6 +98,6 @@ void ProfileSummaryBuilder::addCount(uint64_t Count) {    CountFrequencies[Count]++;  } -  } // end namespace llvm -#endif + +#endif // LLVM_PROFILEDATA_PROFILECOMMON_H diff --git a/llvm/include/llvm/ProfileData/SampleProf.h b/llvm/include/llvm/ProfileData/SampleProf.h index 1ae1cc48a8a..1fd8c417505 100644 --- a/llvm/include/llvm/ProfileData/SampleProf.h +++ b/llvm/include/llvm/ProfileData/SampleProf.h @@ -1,4 +1,4 @@ -//=-- SampleProf.h - Sampling profiling format support --------------------===// +//===- SampleProf.h - Sampling profiling format support ---------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,23 +12,30 @@  //  //===----------------------------------------------------------------------===// -#ifndef LLVM_PROFILEDATA_SAMPLEPROF_H_ -#define LLVM_PROFILEDATA_SAMPLEPROF_H_ +#ifndef LLVM_PROFILEDATA_SAMPLEPROF_H +#define LLVM_PROFILEDATA_SAMPLEPROF_H  #include "llvm/ADT/DenseSet.h"  #include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/Function.h"  #include "llvm/IR/GlobalValue.h"  #include "llvm/IR/Module.h"  #include "llvm/Support/Debug.h"  #include "llvm/Support/ErrorOr.h" -#include "llvm/Support/raw_ostream.h" - +#include "llvm/Support/MathExtras.h" +#include <algorithm> +#include <cstdint>  #include <map> +#include <string>  #include <system_error> +#include <utility>  namespace llvm { +class raw_ostream; +  const std::error_category &sampleprof_category();  enum class sampleprof_error { @@ -62,12 +69,13 @@ inline sampleprof_error MergeResult(sampleprof_error &Accumulator,  } // end namespace llvm  namespace std { +  template <>  struct is_error_code_enum<llvm::sampleprof_error> : std::true_type {}; -} -namespace llvm { +} // end namespace std +namespace llvm {  namespace sampleprof {  static inline uint64_t SPMagic() { @@ -90,8 +98,10 @@ static inline uint64_t SPVersion() { return 103; }  /// (e.g., the two post-increment instructions in "if (p) x++; else y++;").  struct LineLocation {    LineLocation(uint32_t L, uint32_t D) : LineOffset(L), Discriminator(D) {} +    void print(raw_ostream &OS) const;    void dump() const; +    bool operator<(const LineLocation &O) const {      return LineOffset < O.LineOffset ||             (LineOffset == O.LineOffset && Discriminator < O.Discriminator); @@ -117,7 +127,7 @@ class SampleRecord {  public:    typedef StringMap<uint64_t> CallTargetMap; -  SampleRecord() : NumSamples(0), CallTargets() {} +  SampleRecord() = default;    /// Increment the number of samples for this record by \p S.    /// Optionally scale sample count \p S by \p Weight. @@ -147,7 +157,7 @@ public:    }    /// Return true if this sample record contains function calls. -  bool hasCalls() const { return CallTargets.size() > 0; } +  bool hasCalls() const { return !CallTargets.empty(); }    uint64_t getSamples() const { return NumSamples; }    const CallTargetMap &getCallTargets() const { return CallTargets; } @@ -166,7 +176,7 @@ public:    void dump() const;  private: -  uint64_t NumSamples; +  uint64_t NumSamples = 0;    CallTargetMap CallTargets;  }; @@ -183,9 +193,11 @@ typedef std::map<LineLocation, FunctionSamples> CallsiteSampleMap;  /// within the body of the function.  class FunctionSamples {  public: -  FunctionSamples() : Name(), TotalSamples(0), TotalHeadSamples(0) {} +  FunctionSamples() = default; +    void print(raw_ostream &OS = dbgs(), unsigned Indent = 0) const;    void dump() const; +    sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight = 1) {      bool Overflowed;      TotalSamples = @@ -193,6 +205,7 @@ public:      return Overflowed ? sampleprof_error::counter_overflow                        : sampleprof_error::success;    } +    sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight = 1) {      bool Overflowed;      TotalHeadSamples = @@ -200,11 +213,13 @@ public:      return Overflowed ? sampleprof_error::counter_overflow                        : sampleprof_error::success;    } +    sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator,                                    uint64_t Num, uint64_t Weight = 1) {      return BodySamples[LineLocation(LineOffset, Discriminator)].addSamples(          Num, Weight);    } +    sampleprof_error addCalledTargetSamples(uint32_t LineOffset,                                            uint32_t Discriminator,                                            const std::string &FName, @@ -331,12 +346,12 @@ private:    ///    /// Samples are cumulative, they include all the samples collected    /// inside this function and all its inlined callees. -  uint64_t TotalSamples; +  uint64_t TotalSamples = 0;    /// Total number of samples collected at the head of the function.    /// This is an approximation of the number of calls made to this function    /// at runtime. -  uint64_t TotalHeadSamples; +  uint64_t TotalHeadSamples = 0;    /// Map instruction locations to collected samples.    /// @@ -383,6 +398,7 @@ public:                         return A->first < B->first;                       });    } +    const SamplesWithLocList &get() const { return V; }  private: @@ -390,7 +406,6 @@ private:  };  } // end namespace sampleprof -  } // end namespace llvm -#endif // LLVM_PROFILEDATA_SAMPLEPROF_H_ +#endif // LLVM_PROFILEDATA_SAMPLEPROF_H diff --git a/llvm/include/llvm/ProfileData/SampleProfReader.h b/llvm/include/llvm/ProfileData/SampleProfReader.h index bf86721709c..5cfebdf9de2 100644 --- a/llvm/include/llvm/ProfileData/SampleProfReader.h +++ b/llvm/include/llvm/ProfileData/SampleProfReader.h @@ -1,4 +1,4 @@ -//===- SampleProfReader.h - Read LLVM sample profile data -----------------===// +//===- SampleProfReader.h - Read LLVM sample profile data -------*- C++ -*-===//  //  //                      The LLVM Compiler Infrastructure  // @@ -205,26 +205,34 @@  //        FUNCTION BODY  //          A FUNCTION BODY entry describing the inlined function.  //===----------------------------------------------------------------------===// +  #ifndef LLVM_PROFILEDATA_SAMPLEPROFREADER_H  #define LLVM_PROFILEDATA_SAMPLEPROFREADER_H +#include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringMap.h"  #include "llvm/ADT/StringRef.h"  #include "llvm/ADT/Twine.h"  #include "llvm/IR/DiagnosticInfo.h"  #include "llvm/IR/Function.h"  #include "llvm/IR/LLVMContext.h" -#include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/IR/ProfileSummary.h"  #include "llvm/ProfileData/SampleProf.h"  #include "llvm/Support/Debug.h" -#include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/ErrorOr.h"  #include "llvm/Support/GCOV.h"  #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cstdint> +#include <memory> +#include <string> +#include <system_error> +#include <vector>  namespace llvm { +class raw_ostream; +  namespace sampleprof {  /// \brief Sample-based profile reader. @@ -259,7 +267,7 @@ public:    SampleProfileReader(std::unique_ptr<MemoryBuffer> B, LLVMContext &C)        : Profiles(0), Ctx(C), Buffer(std::move(B)) {} -  virtual ~SampleProfileReader() {} +  virtual ~SampleProfileReader() = default;    /// \brief Read and validate the file header.    virtual std::error_code readHeader() = 0; @@ -442,8 +450,8 @@ protected:    static const uint32_t GCOVTagAFDOFunction = 0xac000000;  }; -} // End namespace sampleprof +} // end namespace sampleprof -} // End namespace llvm +} // end namespace llvm  #endif // LLVM_PROFILEDATA_SAMPLEPROFREADER_H diff --git a/llvm/include/llvm/ProfileData/SampleProfWriter.h b/llvm/include/llvm/ProfileData/SampleProfWriter.h index f6f2e2702e3..9d69af32dd4 100644 --- a/llvm/include/llvm/ProfileData/SampleProfWriter.h +++ b/llvm/include/llvm/ProfileData/SampleProfWriter.h @@ -1,4 +1,4 @@ -//===- SampleProfWriter.h - Write LLVM sample profile data ----------------===// +//===- SampleProfWriter.h - Write LLVM sample profile data ------*- C++ -*-===//  //  //                      The LLVM Compiler Infrastructure  // @@ -14,15 +14,18 @@  #define LLVM_PROFILEDATA_SAMPLEPROFWRITER_H  #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/StringMap.h"  #include "llvm/ADT/StringRef.h" -#include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/IR/ProfileSummary.h"  #include "llvm/ProfileData/SampleProf.h"  #include "llvm/Support/ErrorOr.h" -#include "llvm/Support/FileSystem.h"  #include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cstdint> +#include <memory> +#include <system_error>  namespace llvm { -  namespace sampleprof {  enum SampleProfileFormat { SPF_None = 0, SPF_Text, SPF_Binary, SPF_GCC }; @@ -30,7 +33,7 @@ enum SampleProfileFormat { SPF_None = 0, SPF_Text, SPF_Binary, SPF_GCC };  /// \brief Sample-based profile writer. Base class.  class SampleProfileWriter {  public: -  virtual ~SampleProfileWriter() {} +  virtual ~SampleProfileWriter() = default;    /// Write sample profiles in \p S.    /// @@ -114,7 +117,7 @@ public:  protected:    SampleProfileWriterBinary(std::unique_ptr<raw_ostream> &OS) -      : SampleProfileWriter(OS), NameTable() {} +      : SampleProfileWriter(OS) {}    std::error_code    writeHeader(const StringMap<FunctionSamples> &ProfileMap) override; @@ -133,8 +136,7 @@ private:                                SampleProfileFormat Format);  }; -} // End namespace sampleprof - -} // End namespace llvm +} // end namespace sampleprof +} // end namespace llvm  #endif // LLVM_PROFILEDATA_SAMPLEPROFWRITER_H diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 6d907c7098e..23999a5312c 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -1,4 +1,4 @@ -//=-- CoverageMapping.cpp - Code coverage mapping support ---------*- C++ -*-=// +//===- CoverageMapping.cpp - Code coverage mapping support ------*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,18 +12,32 @@  //  //===----------------------------------------------------------------------===// -#include "llvm/ProfileData/Coverage/CoverageMapping.h" +#include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/None.h"  #include "llvm/ADT/Optional.h"  #include "llvm/ADT/SmallBitVector.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ProfileData/Coverage/CoverageMapping.h"  #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"  #include "llvm/ProfileData/InstrProfReader.h"  #include "llvm/Support/Debug.h"  #include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h"  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Path.h" +#include "llvm/Support/MemoryBuffer.h"  #include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <iterator> +#include <memory> +#include <string> +#include <system_error> +#include <utility> +#include <vector>  using namespace llvm;  using namespace coverage; @@ -59,7 +73,7 @@ void CounterExpressionBuilder::extractTerms(  Counter CounterExpressionBuilder::simplify(Counter ExpressionTree) {    // Gather constant terms. -  llvm::SmallVector<std::pair<unsigned, int>, 32> Terms; +  SmallVector<std::pair<unsigned, int>, 32> Terms;    extractTerms(ExpressionTree, +1, Terms);    // If there are no terms, this is just a zero. The algorithm below assumes at @@ -120,8 +134,7 @@ Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS) {        get(CounterExpression(CounterExpression::Subtract, LHS, RHS)));  } -void CounterMappingContext::dump(const Counter &C, -                                 llvm::raw_ostream &OS) const { +void CounterMappingContext::dump(const Counter &C, raw_ostream &OS) const {    switch (C.getKind()) {    case Counter::Zero:      OS << '0'; @@ -145,7 +158,7 @@ void CounterMappingContext::dump(const Counter &C,      return;    Expected<int64_t> Value = evaluate(C);    if (auto E = Value.takeError()) { -    llvm::consumeError(std::move(E)); +    consumeError(std::move(E));      return;    }    OS << '[' << *Value << ']'; @@ -217,7 +230,7 @@ Error CoverageMapping::loadFunctionRecord(    for (const auto &Region : Record.MappingRegions) {      Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);      if (auto E = ExecutionCount.takeError()) { -      llvm::consumeError(std::move(E)); +      consumeError(std::move(E));        return Error::success();      }      Function.pushRegion(Region, *ExecutionCount); @@ -281,6 +294,7 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,  }  namespace { +  /// \brief Distributes functions into instantiation sets.  ///  /// An instantiation set is a collection of functions that have the same source @@ -326,7 +340,7 @@ class SegmentBuilder {        Segments.pop_back();      DEBUG(dbgs() << "Segment at " << Line << ":" << Col);      // Set this region's count. -    if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion) { +    if (Region.Kind != CounterMappingRegion::SkippedRegion) {        DEBUG(dbgs() << " with count " << Region.ExecutionCount);        Segments.emplace_back(Line, Col, Region.ExecutionCount, IsRegionEntry);      } else @@ -380,10 +394,10 @@ class SegmentBuilder {        // in combineRegions(). Because we accumulate counter values only from        // regions of the same kind as the first region of the area, prefer        // CodeRegion to ExpansionRegion and ExpansionRegion to SkippedRegion. -      static_assert(coverage::CounterMappingRegion::CodeRegion < -                            coverage::CounterMappingRegion::ExpansionRegion && -                        coverage::CounterMappingRegion::ExpansionRegion < -                            coverage::CounterMappingRegion::SkippedRegion, +      static_assert(CounterMappingRegion::CodeRegion < +                            CounterMappingRegion::ExpansionRegion && +                        CounterMappingRegion::ExpansionRegion < +                            CounterMappingRegion::SkippedRegion,                      "Unexpected order of region kind values");        return LHS.Kind < RHS.Kind;      }); @@ -437,7 +451,8 @@ public:      return Segments;    }  }; -} + +} // end anonymous namespace  std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const {    std::vector<StringRef> Filenames; @@ -487,7 +502,7 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) {  CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {    CoverageData FileCoverage(Filename); -  std::vector<coverage::CountedRegion> Regions; +  std::vector<CountedRegion> Regions;    for (const auto &Function : Functions) {      auto MainFileID = findMainViewFileID(Filename, Function); @@ -533,7 +548,7 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const {      return CoverageData();    CoverageData FunctionCoverage(Function.Filenames[*MainFileID]); -  std::vector<coverage::CountedRegion> Regions; +  std::vector<CountedRegion> Regions;    for (const auto &CR : Function.CountedRegions)      if (CR.FileID == *MainFileID) {        Regions.push_back(CR); @@ -551,7 +566,7 @@ CoverageData CoverageMapping::getCoverageForExpansion(      const ExpansionRecord &Expansion) const {    CoverageData ExpansionCoverage(        Expansion.Function.Filenames[Expansion.FileID]); -  std::vector<coverage::CountedRegion> Regions; +  std::vector<CountedRegion> Regions;    for (const auto &CR : Expansion.Function.CountedRegions)      if (CR.FileID == Expansion.FileID) {        Regions.push_back(CR); @@ -566,8 +581,7 @@ CoverageData CoverageMapping::getCoverageForExpansion(    return ExpansionCoverage;  } -namespace { -std::string getCoverageMapErrString(coveragemap_error Err) { +static std::string getCoverageMapErrString(coveragemap_error Err) {    switch (Err) {    case coveragemap_error::success:      return "Success"; @@ -585,6 +599,8 @@ std::string getCoverageMapErrString(coveragemap_error Err) {    llvm_unreachable("A value of coveragemap_error has no message.");  } +namespace { +  // FIXME: This class is only here to support the transition to llvm::Error. It  // will be removed once this transition is complete. Clients should prefer to  // deal with the Error value directly, rather than converting to error_code. @@ -594,6 +610,7 @@ class CoverageMappingErrorCategoryType : public std::error_category {      return getCoverageMapErrString(static_cast<coveragemap_error>(IE));    }  }; +  } // end anonymous namespace  std::string CoverageMapError::message() const { diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index a6c7031ccd3..05c5b28d7a0 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp @@ -1,4 +1,4 @@ -//=-- CoverageMappingReader.cpp - Code coverage mapping reader ----*- C++ -*-=// +//===- CoverageMappingReader.cpp - Code coverage mapping reader -*- C++ -*-===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,15 +12,34 @@  //  //===----------------------------------------------------------------------===// -#include "llvm/ProfileData/Coverage/CoverageMappingReader.h" +#include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h"  +#include "llvm/Object/Binary.h" +#include "llvm/Object/Error.h"  #include "llvm/Object/MachOUniversal.h"  #include "llvm/Object/ObjectFile.h" +#include "llvm/ProfileData/Coverage/CoverageMappingReader.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/Support/Casting.h"  #include "llvm/Support/Debug.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/Endian.h"  #include "llvm/Support/LEB128.h"  #include "llvm/Support/MathExtras.h"  #include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <limits> +#include <memory> +#include <utility> +#include <vector>  using namespace llvm;  using namespace coverage; @@ -226,9 +245,8 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(  }  Error RawCoverageMappingReader::read() { -    // Read the virtual file mapping. -  llvm::SmallVector<unsigned, 8> VirtualFileMapping; +  SmallVector<unsigned, 8> VirtualFileMapping;    uint64_t NumFileMappings;    if (auto Err = readSize(NumFileMappings))      return Err; @@ -349,7 +367,10 @@ static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {  }  namespace { +  struct CovMapFuncRecordReader { +  virtual ~CovMapFuncRecordReader() = default; +    // The interface to read coverage mapping function records for a module.    //    // \p Buf points to the buffer containing the \c CovHeader of the coverage @@ -359,26 +380,24 @@ struct CovMapFuncRecordReader {    // greater than \p End if not.    virtual Expected<const char *> readFunctionRecords(const char *Buf,                                                       const char *End) = 0; -  virtual ~CovMapFuncRecordReader() {} +    template <class IntPtrT, support::endianness Endian>    static Expected<std::unique_ptr<CovMapFuncRecordReader>> -  get(coverage::CovMapVersion Version, InstrProfSymtab &P, +  get(CovMapVersion Version, InstrProfSymtab &P,        std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,        std::vector<StringRef> &F);  };  // A class for reading coverage mapping function records for a module. -template <coverage::CovMapVersion Version, class IntPtrT, -          support::endianness Endian> +template <CovMapVersion Version, class IntPtrT, support::endianness Endian>  class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader { -  typedef typename coverage::CovMapTraits< +  typedef typename CovMapTraits<        Version, IntPtrT>::CovMapFuncRecordType FuncRecordType; -  typedef typename coverage::CovMapTraits<Version, IntPtrT>::NameRefType -      NameRefType; +  typedef typename CovMapTraits<Version, IntPtrT>::NameRefType  NameRefType;    // Maps function's name references to the indexes of their records    // in \c Records. -  llvm::DenseMap<NameRefType, size_t> FunctionRecords; +  DenseMap<NameRefType, size_t> FunctionRecords;    InstrProfSymtab &ProfileNames;    std::vector<StringRef> &Filenames;    std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records; @@ -432,14 +451,16 @@ public:        std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,        std::vector<StringRef> &F)        : ProfileNames(P), Filenames(F), Records(R) {} -  ~VersionedCovMapFuncRecordReader() override {} + +  ~VersionedCovMapFuncRecordReader() override = default;    Expected<const char *> readFunctionRecords(const char *Buf,                                               const char *End) override {      using namespace support; +      if (Buf + sizeof(CovMapHeader) > End)        return make_error<CoverageMapError>(coveragemap_error::malformed); -    auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf); +    auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf);      uint32_t NRecords = CovHeader->getNRecords<Endian>();      uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();      uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>(); @@ -490,14 +511,16 @@ public:      return Buf;    }  }; +  } // end anonymous namespace  template <class IntPtrT, support::endianness Endian>  Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get( -    coverage::CovMapVersion Version, InstrProfSymtab &P, +    CovMapVersion Version, InstrProfSymtab &P,      std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,      std::vector<StringRef> &F) {    using namespace coverage; +    switch (Version) {    case CovMapVersion::Version1:      return llvm::make_unique<VersionedCovMapFuncRecordReader< @@ -518,11 +541,12 @@ static Error readCoverageMappingData(      std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,      std::vector<StringRef> &Filenames) {    using namespace coverage; +    // Read the records in the coverage data section.    auto CovHeader = -      reinterpret_cast<const coverage::CovMapHeader *>(Data.data()); +      reinterpret_cast<const CovMapHeader *>(Data.data());    CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>(); -  if (Version > coverage::CovMapVersion::CurrentVersion) +  if (Version > CovMapVersion::CurrentVersion)      return make_error<CoverageMapError>(coveragemap_error::unsupported_version);    Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =        CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records, @@ -538,6 +562,7 @@ static Error readCoverageMappingData(    }    return Error::success();  } +  static const char *TestingFormatMagic = "llvmcovmtestdata";  static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames, @@ -595,21 +620,21 @@ static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,                                StringRef &CoverageMapping,                                uint8_t &BytesInAddress,                                support::endianness &Endian, StringRef Arch) { -  auto BinOrErr = object::createBinary(ObjectBuffer); +  auto BinOrErr = createBinary(ObjectBuffer);    if (!BinOrErr)      return BinOrErr.takeError();    auto Bin = std::move(BinOrErr.get());    std::unique_ptr<ObjectFile> OF; -  if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) { +  if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {      // If we have a universal binary, try to look up the object for the      // appropriate architecture.      auto ObjectFileOrErr = Universal->getObjectForArch(Arch);      if (!ObjectFileOrErr)        return ObjectFileOrErr.takeError();      OF = std::move(ObjectFileOrErr.get()); -  } else if (isa<object::ObjectFile>(Bin.get())) { +  } else if (isa<ObjectFile>(Bin.get())) {      // For any other object file, upcast and take ownership. -    OF.reset(cast<object::ObjectFile>(Bin.release())); +    OF.reset(cast<ObjectFile>(Bin.release()));      // If we've asked for a particular arch, make sure they match.      if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())        return errorCodeToError(object_error::arch_not_found); diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp index 82356333b93..f131be2cba4 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp @@ -1,4 +1,4 @@ -//=-- CoverageMappingWriter.cpp - Code coverage mapping writer -------------=// +//===- CoverageMappingWriter.cpp - Code coverage mapping writer -----------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,8 +12,15 @@  //  //===----------------------------------------------------------------------===// +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallVector.h"  #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"  #include "llvm/Support/LEB128.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <limits> +#include <vector>  using namespace llvm;  using namespace coverage; @@ -27,14 +34,25 @@ void CoverageFilenamesSectionWriter::write(raw_ostream &OS) {  }  namespace { +  /// \brief Gather only the expressions that are used by the mapping  /// regions in this function.  class CounterExpressionsMinimizer {    ArrayRef<CounterExpression> Expressions; -  llvm::SmallVector<CounterExpression, 16> UsedExpressions; +  SmallVector<CounterExpression, 16> UsedExpressions;    std::vector<unsigned> AdjustedExpressionIDs;  public: +  CounterExpressionsMinimizer(ArrayRef<CounterExpression> Expressions, +                              ArrayRef<CounterMappingRegion> MappingRegions) +      : Expressions(Expressions) { +    AdjustedExpressionIDs.resize(Expressions.size(), 0); +    for (const auto &I : MappingRegions) +      mark(I.Count); +    for (const auto &I : MappingRegions) +      gatherUsed(I.Count); +  } +    void mark(Counter C) {      if (!C.isExpression())        return; @@ -54,16 +72,6 @@ public:      gatherUsed(E.RHS);    } -  CounterExpressionsMinimizer(ArrayRef<CounterExpression> Expressions, -                              ArrayRef<CounterMappingRegion> MappingRegions) -      : Expressions(Expressions) { -    AdjustedExpressionIDs.resize(Expressions.size(), 0); -    for (const auto &I : MappingRegions) -      mark(I.Count); -    for (const auto &I : MappingRegions) -      gatherUsed(I.Count); -  } -    ArrayRef<CounterExpression> getExpressions() const { return UsedExpressions; }    /// \brief Adjust the given counter to correctly transition from the old @@ -74,7 +82,8 @@ public:      return C;    }  }; -} + +} // end anonymous namespace  /// \brief Encode the counter.  /// diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 69cda2ccee2..ccaf15b9840 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -1,4 +1,4 @@ -//=-- InstrProf.cpp - Instrumented profiling format support -----------------=// +//===- InstrProf.cpp - Instrumented profiling format support --------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,19 +12,46 @@  //  //===----------------------------------------------------------------------===// -#include "llvm/ProfileData/InstrProf.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h"  #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringRef.h"  #include "llvm/ADT/Triple.h" +#include "llvm/IR/Constant.h"  #include "llvm/IR/Constants.h"  #include "llvm/IR/Function.h" +#include "llvm/IR/GlobalValue.h"  #include "llvm/IR/GlobalVariable.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/LLVMContext.h"  #include "llvm/IR/MDBuilder.h" +#include "llvm/IR/Metadata.h"  #include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Compiler.h"  #include "llvm/Support/Compression.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h"  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/LEB128.h"  #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MathExtras.h"  #include "llvm/Support/Path.h" +#include "llvm/Support/SwapByteOrder.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <cstring> +#include <cstdint> +#include <memory> +#include <string> +#include <system_error> +#include <utility> +#include <vector>  using namespace llvm; @@ -46,8 +73,7 @@ static cl::opt<unsigned> StaticFuncStripDirNamePrefix(      cl::desc("Strip specified level of directory name from source path in "               "the profile counter name for static functions.")); -namespace { -std::string getInstrProfErrString(instrprof_error Err) { +static std::string getInstrProfErrString(instrprof_error Err) {    switch (Err) {    case instrprof_error::success:      return "Success"; @@ -89,15 +115,19 @@ std::string getInstrProfErrString(instrprof_error Err) {    llvm_unreachable("A value of instrprof_error has no message.");  } +namespace { +  // FIXME: This class is only here to support the transition to llvm::Error. It  // will be removed once this transition is complete. Clients should prefer to  // deal with the Error value directly, rather than converting to error_code.  class InstrProfErrorCategoryType : public std::error_category {    const char *name() const noexcept override { return "llvm.instrprof"; } +    std::string message(int IE) const override {      return getInstrProfErrString(static_cast<instrprof_error>(IE));    }  }; +  } // end anonymous namespace  static ManagedStatic<InstrProfErrorCategoryType> ErrorCategory; @@ -231,7 +261,6 @@ std::string getPGOFuncNameVarName(StringRef FuncName,  GlobalVariable *createPGOFuncNameVar(Module &M,                                       GlobalValue::LinkageTypes Linkage,                                       StringRef PGOFuncName) { -    // We generally want to match the function's linkage, but available_externally    // and extern_weak both have the wrong semantics, and anything that doesn't    // need to link across compilation units doesn't need to be visible at all. @@ -276,7 +305,7 @@ void InstrProfSymtab::create(Module &M, bool InLTO) {  Error collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,                                  bool doCompression, std::string &Result) { -  assert(NameStrs.size() && "No name data to emit"); +  assert(!NameStrs.empty() && "No name data to emit");    uint8_t Header[16], *P = Header;    std::string UncompressedNameStrings = @@ -589,6 +618,7 @@ void ValueProfRecord::deserializeTo(InstrProfRecord &Record,  void ValueProfRecord::swapBytes(support::endianness Old,                                  support::endianness New) {    using namespace support; +    if (Old == New)      return; @@ -625,6 +655,7 @@ void ValueProfData::deserializeTo(InstrProfRecord &Record,  template <class T>  static T swapToHostOrder(const unsigned char *&D, support::endianness Orig) {    using namespace support; +    if (Orig == little)      return endian::readNext<T, little, unaligned>(D);    else @@ -659,6 +690,7 @@ ValueProfData::getValueProfData(const unsigned char *D,                                  const unsigned char *const BufferEnd,                                  support::endianness Endianness) {    using namespace support; +    if (D + sizeof(ValueProfData) > BufferEnd)      return make_error<InstrProfError>(instrprof_error::truncated); @@ -681,6 +713,7 @@ ValueProfData::getValueProfData(const unsigned char *D,  void ValueProfData::swapBytesToHost(support::endianness Endianness) {    using namespace support; +    if (Endianness == getHostEndianness())      return; @@ -696,6 +729,7 @@ void ValueProfData::swapBytesToHost(support::endianness Endianness) {  void ValueProfData::swapBytesFromHost(support::endianness Endianness) {    using namespace support; +    if (Endianness == getHostEndianness())      return; @@ -890,4 +924,5 @@ bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken) {    }    return true;  } +  } // end namespace llvm diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index cdc4593602f..0ba6cdb0c70 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -1,4 +1,4 @@ -//=-- InstrProfReader.cpp - Instrumented profiling reader -------------------=// +//===- InstrProfReader.cpp - Instrumented profiling reader ----------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,9 +12,27 @@  //  //===----------------------------------------------------------------------===// -#include "llvm/ProfileData/InstrProfReader.h" +#include "llvm/ADT/ArrayRef.h"  #include "llvm/ADT/STLExtras.h" -#include <cassert> +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/ProfileSummary.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/ProfileData/InstrProfReader.h" +#include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SwapByteOrder.h" +#include <algorithm> +#include <cctype> +#include <cstddef> +#include <cstdint> +#include <limits> +#include <memory> +#include <system_error> +#include <utility> +#include <vector>  using namespace llvm; @@ -78,7 +96,6 @@ IndexedInstrProfReader::create(const Twine &Path) {    return IndexedInstrProfReader::create(std::move(BufferOrError.get()));  } -  Expected<std::unique_ptr<IndexedInstrProfReader>>  IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {    // Sanity check the buffer. @@ -399,7 +416,6 @@ Error RawInstrProfReader<IntPtrT>::readRawCounts(  template <class IntPtrT>  Error RawInstrProfReader<IntPtrT>::readValueProfilingData(      InstrProfRecord &Record) { -    Record.clearValueData();    CurValueDataSize = 0;    // Need to match the logic in value profile dumper code in compiler-rt: @@ -455,9 +471,11 @@ Error RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {  }  namespace llvm { +  template class RawInstrProfReader<uint32_t>;  template class RawInstrProfReader<uint64_t>; -} + +} // end namespace llvm  InstrProfLookupTrait::hash_value_type  InstrProfLookupTrait::ComputeHash(StringRef K) { @@ -483,6 +501,8 @@ bool InstrProfLookupTrait::readValueProfilingData(  data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,                                           offset_type N) { +  using namespace support; +    // Check if the data is corrupt. If so, don't try to read it.    if (N % sizeof(uint64_t))      return data_type(); @@ -490,7 +510,6 @@ data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,    DataBuffer.clear();    std::vector<uint64_t> CounterBuffer; -  using namespace support;    const unsigned char *End = D + N;    while (D < End) {      // Read hash. @@ -568,9 +587,10 @@ InstrProfReaderIndex<HashTableImpl>::InstrProfReaderIndex(  }  bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) { +  using namespace support; +    if (DataBuffer.getBufferSize() < 8)      return false; -  using namespace support;    uint64_t Magic =        endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart());    // Verify that it's magical. @@ -582,6 +602,7 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,                                      const unsigned char *Cur) {    using namespace IndexedInstrProf;    using namespace support; +    if (Version >= IndexedInstrProf::Version4) {      const IndexedInstrProf::Summary *SummaryInLE =          reinterpret_cast<const IndexedInstrProf::Summary *>(Cur); @@ -618,6 +639,7 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,    } else {      // For older version of profile data, we need to compute on the fly:      using namespace IndexedInstrProf; +      InstrProfSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);      // FIXME: This only computes an empty summary. Need to call addRecord for      // all InstrProfRecords to get the correct summary. @@ -627,14 +649,14 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,  }  Error IndexedInstrProfReader::readHeader() { +  using namespace support; +    const unsigned char *Start =        (const unsigned char *)DataBuffer->getBufferStart();    const unsigned char *Cur = Start;    if ((const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)      return error(instrprof_error::truncated); -  using namespace support; -    auto *Header = reinterpret_cast<const IndexedInstrProf::Header *>(Cur);    Cur += sizeof(IndexedInstrProf::Header); diff --git a/llvm/lib/ProfileData/InstrProfWriter.cpp b/llvm/lib/ProfileData/InstrProfWriter.cpp index 029d75660a7..6b7bd3b2fc0 100644 --- a/llvm/lib/ProfileData/InstrProfWriter.cpp +++ b/llvm/lib/ProfileData/InstrProfWriter.cpp @@ -1,4 +1,4 @@ -//=-- InstrProfWriter.cpp - Instrumented profiling writer -------------------=// +//===- InstrProfWriter.cpp - Instrumented profiling writer ----------------===//  //  //                     The LLVM Compiler Infrastructure  // @@ -12,15 +12,21 @@  //  //===----------------------------------------------------------------------===// -#include "llvm/ProfileData/InstrProfWriter.h" +#include "llvm/ADT/STLExtras.h"  #include "llvm/ADT/StringRef.h"  #include "llvm/IR/ProfileSummary.h" +#include "llvm/ProfileData/InstrProf.h" +#include "llvm/ProfileData/InstrProfWriter.h"  #include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/Support/Endian.h"  #include "llvm/Support/EndianStream.h" +#include "llvm/Support/Error.h"  #include "llvm/Support/MemoryBuffer.h"  #include "llvm/Support/OnDiskHashTable.h"  #include "llvm/Support/raw_ostream.h"  #include <algorithm> +#include <cstdint> +#include <memory>  #include <string>  #include <tuple>  #include <utility> @@ -41,10 +47,9 @@ namespace llvm {  // A wrapper class to abstract writer stream with support of bytes  // back patching.  class ProfOStream { -  public: -  ProfOStream(llvm::raw_fd_ostream &FD) : IsFDOStream(true), OS(FD), LE(FD) {} -  ProfOStream(llvm::raw_string_ostream &STR) +  ProfOStream(raw_fd_ostream &FD) : IsFDOStream(true), OS(FD), LE(FD) {} +  ProfOStream(raw_string_ostream &STR)        : IsFDOStream(false), OS(STR), LE(STR) {}    uint64_t tell() { return OS.tell(); } @@ -55,15 +60,16 @@ public:    // directly and it won't be reflected in the stream's internal buffer.    void patch(PatchItem *P, int NItems) {      using namespace support; +      if (IsFDOStream) { -      llvm::raw_fd_ostream &FDOStream = static_cast<llvm::raw_fd_ostream &>(OS); +      raw_fd_ostream &FDOStream = static_cast<raw_fd_ostream &>(OS);        for (int K = 0; K < NItems; K++) {          FDOStream.seek(P[K].Pos);          for (int I = 0; I < P[K].N; I++)            write(P[K].D[I]);        }      } else { -      llvm::raw_string_ostream &SOStream = +      raw_string_ostream &SOStream =            static_cast<llvm::raw_string_ostream &>(OS);        std::string &Data = SOStream.str(); // with flush        for (int K = 0; K < NItems; K++) { @@ -94,17 +100,19 @@ public:    typedef uint64_t hash_value_type;    typedef uint64_t offset_type; -  support::endianness ValueProfDataEndianness; +  support::endianness ValueProfDataEndianness = support::little;    InstrProfSummaryBuilder *SummaryBuilder; -  InstrProfRecordWriterTrait() : ValueProfDataEndianness(support::little) {} +  InstrProfRecordWriterTrait() = default; +    static hash_value_type ComputeHash(key_type_ref K) {      return IndexedInstrProf::ComputeHash(K);    }    static std::pair<offset_type, offset_type>    EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V) { -    using namespace llvm::support; +    using namespace support; +      endian::Writer<little> LE(Out);      offset_type N = K.size(); @@ -130,7 +138,8 @@ public:    }    void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type) { -    using namespace llvm::support; +    using namespace support; +      endian::Writer<little> LE(Out);      for (const auto &ProfileData : *V) {        const InstrProfRecord &ProfRecord = ProfileData.second; @@ -154,8 +163,7 @@ public:  } // end namespace llvm  InstrProfWriter::InstrProfWriter(bool Sparse) -    : Sparse(Sparse), FunctionData(), ProfileKind(PF_Unknown), -      InfoObj(new InstrProfRecordWriterTrait()) {} +    : Sparse(Sparse), InfoObj(new InstrProfRecordWriterTrait()) {}  InstrProfWriter::~InstrProfWriter() { delete InfoObj; } @@ -208,7 +216,7 @@ bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) {      return true;    for (const auto &Func : PD) {      const InstrProfRecord &IPR = Func.second; -    if (any_of(IPR.Counts, [](uint64_t Count) { return Count > 0; })) +    if (llvm::any_of(IPR.Counts, [](uint64_t Count) { return Count > 0; }))        return true;    }    return false; @@ -217,6 +225,7 @@ bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) {  static void setSummary(IndexedInstrProf::Summary *TheSummary,                         ProfileSummary &PS) {    using namespace IndexedInstrProf; +    std::vector<ProfileSummaryEntry> &Res = PS.getDetailedSummary();    TheSummary->NumSummaryFields = Summary::NumKinds;    TheSummary->NumCutoffEntries = Res.size(); @@ -231,9 +240,10 @@ static void setSummary(IndexedInstrProf::Summary *TheSummary,  }  void InstrProfWriter::writeImpl(ProfOStream &OS) { +  using namespace IndexedInstrProf; +    OnDiskChainedHashTableGenerator<InstrProfRecordWriterTrait> Generator; -  using namespace IndexedInstrProf;    InstrProfSummaryBuilder ISB(ProfileSummaryBuilder::DefaultCutoffs);    InfoObj->SummaryBuilder = &ISB; @@ -301,7 +311,7 @@ void InstrProfWriter::write(raw_fd_ostream &OS) {  std::unique_ptr<MemoryBuffer> InstrProfWriter::writeBuffer() {    std::string Data; -  llvm::raw_string_ostream OS(Data); +  raw_string_ostream OS(Data);    ProfOStream POS(OS);    // Write the hash table.    writeImpl(POS); diff --git a/llvm/lib/ProfileData/SampleProf.cpp b/llvm/lib/ProfileData/SampleProf.cpp index 8fe85d69bb6..8493acc2d95 100644 --- a/llvm/lib/ProfileData/SampleProf.cpp +++ b/llvm/lib/ProfileData/SampleProf.cpp @@ -13,18 +13,25 @@  //===----------------------------------------------------------------------===//  #include "llvm/ProfileData/SampleProf.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h"  #include "llvm/Support/ErrorHandling.h"  #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/raw_ostream.h" +#include <string> +#include <system_error> -using namespace llvm::sampleprof;  using namespace llvm; +using namespace sampleprof;  namespace { +  // FIXME: This class is only here to support the transition to llvm::Error. It  // will be removed once this transition is complete. Clients should prefer to  // deal with the Error value directly, rather than converting to error_code.  class SampleProfErrorCategoryType : public std::error_category {    const char *name() const noexcept override { return "llvm.sampleprof"; } +    std::string message(int IE) const override {      sampleprof_error E = static_cast<sampleprof_error>(IE);      switch (E) { @@ -54,7 +61,8 @@ class SampleProfErrorCategoryType : public std::error_category {      llvm_unreachable("A value of sampleprof_error has no message.");    }  }; -} + +} // end anonymous namespace  static ManagedStatic<SampleProfErrorCategoryType> ErrorCategory; @@ -105,7 +113,7 @@ void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const {       << " sampled lines\n";    OS.indent(Indent); -  if (BodySamples.size() > 0) { +  if (!BodySamples.empty()) {      OS << "Samples collected in the function's body {\n";      SampleSorter<LineLocation, SampleRecord> SortedBodySamples(BodySamples);      for (const auto &SI : SortedBodySamples.get()) { @@ -119,7 +127,7 @@ void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const {    }    OS.indent(Indent); -  if (CallsiteSamples.size() > 0) { +  if (!CallsiteSamples.empty()) {      OS << "Samples collected in inlined callsites {\n";      SampleSorter<LineLocation, FunctionSamples> SortedCallsiteSamples(          CallsiteSamples); @@ -141,5 +149,5 @@ raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS,  }  #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void FunctionSamples::dump(void) const { print(dbgs(), 0); } +LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); }  #endif diff --git a/llvm/lib/ProfileData/SampleProfReader.cpp b/llvm/lib/ProfileData/SampleProfReader.cpp index 6d063602fb2..3a8d6190d2c 100644 --- a/llvm/lib/ProfileData/SampleProfReader.cpp +++ b/llvm/lib/ProfileData/SampleProfReader.cpp @@ -23,14 +23,25 @@  #include "llvm/ProfileData/SampleProfReader.h"  #include "llvm/ADT/DenseMap.h"  #include "llvm/ADT/STLExtras.h" -#include "llvm/Support/Debug.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/ProfileSummary.h" +#include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/ProfileData/SampleProf.h"  #include "llvm/Support/ErrorOr.h"  #include "llvm/Support/LEB128.h"  #include "llvm/Support/LineIterator.h"  #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cstddef> +#include <cstdint> +#include <limits> +#include <memory> +#include <system_error> +#include <vector> -using namespace llvm::sampleprof;  using namespace llvm; +using namespace sampleprof;  /// \brief Dump the function profile for \p FName.  /// diff --git a/llvm/lib/ProfileData/SampleProfWriter.cpp b/llvm/lib/ProfileData/SampleProfWriter.cpp index 4fa71288f8d..e1d6d575631 100644 --- a/llvm/lib/ProfileData/SampleProfWriter.cpp +++ b/llvm/lib/ProfileData/SampleProfWriter.cpp @@ -18,16 +18,23 @@  //  //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringRef.h" +#include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/ProfileData/SampleProf.h"  #include "llvm/ProfileData/SampleProfWriter.h" -#include "llvm/Support/Debug.h"  #include "llvm/Support/ErrorOr.h" +#include "llvm/Support/FileSystem.h"  #include "llvm/Support/LEB128.h" -#include "llvm/Support/LineIterator.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Regex.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cstdint> +#include <memory> +#include <system_error> +#include <utility> +#include <vector> -using namespace llvm::sampleprof;  using namespace llvm; +using namespace sampleprof;  /// \brief Write samples to a text file.  ///  | 

