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