summaryrefslogtreecommitdiff
path: root/include/llvm/ProfileData
diff options
context:
space:
mode:
Diffstat (limited to 'include/llvm/ProfileData')
-rw-r--r--include/llvm/ProfileData/Coverage/CoverageMapping.h79
-rw-r--r--include/llvm/ProfileData/Coverage/CoverageMappingReader.h46
-rw-r--r--include/llvm/ProfileData/Coverage/CoverageMappingWriter.h15
-rw-r--r--include/llvm/ProfileData/InstrProf.h171
-rw-r--r--include/llvm/ProfileData/InstrProfData.inc84
-rw-r--r--include/llvm/ProfileData/InstrProfReader.h88
-rw-r--r--include/llvm/ProfileData/InstrProfWriter.h20
-rw-r--r--include/llvm/ProfileData/ProfileCommon.h54
-rw-r--r--include/llvm/ProfileData/SampleProf.h124
-rw-r--r--include/llvm/ProfileData/SampleProfReader.h29
-rw-r--r--include/llvm/ProfileData/SampleProfWriter.h20
11 files changed, 485 insertions, 245 deletions
diff --git a/include/llvm/ProfileData/Coverage/CoverageMapping.h b/include/llvm/ProfileData/Coverage/CoverageMapping.h
index d6051ffb3f8d0..b9a9f53776984 100644
--- a/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/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/include/llvm/ProfileData/Coverage/CoverageMappingReader.h b/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
index db907f128d931..5b372252a9ac9 100644
--- a/include/llvm/ProfileData/Coverage/CoverageMappingReader.h
+++ b/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/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h b/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
index 24fb94647247c..b6f864ab3de38 100644
--- a/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h
+++ b/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/include/llvm/ProfileData/InstrProf.h b/include/llvm/ProfileData/InstrProf.h
index c7e558efa3dcc..c9828858cce3a 100644
--- a/include/llvm/ProfileData/InstrProf.h
+++ b/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,62 +16,57 @@
#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/ADT/Triple.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.
-inline StringRef getInstrProfCountersSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_CNTS_SECT_NAME_STR
- : INSTR_PROF_CNTS_SECT_NAME_STR;
-}
-
-/// Return the name of data section containing names of instrumented
-/// functions.
-inline StringRef getInstrProfNameSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_NAME_SECT_NAME_STR
- : INSTR_PROF_NAME_SECT_NAME_STR;
-}
-
-/// Return the name of the data section containing per-function control
-/// data.
-inline StringRef getInstrProfDataSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_DATA_SECT_NAME_STR
- ",regular,live_support"
- : INSTR_PROF_DATA_SECT_NAME_STR;
-}
-
-/// Return the name of data section containing pointers to value profile
-/// counters/nodes.
-inline StringRef getInstrProfValuesSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_VALS_SECT_NAME_STR
- : INSTR_PROF_VALS_SECT_NAME_STR;
-}
+enum InstrProfSectKind {
+#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) Kind,
+#include "llvm/ProfileData/InstrProfData.inc"
+};
-/// Return the name of data section containing nodes holdling value
-/// profiling data.
-inline StringRef getInstrProfVNodesSectionName(bool AddSegment) {
- return AddSegment ? "__DATA," INSTR_PROF_VNODES_SECT_NAME_STR
- : INSTR_PROF_VNODES_SECT_NAME_STR;
-}
+/// Return the name of the profile section corresponding to \p IPSK.
+///
+/// The name of the section depends on the object format type \p OF. If
+/// \p AddSegmentInfo is true, a segment prefix and additional linker hints may
+/// be added to the section name (this is the default).
+std::string getInstrProfSectionName(InstrProfSectKind IPSK,
+ Triple::ObjectFormatType OF,
+ bool AddSegmentInfo = true);
/// Return the name profile runtime entry point to do value profiling
/// for a given site.
@@ -79,12 +74,18 @@ inline StringRef getInstrProfValueProfFuncName() {
return INSTR_PROF_VALUE_PROF_FUNC_STR;
}
+/// Return the name profile runtime entry point to do value range profiling.
+inline StringRef getInstrProfValueRangeProfFuncName() {
+ return INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR;
+}
+
/// Return the name of the section containing function coverage mapping
/// data.
-inline StringRef getInstrProfCoverageSectionName(bool AddSegment) {
- return AddSegment ? "__LLVM_COV," INSTR_PROF_COVMAP_SECT_NAME_STR
- : INSTR_PROF_COVMAP_SECT_NAME_STR;
-}
+std::string getInstrProfCoverageSectionName(const Module *M = nullptr);
+/// Similar to the above, but used by host tool (e.g, coverage) which has
+/// object format information. The section name returned is not prefixed
+/// with segment name.
+std::string getInstrProfCoverageSectionNameInObject(bool isCoff);
/// Return the name prefix of variables containing instrumented function names.
inline StringRef getInstrProfNameVarPrefix() { return "__profn_"; }
@@ -201,6 +202,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 +222,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 +247,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 +254,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 +349,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 +400,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 +422,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 +435,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 +444,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 +478,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 +593,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,
@@ -635,6 +657,13 @@ struct InstrProfRecord {
SR.sortByCount();
}
}
+
+ /// Clear value data entries and edge counters.
+ void Clear() {
+ Counts.clear();
+ clearValueData();
+ }
+
/// Clear value data entries
void clearValueData() {
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
@@ -646,11 +675,15 @@ struct InstrProfRecord {
private:
std::vector<InstrProfValueSiteRecord> IndirectCallSites;
+ std::vector<InstrProfValueSiteRecord> MemOPSizes;
const std::vector<InstrProfValueSiteRecord> &
+
getValueSitesForKind(uint32_t ValueKind) const {
switch (ValueKind) {
case IPVK_IndirectCallTarget:
return IndirectCallSites;
+ case IPVK_MemOPSize:
+ return MemOPSizes;
default:
llvm_unreachable("Unknown value kind!");
}
@@ -672,6 +705,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 +740,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 +796,6 @@ namespace IndexedInstrProf {
enum class HashT : uint32_t {
MD5,
-
Last = MD5
};
@@ -816,7 +849,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 +889,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 +912,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 +930,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 {
@@ -937,6 +974,10 @@ struct Header {
} // end namespace RawInstrProf
+// Parse MemOP Size range option.
+void getMemOPSizeRangeFromOption(std::string Str, int64_t &RangeStart,
+ int64_t &RangeLast);
+
} // end namespace llvm
#endif // LLVM_PROFILEDATA_INSTRPROF_H
diff --git a/include/llvm/ProfileData/InstrProfData.inc b/include/llvm/ProfileData/InstrProfData.inc
index f7c22d10763c5..be0dd4ad04bf6 100644
--- a/include/llvm/ProfileData/InstrProfData.inc
+++ b/include/llvm/ProfileData/InstrProfData.inc
@@ -153,7 +153,17 @@ INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last)
VALUE_PROF_FUNC_PARAM(uint64_t, TargetValue, Type::getInt64Ty(Ctx)) \
INSTR_PROF_COMMA
VALUE_PROF_FUNC_PARAM(void *, Data, Type::getInt8PtrTy(Ctx)) INSTR_PROF_COMMA
+#ifndef VALUE_RANGE_PROF
VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx))
+#else /* VALUE_RANGE_PROF */
+VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx)) \
+ INSTR_PROF_COMMA
+VALUE_PROF_FUNC_PARAM(uint64_t, PreciseRangeStart, Type::getInt64Ty(Ctx)) \
+ INSTR_PROF_COMMA
+VALUE_PROF_FUNC_PARAM(uint64_t, PreciseRangeLast, Type::getInt64Ty(Ctx)) \
+ INSTR_PROF_COMMA
+VALUE_PROF_FUNC_PARAM(uint64_t, LargeValue, Type::getInt64Ty(Ctx))
+#endif /*VALUE_RANGE_PROF */
#undef VALUE_PROF_FUNC_PARAM
#undef INSTR_PROF_COMMA
/* VALUE_PROF_FUNC_PARAM end */
@@ -174,13 +184,15 @@ VALUE_PROF_FUNC_PARAM(uint32_t, CounterIndex, Type::getInt32Ty(Ctx))
* name hash and the function address.
*/
VALUE_PROF_KIND(IPVK_IndirectCallTarget, 0)
+/* For memory intrinsic functions size profiling. */
+VALUE_PROF_KIND(IPVK_MemOPSize, 1)
/* These two kinds must be the last to be
* declared. This is to make sure the string
* array created with the template can be
* indexed with the kind value.
*/
VALUE_PROF_KIND(IPVK_First, IPVK_IndirectCallTarget)
-VALUE_PROF_KIND(IPVK_Last, IPVK_IndirectCallTarget)
+VALUE_PROF_KIND(IPVK_Last, IPVK_MemOPSize)
#undef VALUE_PROF_KIND
/* VALUE_PROF_KIND end */
@@ -234,6 +246,31 @@ COVMAP_HEADER(uint32_t, Int32Ty, Version, \
/* COVMAP_HEADER end. */
+#ifdef INSTR_PROF_SECT_ENTRY
+#define INSTR_PROF_DATA_DEFINED
+INSTR_PROF_SECT_ENTRY(IPSK_data, \
+ INSTR_PROF_QUOTE(INSTR_PROF_DATA_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_DATA_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_cnts, \
+ INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_CNTS_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_name, \
+ INSTR_PROF_QUOTE(INSTR_PROF_NAME_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_NAME_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_vals, \
+ INSTR_PROF_QUOTE(INSTR_PROF_VALS_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_VALS_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_vnodes, \
+ INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_VNODES_COFF), "__DATA,")
+INSTR_PROF_SECT_ENTRY(IPSK_covmap, \
+ INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COMMON), \
+ INSTR_PROF_QUOTE(INSTR_PROF_COVMAP_COFF), "__LLVM_COV,")
+
+#undef INSTR_PROF_SECT_ENTRY
+#endif
+
+
#ifdef INSTR_PROF_VALUE_PROF_DATA
#define INSTR_PROF_DATA_DEFINED
@@ -610,17 +647,47 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
* specified via command line. */
#define INSTR_PROF_PROFILE_NAME_VAR __llvm_profile_filename
+/* section name strings common to all targets other
+ than WIN32 */
+#define INSTR_PROF_DATA_COMMON __llvm_prf_data
+#define INSTR_PROF_NAME_COMMON __llvm_prf_names
+#define INSTR_PROF_CNTS_COMMON __llvm_prf_cnts
+#define INSTR_PROF_VALS_COMMON __llvm_prf_vals
+#define INSTR_PROF_VNODES_COMMON __llvm_prf_vnds
+#define INSTR_PROF_COVMAP_COMMON __llvm_covmap
+/* Win32 */
+#define INSTR_PROF_DATA_COFF .lprfd
+#define INSTR_PROF_NAME_COFF .lprfn
+#define INSTR_PROF_CNTS_COFF .lprfc
+#define INSTR_PROF_VALS_COFF .lprfv
+#define INSTR_PROF_VNODES_COFF .lprfnd
+#define INSTR_PROF_COVMAP_COFF .lcovmap
+
+#ifdef _WIN32
/* Runtime section names and name strings. */
-#define INSTR_PROF_DATA_SECT_NAME __llvm_prf_data
-#define INSTR_PROF_NAME_SECT_NAME __llvm_prf_names
-#define INSTR_PROF_CNTS_SECT_NAME __llvm_prf_cnts
+#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COFF
+#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COFF
+#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COFF
/* Array of pointers. Each pointer points to a list
* of value nodes associated with one value site.
*/
-#define INSTR_PROF_VALS_SECT_NAME __llvm_prf_vals
+#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COFF
/* Value profile nodes section. */
-#define INSTR_PROF_VNODES_SECT_NAME __llvm_prf_vnds
-#define INSTR_PROF_COVMAP_SECT_NAME __llvm_covmap
+#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COFF
+#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COFF
+#else
+/* Runtime section names and name strings. */
+#define INSTR_PROF_DATA_SECT_NAME INSTR_PROF_DATA_COMMON
+#define INSTR_PROF_NAME_SECT_NAME INSTR_PROF_NAME_COMMON
+#define INSTR_PROF_CNTS_SECT_NAME INSTR_PROF_CNTS_COMMON
+/* Array of pointers. Each pointer points to a list
+ * of value nodes associated with one value site.
+ */
+#define INSTR_PROF_VALS_SECT_NAME INSTR_PROF_VALS_COMMON
+/* Value profile nodes section. */
+#define INSTR_PROF_VNODES_SECT_NAME INSTR_PROF_VNODES_COMMON
+#define INSTR_PROF_COVMAP_SECT_NAME INSTR_PROF_COVMAP_COMMON
+#endif
#define INSTR_PROF_DATA_SECT_NAME_STR \
INSTR_PROF_QUOTE(INSTR_PROF_DATA_SECT_NAME)
@@ -649,6 +716,9 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure,
#define INSTR_PROF_VALUE_PROF_FUNC __llvm_profile_instrument_target
#define INSTR_PROF_VALUE_PROF_FUNC_STR \
INSTR_PROF_QUOTE(INSTR_PROF_VALUE_PROF_FUNC)
+#define INSTR_PROF_VALUE_RANGE_PROF_FUNC __llvm_profile_instrument_range
+#define INSTR_PROF_VALUE_RANGE_PROF_FUNC_STR \
+ INSTR_PROF_QUOTE(INSTR_PROF_VALUE_RANGE_PROF_FUNC)
/* InstrProfile per-function control data alignment. */
#define INSTR_PROF_DATA_ALIGNMENT 8
diff --git a/include/llvm/ProfileData/InstrProfReader.h b/include/llvm/ProfileData/InstrProfReader.h
index 65b11f61d10bc..1d85a7149afc8 100644
--- a/include/llvm/ProfileData/InstrProfReader.h
+++ b/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/include/llvm/ProfileData/InstrProfWriter.h b/include/llvm/ProfileData/InstrProfWriter.h
index f7780fb450048..10742c0228ebe 100644
--- a/include/llvm/ProfileData/InstrProfWriter.h
+++ b/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/include/llvm/ProfileData/ProfileCommon.h b/include/llvm/ProfileData/ProfileCommon.h
index e955755e5c9a5..987e3160ccae2 100644
--- a/include/llvm/ProfileData/ProfileCommon.h
+++ b/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/include/llvm/ProfileData/SampleProf.h b/include/llvm/ProfileData/SampleProf.h
index a96f83620f8b5..7a705ca5416da 100644
--- a/include/llvm/ProfileData/SampleProf.h
+++ b/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,20 +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 {
@@ -59,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() {
@@ -87,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);
@@ -114,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.
@@ -144,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; }
@@ -163,7 +176,7 @@ public:
void dump() const;
private:
- uint64_t NumSamples;
+ uint64_t NumSamples = 0;
CallTargetMap CallTargets;
};
@@ -171,7 +184,8 @@ raw_ostream &operator<<(raw_ostream &OS, const SampleRecord &Sample);
typedef std::map<LineLocation, SampleRecord> BodySampleMap;
class FunctionSamples;
-typedef std::map<LineLocation, FunctionSamples> CallsiteSampleMap;
+typedef StringMap<FunctionSamples> FunctionSamplesMap;
+typedef std::map<LineLocation, FunctionSamplesMap> CallsiteSampleMap;
/// Representation of the samples collected for a function.
///
@@ -180,9 +194,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 =
@@ -190,6 +206,7 @@ public:
return Overflowed ? sampleprof_error::counter_overflow
: sampleprof_error::success;
}
+
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight = 1) {
bool Overflowed;
TotalHeadSamples =
@@ -197,11 +214,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,
@@ -222,34 +241,53 @@ public:
return ret->second.getSamples();
}
- /// Return the total number of call target samples collected at a given
- /// location. Each location is specified by \p LineOffset and
- /// \p Discriminator. If the location is not found in profile, return error.
- ErrorOr<uint64_t> findCallSamplesAt(uint32_t LineOffset,
- uint32_t Discriminator) const {
+ /// Returns the call target map collected at a given location.
+ /// Each location is specified by \p LineOffset and \p Discriminator.
+ /// If the location is not found in profile, return error.
+ ErrorOr<SampleRecord::CallTargetMap>
+ findCallTargetMapAt(uint32_t LineOffset, uint32_t Discriminator) const {
const auto &ret = BodySamples.find(LineLocation(LineOffset, Discriminator));
if (ret == BodySamples.end())
return std::error_code();
- uint64_t T = 0;
- for (const auto &t_c : ret->second.getCallTargets()) {
- T += t_c.second;
- }
- return T;
+ return ret->second.getCallTargets();
}
/// Return the function samples at the given callsite location.
- FunctionSamples &functionSamplesAt(const LineLocation &Loc) {
+ FunctionSamplesMap &functionSamplesAt(const LineLocation &Loc) {
return CallsiteSamples[Loc];
}
- /// Return a pointer to function samples at the given callsite location.
- const FunctionSamples *findFunctionSamplesAt(const LineLocation &Loc) const {
+ /// Returns the FunctionSamplesMap at the given \p Loc.
+ const FunctionSamplesMap *
+ findFunctionSamplesMapAt(const LineLocation &Loc) const {
auto iter = CallsiteSamples.find(Loc);
- if (iter == CallsiteSamples.end()) {
+ if (iter == CallsiteSamples.end())
return nullptr;
- } else {
- return &iter->second;
- }
+ return &iter->second;
+ }
+
+ /// Returns a pointer to FunctionSamples at the given callsite location \p Loc
+ /// with callee \p CalleeName. If no callsite can be found, relax the
+ /// restriction to return the FunctionSamples at callsite location \p Loc
+ /// with the maximum total sample count.
+ const FunctionSamples *findFunctionSamplesAt(const LineLocation &Loc,
+ StringRef CalleeName) const {
+ auto iter = CallsiteSamples.find(Loc);
+ if (iter == CallsiteSamples.end())
+ return nullptr;
+ auto FS = iter->second.find(CalleeName);
+ if (FS != iter->second.end())
+ return &FS->getValue();
+ // If we cannot find exact match of the callee name, return the FS with
+ // the max total count.
+ uint64_t MaxTotalSamples = 0;
+ const FunctionSamples *R = nullptr;
+ for (const auto &NameFS : iter->second)
+ if (NameFS.second.getTotalSamples() >= MaxTotalSamples) {
+ MaxTotalSamples = NameFS.second.getTotalSamples();
+ R = &NameFS.second;
+ }
+ return R;
}
bool empty() const { return TotalSamples == 0; }
@@ -283,12 +321,28 @@ public:
}
for (const auto &I : Other.getCallsiteSamples()) {
const LineLocation &Loc = I.first;
- const FunctionSamples &Rec = I.second;
- MergeResult(Result, functionSamplesAt(Loc).merge(Rec, Weight));
+ FunctionSamplesMap &FSMap = functionSamplesAt(Loc);
+ for (const auto &Rec : I.second)
+ MergeResult(Result, FSMap[Rec.first()].merge(Rec.second, Weight));
}
return Result;
}
+ /// Recursively traverses all children, if the corresponding function is
+ /// not defined in module \p M, and its total sample is no less than
+ /// \p Threshold, add its corresponding GUID to \p S.
+ void findImportedFunctions(DenseSet<GlobalValue::GUID> &S, const Module *M,
+ uint64_t Threshold) const {
+ if (TotalSamples <= Threshold)
+ return;
+ Function *F = M->getFunction(Name);
+ if (!F || !F->getSubprogram())
+ S.insert(Function::getGUID(Name));
+ for (auto CS : CallsiteSamples)
+ for (const auto &NameFS : CS.second)
+ NameFS.second.findImportedFunctions(S, M, Threshold);
+ }
+
/// Set the name of the function.
void setName(StringRef FunctionName) { Name = FunctionName; }
@@ -303,12 +357,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.
///
@@ -355,6 +409,7 @@ public:
return A->first < B->first;
});
}
+
const SamplesWithLocList &get() const { return V; }
private:
@@ -362,7 +417,6 @@ private:
};
} // end namespace sampleprof
-
} // end namespace llvm
-#endif // LLVM_PROFILEDATA_SAMPLEPROF_H_
+#endif // LLVM_PROFILEDATA_SAMPLEPROF_H
diff --git a/include/llvm/ProfileData/SampleProfReader.h b/include/llvm/ProfileData/SampleProfReader.h
index bf86721709c7b..29e3aba3e0e76 100644
--- a/include/llvm/ProfileData/SampleProfReader.h
+++ b/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;
@@ -275,7 +283,12 @@ public:
/// \brief Return the samples collected for function \p F.
FunctionSamples *getSamplesFor(const Function &F) {
- return &Profiles[F.getName()];
+ // The function name may have been updated by adding suffix. In sample
+ // profile, the function names are all stripped, so we need to strip
+ // the function name suffix before matching with profile.
+ if (Profiles.count(F.getName().split('.').first))
+ return &Profiles[(F.getName().split('.').first)];
+ return nullptr;
}
/// \brief Return all the profiles.
@@ -442,8 +455,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/include/llvm/ProfileData/SampleProfWriter.h b/include/llvm/ProfileData/SampleProfWriter.h
index f6f2e2702e316..9d69af32dd46a 100644
--- a/include/llvm/ProfileData/SampleProfWriter.h
+++ b/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