aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/lib/ProfileData
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/ProfileData')
-rw-r--r--contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp55
-rw-r--r--contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp74
-rw-r--r--contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp35
-rw-r--r--contrib/llvm/lib/ProfileData/InstrProf.cpp174
-rw-r--r--contrib/llvm/lib/ProfileData/InstrProfReader.cpp49
-rw-r--r--contrib/llvm/lib/ProfileData/InstrProfWriter.cpp42
-rw-r--r--contrib/llvm/lib/ProfileData/SampleProf.cpp34
-rw-r--r--contrib/llvm/lib/ProfileData/SampleProfReader.cpp31
-rw-r--r--contrib/llvm/lib/ProfileData/SampleProfWriter.cpp70
9 files changed, 416 insertions, 148 deletions
diff --git a/contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 6d907c7098e0..23999a5312c7 100644
--- a/contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/contrib/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -1,4 +1,4 @@
-//=-- CoverageMapping.cpp - Code coverage mapping support ---------*- C++ -*-=//
+//===- CoverageMapping.cpp - Code coverage mapping support ------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,18 +12,32 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ProfileData/Coverage/CoverageMapping.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/None.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SmallBitVector.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ProfileData/Coverage/CoverageMapping.h"
#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
-#include "llvm/Support/Path.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <iterator>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <vector>
using namespace llvm;
using namespace coverage;
@@ -59,7 +73,7 @@ void CounterExpressionBuilder::extractTerms(
Counter CounterExpressionBuilder::simplify(Counter ExpressionTree) {
// Gather constant terms.
- llvm::SmallVector<std::pair<unsigned, int>, 32> Terms;
+ SmallVector<std::pair<unsigned, int>, 32> Terms;
extractTerms(ExpressionTree, +1, Terms);
// If there are no terms, this is just a zero. The algorithm below assumes at
@@ -120,8 +134,7 @@ Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS) {
get(CounterExpression(CounterExpression::Subtract, LHS, RHS)));
}
-void CounterMappingContext::dump(const Counter &C,
- llvm::raw_ostream &OS) const {
+void CounterMappingContext::dump(const Counter &C, raw_ostream &OS) const {
switch (C.getKind()) {
case Counter::Zero:
OS << '0';
@@ -145,7 +158,7 @@ void CounterMappingContext::dump(const Counter &C,
return;
Expected<int64_t> Value = evaluate(C);
if (auto E = Value.takeError()) {
- llvm::consumeError(std::move(E));
+ consumeError(std::move(E));
return;
}
OS << '[' << *Value << ']';
@@ -217,7 +230,7 @@ Error CoverageMapping::loadFunctionRecord(
for (const auto &Region : Record.MappingRegions) {
Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
if (auto E = ExecutionCount.takeError()) {
- llvm::consumeError(std::move(E));
+ consumeError(std::move(E));
return Error::success();
}
Function.pushRegion(Region, *ExecutionCount);
@@ -281,6 +294,7 @@ CoverageMapping::load(ArrayRef<StringRef> ObjectFilenames,
}
namespace {
+
/// \brief Distributes functions into instantiation sets.
///
/// An instantiation set is a collection of functions that have the same source
@@ -326,7 +340,7 @@ class SegmentBuilder {
Segments.pop_back();
DEBUG(dbgs() << "Segment at " << Line << ":" << Col);
// Set this region's count.
- if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion) {
+ if (Region.Kind != CounterMappingRegion::SkippedRegion) {
DEBUG(dbgs() << " with count " << Region.ExecutionCount);
Segments.emplace_back(Line, Col, Region.ExecutionCount, IsRegionEntry);
} else
@@ -380,10 +394,10 @@ class SegmentBuilder {
// in combineRegions(). Because we accumulate counter values only from
// regions of the same kind as the first region of the area, prefer
// CodeRegion to ExpansionRegion and ExpansionRegion to SkippedRegion.
- static_assert(coverage::CounterMappingRegion::CodeRegion <
- coverage::CounterMappingRegion::ExpansionRegion &&
- coverage::CounterMappingRegion::ExpansionRegion <
- coverage::CounterMappingRegion::SkippedRegion,
+ static_assert(CounterMappingRegion::CodeRegion <
+ CounterMappingRegion::ExpansionRegion &&
+ CounterMappingRegion::ExpansionRegion <
+ CounterMappingRegion::SkippedRegion,
"Unexpected order of region kind values");
return LHS.Kind < RHS.Kind;
});
@@ -437,7 +451,8 @@ public:
return Segments;
}
};
-}
+
+} // end anonymous namespace
std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const {
std::vector<StringRef> Filenames;
@@ -487,7 +502,7 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) {
CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
CoverageData FileCoverage(Filename);
- std::vector<coverage::CountedRegion> Regions;
+ std::vector<CountedRegion> Regions;
for (const auto &Function : Functions) {
auto MainFileID = findMainViewFileID(Filename, Function);
@@ -533,7 +548,7 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const {
return CoverageData();
CoverageData FunctionCoverage(Function.Filenames[*MainFileID]);
- std::vector<coverage::CountedRegion> Regions;
+ std::vector<CountedRegion> Regions;
for (const auto &CR : Function.CountedRegions)
if (CR.FileID == *MainFileID) {
Regions.push_back(CR);
@@ -551,7 +566,7 @@ CoverageData CoverageMapping::getCoverageForExpansion(
const ExpansionRecord &Expansion) const {
CoverageData ExpansionCoverage(
Expansion.Function.Filenames[Expansion.FileID]);
- std::vector<coverage::CountedRegion> Regions;
+ std::vector<CountedRegion> Regions;
for (const auto &CR : Expansion.Function.CountedRegions)
if (CR.FileID == Expansion.FileID) {
Regions.push_back(CR);
@@ -566,8 +581,7 @@ CoverageData CoverageMapping::getCoverageForExpansion(
return ExpansionCoverage;
}
-namespace {
-std::string getCoverageMapErrString(coveragemap_error Err) {
+static std::string getCoverageMapErrString(coveragemap_error Err) {
switch (Err) {
case coveragemap_error::success:
return "Success";
@@ -585,6 +599,8 @@ std::string getCoverageMapErrString(coveragemap_error Err) {
llvm_unreachable("A value of coveragemap_error has no message.");
}
+namespace {
+
// FIXME: This class is only here to support the transition to llvm::Error. It
// will be removed once this transition is complete. Clients should prefer to
// deal with the Error value directly, rather than converting to error_code.
@@ -594,6 +610,7 @@ class CoverageMappingErrorCategoryType : public std::error_category {
return getCoverageMapErrString(static_cast<coveragemap_error>(IE));
}
};
+
} // end anonymous namespace
std::string CoverageMapError::message() const {
diff --git a/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index a6c7031ccd3d..a34f359cd542 100644
--- a/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -1,4 +1,4 @@
-//=-- CoverageMappingReader.cpp - Code coverage mapping reader ----*- C++ -*-=//
+//===- CoverageMappingReader.cpp - Code coverage mapping reader -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@@ -13,14 +13,34 @@
//===----------------------------------------------------------------------===//
#include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/Error.h"
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <utility>
+#include <vector>
using namespace llvm;
using namespace coverage;
@@ -226,9 +246,8 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
}
Error RawCoverageMappingReader::read() {
-
// Read the virtual file mapping.
- llvm::SmallVector<unsigned, 8> VirtualFileMapping;
+ SmallVector<unsigned, 8> VirtualFileMapping;
uint64_t NumFileMappings;
if (auto Err = readSize(NumFileMappings))
return Err;
@@ -349,7 +368,10 @@ static Expected<bool> isCoverageMappingDummy(uint64_t Hash, StringRef Mapping) {
}
namespace {
+
struct CovMapFuncRecordReader {
+ virtual ~CovMapFuncRecordReader() = default;
+
// The interface to read coverage mapping function records for a module.
//
// \p Buf points to the buffer containing the \c CovHeader of the coverage
@@ -359,26 +381,24 @@ struct CovMapFuncRecordReader {
// greater than \p End if not.
virtual Expected<const char *> readFunctionRecords(const char *Buf,
const char *End) = 0;
- virtual ~CovMapFuncRecordReader() {}
+
template <class IntPtrT, support::endianness Endian>
static Expected<std::unique_ptr<CovMapFuncRecordReader>>
- get(coverage::CovMapVersion Version, InstrProfSymtab &P,
+ get(CovMapVersion Version, InstrProfSymtab &P,
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
std::vector<StringRef> &F);
};
// A class for reading coverage mapping function records for a module.
-template <coverage::CovMapVersion Version, class IntPtrT,
- support::endianness Endian>
+template <CovMapVersion Version, class IntPtrT, support::endianness Endian>
class VersionedCovMapFuncRecordReader : public CovMapFuncRecordReader {
- typedef typename coverage::CovMapTraits<
+ typedef typename CovMapTraits<
Version, IntPtrT>::CovMapFuncRecordType FuncRecordType;
- typedef typename coverage::CovMapTraits<Version, IntPtrT>::NameRefType
- NameRefType;
+ typedef typename CovMapTraits<Version, IntPtrT>::NameRefType NameRefType;
// Maps function's name references to the indexes of their records
// in \c Records.
- llvm::DenseMap<NameRefType, size_t> FunctionRecords;
+ DenseMap<NameRefType, size_t> FunctionRecords;
InstrProfSymtab &ProfileNames;
std::vector<StringRef> &Filenames;
std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records;
@@ -432,14 +452,16 @@ public:
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
std::vector<StringRef> &F)
: ProfileNames(P), Filenames(F), Records(R) {}
- ~VersionedCovMapFuncRecordReader() override {}
+
+ ~VersionedCovMapFuncRecordReader() override = default;
Expected<const char *> readFunctionRecords(const char *Buf,
const char *End) override {
using namespace support;
+
if (Buf + sizeof(CovMapHeader) > End)
return make_error<CoverageMapError>(coveragemap_error::malformed);
- auto CovHeader = reinterpret_cast<const coverage::CovMapHeader *>(Buf);
+ auto CovHeader = reinterpret_cast<const CovMapHeader *>(Buf);
uint32_t NRecords = CovHeader->getNRecords<Endian>();
uint32_t FilenamesSize = CovHeader->getFilenamesSize<Endian>();
uint32_t CoverageSize = CovHeader->getCoverageSize<Endian>();
@@ -490,14 +512,16 @@ public:
return Buf;
}
};
+
} // end anonymous namespace
template <class IntPtrT, support::endianness Endian>
Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
- coverage::CovMapVersion Version, InstrProfSymtab &P,
+ CovMapVersion Version, InstrProfSymtab &P,
std::vector<BinaryCoverageReader::ProfileMappingRecord> &R,
std::vector<StringRef> &F) {
using namespace coverage;
+
switch (Version) {
case CovMapVersion::Version1:
return llvm::make_unique<VersionedCovMapFuncRecordReader<
@@ -518,11 +542,12 @@ static Error readCoverageMappingData(
std::vector<BinaryCoverageReader::ProfileMappingRecord> &Records,
std::vector<StringRef> &Filenames) {
using namespace coverage;
+
// Read the records in the coverage data section.
auto CovHeader =
- reinterpret_cast<const coverage::CovMapHeader *>(Data.data());
+ reinterpret_cast<const CovMapHeader *>(Data.data());
CovMapVersion Version = (CovMapVersion)CovHeader->getVersion<Endian>();
- if (Version > coverage::CovMapVersion::CurrentVersion)
+ if (Version > CovMapVersion::CurrentVersion)
return make_error<CoverageMapError>(coveragemap_error::unsupported_version);
Expected<std::unique_ptr<CovMapFuncRecordReader>> ReaderExpected =
CovMapFuncRecordReader::get<T, Endian>(Version, ProfileNames, Records,
@@ -538,6 +563,7 @@ static Error readCoverageMappingData(
}
return Error::success();
}
+
static const char *TestingFormatMagic = "llvmcovmtestdata";
static Error loadTestingFormat(StringRef Data, InstrProfSymtab &ProfileNames,
@@ -595,21 +621,21 @@ static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
StringRef &CoverageMapping,
uint8_t &BytesInAddress,
support::endianness &Endian, StringRef Arch) {
- auto BinOrErr = object::createBinary(ObjectBuffer);
+ auto BinOrErr = createBinary(ObjectBuffer);
if (!BinOrErr)
return BinOrErr.takeError();
auto Bin = std::move(BinOrErr.get());
std::unique_ptr<ObjectFile> OF;
- if (auto *Universal = dyn_cast<object::MachOUniversalBinary>(Bin.get())) {
+ if (auto *Universal = dyn_cast<MachOUniversalBinary>(Bin.get())) {
// If we have a universal binary, try to look up the object for the
// appropriate architecture.
auto ObjectFileOrErr = Universal->getObjectForArch(Arch);
if (!ObjectFileOrErr)
return ObjectFileOrErr.takeError();
OF = std::move(ObjectFileOrErr.get());
- } else if (isa<object::ObjectFile>(Bin.get())) {
+ } else if (isa<ObjectFile>(Bin.get())) {
// For any other object file, upcast and take ownership.
- OF.reset(cast<object::ObjectFile>(Bin.release()));
+ OF.reset(cast<ObjectFile>(Bin.release()));
// If we've asked for a particular arch, make sure they match.
if (!Arch.empty() && OF->getArch() != Triple(Arch).getArch())
return errorCodeToError(object_error::arch_not_found);
@@ -623,11 +649,15 @@ static Error loadBinaryFormat(MemoryBufferRef ObjectBuffer,
: support::endianness::big;
// Look for the sections that we are interested in.
- auto NamesSection = lookupSection(*OF, getInstrProfNameSectionName(false));
+ auto ObjFormat = OF->getTripleObjectFormat();
+ auto NamesSection =
+ lookupSection(*OF, getInstrProfSectionName(IPSK_name, ObjFormat,
+ /*AddSegmentInfo=*/false));
if (auto E = NamesSection.takeError())
return E;
auto CoverageSection =
- lookupSection(*OF, getInstrProfCoverageSectionName(false));
+ lookupSection(*OF, getInstrProfSectionName(IPSK_covmap, ObjFormat,
+ /*AddSegmentInfo=*/false));
if (auto E = CoverageSection.takeError())
return E;
diff --git a/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp b/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
index 82356333b937..f131be2cba49 100644
--- a/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
+++ b/contrib/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
@@ -1,4 +1,4 @@
-//=-- CoverageMappingWriter.cpp - Code coverage mapping writer -------------=//
+//===- CoverageMappingWriter.cpp - Code coverage mapping writer -----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,8 +12,15 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
#include "llvm/Support/LEB128.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cassert>
+#include <limits>
+#include <vector>
using namespace llvm;
using namespace coverage;
@@ -27,14 +34,25 @@ void CoverageFilenamesSectionWriter::write(raw_ostream &OS) {
}
namespace {
+
/// \brief Gather only the expressions that are used by the mapping
/// regions in this function.
class CounterExpressionsMinimizer {
ArrayRef<CounterExpression> Expressions;
- llvm::SmallVector<CounterExpression, 16> UsedExpressions;
+ SmallVector<CounterExpression, 16> UsedExpressions;
std::vector<unsigned> AdjustedExpressionIDs;
public:
+ CounterExpressionsMinimizer(ArrayRef<CounterExpression> Expressions,
+ ArrayRef<CounterMappingRegion> MappingRegions)
+ : Expressions(Expressions) {
+ AdjustedExpressionIDs.resize(Expressions.size(), 0);
+ for (const auto &I : MappingRegions)
+ mark(I.Count);
+ for (const auto &I : MappingRegions)
+ gatherUsed(I.Count);
+ }
+
void mark(Counter C) {
if (!C.isExpression())
return;
@@ -54,16 +72,6 @@ public:
gatherUsed(E.RHS);
}
- CounterExpressionsMinimizer(ArrayRef<CounterExpression> Expressions,
- ArrayRef<CounterMappingRegion> MappingRegions)
- : Expressions(Expressions) {
- AdjustedExpressionIDs.resize(Expressions.size(), 0);
- for (const auto &I : MappingRegions)
- mark(I.Count);
- for (const auto &I : MappingRegions)
- gatherUsed(I.Count);
- }
-
ArrayRef<CounterExpression> getExpressions() const { return UsedExpressions; }
/// \brief Adjust the given counter to correctly transition from the old
@@ -74,7 +82,8 @@ public:
return C;
}
};
-}
+
+} // end anonymous namespace
/// \brief Encode the counter.
///
diff --git a/contrib/llvm/lib/ProfileData/InstrProf.cpp b/contrib/llvm/lib/ProfileData/InstrProf.cpp
index 74acd9e5e207..64a65ccc11a1 100644
--- a/contrib/llvm/lib/ProfileData/InstrProf.cpp
+++ b/contrib/llvm/lib/ProfileData/InstrProf.cpp
@@ -1,4 +1,4 @@
-//=-- InstrProf.cpp - Instrumented profiling format support -----------------=//
+//===- InstrProf.cpp - Instrumented profiling format support --------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,29 +12,68 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
+#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
+#include "llvm/IR/Instruction.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
+#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
+#include "llvm/IR/Type.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstring>
+#include <cstdint>
+#include <memory>
+#include <string>
+#include <system_error>
+#include <utility>
+#include <vector>
using namespace llvm;
static cl::opt<bool> StaticFuncFullModulePrefix(
- "static-func-full-module-prefix", cl::init(false),
+ "static-func-full-module-prefix", cl::init(true),
cl::desc("Use full module build paths in the profile counter names for "
"static functions."));
-namespace {
-std::string getInstrProfErrString(instrprof_error Err) {
+// This option is tailored to users that have different top-level directory in
+// profile-gen and profile-use compilation. Users need to specific the number
+// of levels to strip. A value larger than the number of directories in the
+// source file will strip all the directory names and only leave the basename.
+//
+// Note current ThinLTO module importing for the indirect-calls assumes
+// the source directory name not being stripped. A non-zero option value here
+// can potentially prevent some inter-module indirect-call-promotions.
+static cl::opt<unsigned> StaticFuncStripDirNamePrefix(
+ "static-func-strip-dirname-prefix", cl::init(0),
+ cl::desc("Strip specified level of directory name from source path in "
+ "the profile counter name for static functions."));
+
+static std::string getInstrProfErrString(instrprof_error Err) {
switch (Err) {
case instrprof_error::success:
return "Success";
@@ -76,15 +115,19 @@ std::string getInstrProfErrString(instrprof_error Err) {
llvm_unreachable("A value of instrprof_error has no message.");
}
+namespace {
+
// FIXME: This class is only here to support the transition to llvm::Error. It
// will be removed once this transition is complete. Clients should prefer to
// deal with the Error value directly, rather than converting to error_code.
class InstrProfErrorCategoryType : public std::error_category {
const char *name() const noexcept override { return "llvm.instrprof"; }
+
std::string message(int IE) const override {
return getInstrProfErrString(static_cast<instrprof_error>(IE));
}
};
+
} // end anonymous namespace
static ManagedStatic<InstrProfErrorCategoryType> ErrorCategory;
@@ -93,8 +136,49 @@ const std::error_category &llvm::instrprof_category() {
return *ErrorCategory;
}
+namespace {
+
+const char *InstrProfSectNameCommon[] = {
+#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
+ SectNameCommon,
+#include "llvm/ProfileData/InstrProfData.inc"
+};
+
+const char *InstrProfSectNameCoff[] = {
+#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
+ SectNameCoff,
+#include "llvm/ProfileData/InstrProfData.inc"
+};
+
+const char *InstrProfSectNamePrefix[] = {
+#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix) \
+ Prefix,
+#include "llvm/ProfileData/InstrProfData.inc"
+};
+
+} // namespace
+
namespace llvm {
+std::string getInstrProfSectionName(InstrProfSectKind IPSK,
+ Triple::ObjectFormatType OF,
+ bool AddSegmentInfo) {
+ std::string SectName;
+
+ if (OF == Triple::MachO && AddSegmentInfo)
+ SectName = InstrProfSectNamePrefix[IPSK];
+
+ if (OF == Triple::COFF)
+ SectName += InstrProfSectNameCoff[IPSK];
+ else
+ SectName += InstrProfSectNameCommon[IPSK];
+
+ if (OF == Triple::MachO && IPSK == IPSK_data && AddSegmentInfo)
+ SectName += ",regular,live_support";
+
+ return SectName;
+}
+
void SoftInstrProfErrors::addError(instrprof_error IE) {
if (IE == instrprof_error::success)
return;
@@ -133,6 +217,24 @@ std::string getPGOFuncName(StringRef RawFuncName,
return GlobalValue::getGlobalIdentifier(RawFuncName, Linkage, FileName);
}
+// Strip NumPrefix level of directory name from PathNameStr. If the number of
+// directory separators is less than NumPrefix, strip all the directories and
+// leave base file name only.
+static StringRef stripDirPrefix(StringRef PathNameStr, uint32_t NumPrefix) {
+ uint32_t Count = NumPrefix;
+ uint32_t Pos = 0, LastPos = 0;
+ for (auto & CI : PathNameStr) {
+ ++Pos;
+ if (llvm::sys::path::is_separator(CI)) {
+ LastPos = Pos;
+ --Count;
+ }
+ if (Count == 0)
+ break;
+ }
+ return PathNameStr.substr(LastPos);
+}
+
// Return the PGOFuncName. This function has some special handling when called
// in LTO optimization. The following only applies when calling in LTO passes
// (when \c InLTO is true): LTO's internalization privatizes many global linkage
@@ -151,6 +253,8 @@ std::string getPGOFuncName(const Function &F, bool InLTO, uint64_t Version) {
StringRef FileName = (StaticFuncFullModulePrefix
? F.getParent()->getName()
: sys::path::filename(F.getParent()->getName()));
+ if (StaticFuncFullModulePrefix && StaticFuncStripDirNamePrefix != 0)
+ FileName = stripDirPrefix(FileName, StaticFuncStripDirNamePrefix);
return getPGOFuncName(F.getName(), F.getLinkage(), FileName, Version);
}
@@ -198,7 +302,6 @@ std::string getPGOFuncNameVarName(StringRef FuncName,
GlobalVariable *createPGOFuncNameVar(Module &M,
GlobalValue::LinkageTypes Linkage,
StringRef PGOFuncName) {
-
// We generally want to match the function's linkage, but available_externally
// and extern_weak both have the wrong semantics, and anything that doesn't
// need to link across compilation units doesn't need to be visible at all.
@@ -236,6 +339,17 @@ void InstrProfSymtab::create(Module &M, bool InLTO) {
const std::string &PGOFuncName = getPGOFuncName(F, InLTO);
addFuncName(PGOFuncName);
MD5FuncMap.emplace_back(Function::getGUID(PGOFuncName), &F);
+ // In ThinLTO, local function may have been promoted to global and have
+ // suffix added to the function name. We need to add the stripped function
+ // name to the symbol table so that we can find a match from profile.
+ if (InLTO) {
+ auto pos = PGOFuncName.find('.');
+ if (pos != std::string::npos) {
+ const std::string &OtherFuncName = PGOFuncName.substr(0, pos);
+ addFuncName(OtherFuncName);
+ MD5FuncMap.emplace_back(Function::getGUID(OtherFuncName), &F);
+ }
+ }
}
finalizeSymtab();
@@ -243,7 +357,7 @@ void InstrProfSymtab::create(Module &M, bool InLTO) {
Error collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,
bool doCompression, std::string &Result) {
- assert(NameStrs.size() && "No name data to emit");
+ assert(!NameStrs.empty() && "No name data to emit");
uint8_t Header[16], *P = Header;
std::string UncompressedNameStrings =
@@ -271,12 +385,12 @@ Error collectPGOFuncNameStrings(const std::vector<std::string> &NameStrs,
}
SmallString<128> CompressedNameStrings;
- zlib::Status Success =
- zlib::compress(StringRef(UncompressedNameStrings), CompressedNameStrings,
- zlib::BestSizeCompression);
-
- if (Success != zlib::StatusOK)
+ Error E = zlib::compress(StringRef(UncompressedNameStrings),
+ CompressedNameStrings, zlib::BestSizeCompression);
+ if (E) {
+ consumeError(std::move(E));
return make_error<InstrProfError>(instrprof_error::compress_failed);
+ }
return WriteStringToResult(CompressedNameStrings.size(),
CompressedNameStrings);
@@ -315,9 +429,12 @@ Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) {
if (isCompressed) {
StringRef CompressedNameStrings(reinterpret_cast<const char *>(P),
CompressedSize);
- if (zlib::uncompress(CompressedNameStrings, UncompressedNameStrings,
- UncompressedSize) != zlib::StatusOK)
+ if (Error E =
+ zlib::uncompress(CompressedNameStrings, UncompressedNameStrings,
+ UncompressedSize)) {
+ consumeError(std::move(E));
return make_error<InstrProfError>(instrprof_error::uncompress_failed);
+ }
P += CompressedSize;
NameStrings = StringRef(UncompressedNameStrings.data(),
UncompressedNameStrings.size());
@@ -553,6 +670,7 @@ void ValueProfRecord::deserializeTo(InstrProfRecord &Record,
void ValueProfRecord::swapBytes(support::endianness Old,
support::endianness New) {
using namespace support;
+
if (Old == New)
return;
@@ -589,6 +707,7 @@ void ValueProfData::deserializeTo(InstrProfRecord &Record,
template <class T>
static T swapToHostOrder(const unsigned char *&D, support::endianness Orig) {
using namespace support;
+
if (Orig == little)
return endian::readNext<T, little, unaligned>(D);
else
@@ -623,6 +742,7 @@ ValueProfData::getValueProfData(const unsigned char *D,
const unsigned char *const BufferEnd,
support::endianness Endianness) {
using namespace support;
+
if (D + sizeof(ValueProfData) > BufferEnd)
return make_error<InstrProfError>(instrprof_error::truncated);
@@ -645,6 +765,7 @@ ValueProfData::getValueProfData(const unsigned char *D,
void ValueProfData::swapBytesToHost(support::endianness Endianness) {
using namespace support;
+
if (Endianness == getHostEndianness())
return;
@@ -660,6 +781,7 @@ void ValueProfData::swapBytesToHost(support::endianness Endianness) {
void ValueProfData::swapBytesFromHost(support::endianness Endianness) {
using namespace support;
+
if (Endianness == getHostEndianness())
return;
@@ -791,7 +913,7 @@ bool needsComdatForCounter(const Function &F, const Module &M) {
return true;
Triple TT(M.getTargetTriple());
- if (!TT.isOSBinFormatELF())
+ if (!TT.isOSBinFormatELF() && !TT.isOSBinFormatWasm())
return false;
// See createPGOFuncNameVar for more details. To avoid link errors, profile
@@ -854,4 +976,26 @@ bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken) {
}
return true;
}
+
+// Parse the value profile options.
+void getMemOPSizeRangeFromOption(std::string MemOPSizeRange,
+ int64_t &RangeStart, int64_t &RangeLast) {
+ static const int64_t DefaultMemOPSizeRangeStart = 0;
+ static const int64_t DefaultMemOPSizeRangeLast = 8;
+ RangeStart = DefaultMemOPSizeRangeStart;
+ RangeLast = DefaultMemOPSizeRangeLast;
+
+ if (!MemOPSizeRange.empty()) {
+ auto Pos = MemOPSizeRange.find(":");
+ if (Pos != std::string::npos) {
+ if (Pos > 0)
+ RangeStart = atoi(MemOPSizeRange.substr(0, Pos).c_str());
+ if (Pos < MemOPSizeRange.size() - 1)
+ RangeLast = atoi(MemOPSizeRange.substr(Pos + 1).c_str());
+ } else
+ RangeLast = atoi(MemOPSizeRange.c_str());
+ }
+ assert(RangeLast >= RangeStart);
+}
+
} // end namespace llvm
diff --git a/contrib/llvm/lib/ProfileData/InstrProfReader.cpp b/contrib/llvm/lib/ProfileData/InstrProfReader.cpp
index ad407f07957f..856f793363f7 100644
--- a/contrib/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/contrib/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -1,4 +1,4 @@
-//=-- InstrProfReader.cpp - Instrumented profiling reader -------------------=//
+//===- InstrProfReader.cpp - Instrumented profiling reader ----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,9 +12,27 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ProfileData/InstrProfReader.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
-#include <cassert>
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/ProfileSummary.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/ProfileData/InstrProfReader.h"
+#include "llvm/ProfileData/ProfileCommon.h"
+#include "llvm/Support/Endian.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/SwapByteOrder.h"
+#include <algorithm>
+#include <cctype>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <system_error>
+#include <utility>
+#include <vector>
using namespace llvm;
@@ -78,7 +96,6 @@ IndexedInstrProfReader::create(const Twine &Path) {
return IndexedInstrProfReader::create(std::move(BufferOrError.get()));
}
-
Expected<std::unique_ptr<IndexedInstrProfReader>>
IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
// Sanity check the buffer.
@@ -182,7 +199,7 @@ TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
CHECK_LINE_END(Line);
std::pair<StringRef, StringRef> VD = Line->rsplit(':');
uint64_t TakenCount, Value;
- if (VK == IPVK_IndirectCallTarget) {
+ if (ValueKind == IPVK_IndirectCallTarget) {
Symtab->addFuncName(VD.first);
Value = IndexedInstrProf::ComputeHash(VD.first);
} else {
@@ -192,7 +209,8 @@ TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
CurrentValues.push_back({Value, TakenCount});
Line++;
}
- Record.addValueData(VK, S, CurrentValues.data(), NumValueData, nullptr);
+ Record.addValueData(ValueKind, S, CurrentValues.data(), NumValueData,
+ nullptr);
}
}
return success();
@@ -232,7 +250,7 @@ Error TextInstrProfReader::readNextRecord(InstrProfRecord &Record) {
return error(instrprof_error::malformed);
// Read each counter and fill our internal storage with the values.
- Record.Counts.clear();
+ Record.Clear();
Record.Counts.reserve(NumCounters);
for (uint64_t I = 0; I < NumCounters; ++I) {
if (Line.is_at_end())
@@ -398,7 +416,6 @@ Error RawInstrProfReader<IntPtrT>::readRawCounts(
template <class IntPtrT>
Error RawInstrProfReader<IntPtrT>::readValueProfilingData(
InstrProfRecord &Record) {
-
Record.clearValueData();
CurValueDataSize = 0;
// Need to match the logic in value profile dumper code in compiler-rt:
@@ -454,9 +471,11 @@ Error RawInstrProfReader<IntPtrT>::readNextRecord(InstrProfRecord &Record) {
}
namespace llvm {
+
template class RawInstrProfReader<uint32_t>;
template class RawInstrProfReader<uint64_t>;
-}
+
+} // end namespace llvm
InstrProfLookupTrait::hash_value_type
InstrProfLookupTrait::ComputeHash(StringRef K) {
@@ -482,6 +501,8 @@ bool InstrProfLookupTrait::readValueProfilingData(
data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
offset_type N) {
+ using namespace support;
+
// Check if the data is corrupt. If so, don't try to read it.
if (N % sizeof(uint64_t))
return data_type();
@@ -489,7 +510,6 @@ data_type InstrProfLookupTrait::ReadData(StringRef K, const unsigned char *D,
DataBuffer.clear();
std::vector<uint64_t> CounterBuffer;
- using namespace support;
const unsigned char *End = D + N;
while (D < End) {
// Read hash.
@@ -567,9 +587,10 @@ InstrProfReaderIndex<HashTableImpl>::InstrProfReaderIndex(
}
bool IndexedInstrProfReader::hasFormat(const MemoryBuffer &DataBuffer) {
+ using namespace support;
+
if (DataBuffer.getBufferSize() < 8)
return false;
- using namespace support;
uint64_t Magic =
endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart());
// Verify that it's magical.
@@ -581,6 +602,7 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
const unsigned char *Cur) {
using namespace IndexedInstrProf;
using namespace support;
+
if (Version >= IndexedInstrProf::Version4) {
const IndexedInstrProf::Summary *SummaryInLE =
reinterpret_cast<const IndexedInstrProf::Summary *>(Cur);
@@ -617,6 +639,7 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
} else {
// For older version of profile data, we need to compute on the fly:
using namespace IndexedInstrProf;
+
InstrProfSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
// FIXME: This only computes an empty summary. Need to call addRecord for
// all InstrProfRecords to get the correct summary.
@@ -626,14 +649,14 @@ IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
}
Error IndexedInstrProfReader::readHeader() {
+ using namespace support;
+
const unsigned char *Start =
(const unsigned char *)DataBuffer->getBufferStart();
const unsigned char *Cur = Start;
if ((const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
return error(instrprof_error::truncated);
- using namespace support;
-
auto *Header = reinterpret_cast<const IndexedInstrProf::Header *>(Cur);
Cur += sizeof(IndexedInstrProf::Header);
diff --git a/contrib/llvm/lib/ProfileData/InstrProfWriter.cpp b/contrib/llvm/lib/ProfileData/InstrProfWriter.cpp
index 029d75660a73..6b7bd3b2fc0a 100644
--- a/contrib/llvm/lib/ProfileData/InstrProfWriter.cpp
+++ b/contrib/llvm/lib/ProfileData/InstrProfWriter.cpp
@@ -1,4 +1,4 @@
-//=-- InstrProfWriter.cpp - Instrumented profiling writer -------------------=//
+//===- InstrProfWriter.cpp - Instrumented profiling writer ----------------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,15 +12,21 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ProfileData/InstrProfWriter.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/ProfileSummary.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/ProfileData/InstrProfWriter.h"
#include "llvm/ProfileData/ProfileCommon.h"
+#include "llvm/Support/Endian.h"
#include "llvm/Support/EndianStream.h"
+#include "llvm/Support/Error.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/OnDiskHashTable.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cstdint>
+#include <memory>
#include <string>
#include <tuple>
#include <utility>
@@ -41,10 +47,9 @@ namespace llvm {
// A wrapper class to abstract writer stream with support of bytes
// back patching.
class ProfOStream {
-
public:
- ProfOStream(llvm::raw_fd_ostream &FD) : IsFDOStream(true), OS(FD), LE(FD) {}
- ProfOStream(llvm::raw_string_ostream &STR)
+ ProfOStream(raw_fd_ostream &FD) : IsFDOStream(true), OS(FD), LE(FD) {}
+ ProfOStream(raw_string_ostream &STR)
: IsFDOStream(false), OS(STR), LE(STR) {}
uint64_t tell() { return OS.tell(); }
@@ -55,15 +60,16 @@ public:
// directly and it won't be reflected in the stream's internal buffer.
void patch(PatchItem *P, int NItems) {
using namespace support;
+
if (IsFDOStream) {
- llvm::raw_fd_ostream &FDOStream = static_cast<llvm::raw_fd_ostream &>(OS);
+ raw_fd_ostream &FDOStream = static_cast<raw_fd_ostream &>(OS);
for (int K = 0; K < NItems; K++) {
FDOStream.seek(P[K].Pos);
for (int I = 0; I < P[K].N; I++)
write(P[K].D[I]);
}
} else {
- llvm::raw_string_ostream &SOStream =
+ raw_string_ostream &SOStream =
static_cast<llvm::raw_string_ostream &>(OS);
std::string &Data = SOStream.str(); // with flush
for (int K = 0; K < NItems; K++) {
@@ -94,17 +100,19 @@ public:
typedef uint64_t hash_value_type;
typedef uint64_t offset_type;
- support::endianness ValueProfDataEndianness;
+ support::endianness ValueProfDataEndianness = support::little;
InstrProfSummaryBuilder *SummaryBuilder;
- InstrProfRecordWriterTrait() : ValueProfDataEndianness(support::little) {}
+ InstrProfRecordWriterTrait() = default;
+
static hash_value_type ComputeHash(key_type_ref K) {
return IndexedInstrProf::ComputeHash(K);
}
static std::pair<offset_type, offset_type>
EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V) {
- using namespace llvm::support;
+ using namespace support;
+
endian::Writer<little> LE(Out);
offset_type N = K.size();
@@ -130,7 +138,8 @@ public:
}
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type) {
- using namespace llvm::support;
+ using namespace support;
+
endian::Writer<little> LE(Out);
for (const auto &ProfileData : *V) {
const InstrProfRecord &ProfRecord = ProfileData.second;
@@ -154,8 +163,7 @@ public:
} // end namespace llvm
InstrProfWriter::InstrProfWriter(bool Sparse)
- : Sparse(Sparse), FunctionData(), ProfileKind(PF_Unknown),
- InfoObj(new InstrProfRecordWriterTrait()) {}
+ : Sparse(Sparse), InfoObj(new InstrProfRecordWriterTrait()) {}
InstrProfWriter::~InstrProfWriter() { delete InfoObj; }
@@ -208,7 +216,7 @@ bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) {
return true;
for (const auto &Func : PD) {
const InstrProfRecord &IPR = Func.second;
- if (any_of(IPR.Counts, [](uint64_t Count) { return Count > 0; }))
+ if (llvm::any_of(IPR.Counts, [](uint64_t Count) { return Count > 0; }))
return true;
}
return false;
@@ -217,6 +225,7 @@ bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) {
static void setSummary(IndexedInstrProf::Summary *TheSummary,
ProfileSummary &PS) {
using namespace IndexedInstrProf;
+
std::vector<ProfileSummaryEntry> &Res = PS.getDetailedSummary();
TheSummary->NumSummaryFields = Summary::NumKinds;
TheSummary->NumCutoffEntries = Res.size();
@@ -231,9 +240,10 @@ static void setSummary(IndexedInstrProf::Summary *TheSummary,
}
void InstrProfWriter::writeImpl(ProfOStream &OS) {
+ using namespace IndexedInstrProf;
+
OnDiskChainedHashTableGenerator<InstrProfRecordWriterTrait> Generator;
- using namespace IndexedInstrProf;
InstrProfSummaryBuilder ISB(ProfileSummaryBuilder::DefaultCutoffs);
InfoObj->SummaryBuilder = &ISB;
@@ -301,7 +311,7 @@ void InstrProfWriter::write(raw_fd_ostream &OS) {
std::unique_ptr<MemoryBuffer> InstrProfWriter::writeBuffer() {
std::string Data;
- llvm::raw_string_ostream OS(Data);
+ raw_string_ostream OS(Data);
ProfOStream POS(OS);
// Write the hash table.
writeImpl(POS);
diff --git a/contrib/llvm/lib/ProfileData/SampleProf.cpp b/contrib/llvm/lib/ProfileData/SampleProf.cpp
index 5bcfff0801d5..eafdd2154b7b 100644
--- a/contrib/llvm/lib/ProfileData/SampleProf.cpp
+++ b/contrib/llvm/lib/ProfileData/SampleProf.cpp
@@ -13,18 +13,25 @@
//===----------------------------------------------------------------------===//
#include "llvm/ProfileData/SampleProf.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/raw_ostream.h"
+#include <string>
+#include <system_error>
-using namespace llvm::sampleprof;
using namespace llvm;
+using namespace sampleprof;
namespace {
+
// FIXME: This class is only here to support the transition to llvm::Error. It
// will be removed once this transition is complete. Clients should prefer to
// deal with the Error value directly, rather than converting to error_code.
class SampleProfErrorCategoryType : public std::error_category {
const char *name() const noexcept override { return "llvm.sampleprof"; }
+
std::string message(int IE) const override {
sampleprof_error E = static_cast<sampleprof_error>(IE);
switch (E) {
@@ -54,7 +61,8 @@ class SampleProfErrorCategoryType : public std::error_category {
llvm_unreachable("A value of sampleprof_error has no message.");
}
};
-}
+
+} // end anonymous namespace
static ManagedStatic<SampleProfErrorCategoryType> ErrorCategory;
@@ -74,7 +82,9 @@ raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS,
return OS;
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void LineLocation::dump() const { print(dbgs()); }
+#endif
/// \brief Print the sample record to the stream \p OS indented by \p Indent.
void SampleRecord::print(raw_ostream &OS, unsigned Indent) const {
@@ -87,7 +97,9 @@ void SampleRecord::print(raw_ostream &OS, unsigned Indent) const {
OS << "\n";
}
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void SampleRecord::dump() const { print(dbgs(), 0); }
+#endif
raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS,
const SampleRecord &Sample) {
@@ -101,7 +113,7 @@ void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const {
<< " sampled lines\n";
OS.indent(Indent);
- if (BodySamples.size() > 0) {
+ if (!BodySamples.empty()) {
OS << "Samples collected in the function's body {\n";
SampleSorter<LineLocation, SampleRecord> SortedBodySamples(BodySamples);
for (const auto &SI : SortedBodySamples.get()) {
@@ -115,14 +127,16 @@ void FunctionSamples::print(raw_ostream &OS, unsigned Indent) const {
}
OS.indent(Indent);
- if (CallsiteSamples.size() > 0) {
+ if (!CallsiteSamples.empty()) {
OS << "Samples collected in inlined callsites {\n";
- SampleSorter<LineLocation, FunctionSamples> SortedCallsiteSamples(
+ SampleSorter<LineLocation, FunctionSamplesMap> SortedCallsiteSamples(
CallsiteSamples);
for (const auto &CS : SortedCallsiteSamples.get()) {
- OS.indent(Indent + 2);
- OS << CS->first << ": inlined callee: " << CS->second.getName() << ": ";
- CS->second.print(OS, Indent + 4);
+ for (const auto &FS : CS->second) {
+ OS.indent(Indent + 2);
+ OS << CS->first << ": inlined callee: " << FS.second.getName() << ": ";
+ FS.second.print(OS, Indent + 4);
+ }
}
OS << "}\n";
} else {
@@ -136,4 +150,6 @@ raw_ostream &llvm::sampleprof::operator<<(raw_ostream &OS,
return OS;
}
-void FunctionSamples::dump(void) const { print(dbgs(), 0); }
+#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
+LLVM_DUMP_METHOD void FunctionSamples::dump() const { print(dbgs(), 0); }
+#endif
diff --git a/contrib/llvm/lib/ProfileData/SampleProfReader.cpp b/contrib/llvm/lib/ProfileData/SampleProfReader.cpp
index af80b036a5bb..234fe02ac8a8 100644
--- a/contrib/llvm/lib/ProfileData/SampleProfReader.cpp
+++ b/contrib/llvm/lib/ProfileData/SampleProfReader.cpp
@@ -23,14 +23,25 @@
#include "llvm/ProfileData/SampleProfReader.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Support/Debug.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/ProfileSummary.h"
+#include "llvm/ProfileData/ProfileCommon.h"
+#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/LineIterator.h"
#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <limits>
+#include <memory>
+#include <system_error>
+#include <vector>
-using namespace llvm::sampleprof;
using namespace llvm;
+using namespace sampleprof;
/// \brief Dump the function profile for \p FName.
///
@@ -200,7 +211,7 @@ std::error_code SampleProfileReaderText::read() {
InlineStack.pop_back();
}
FunctionSamples &FSamples = InlineStack.back()->functionSamplesAt(
- LineLocation(LineOffset, Discriminator));
+ LineLocation(LineOffset, Discriminator))[FName];
FSamples.setName(FName);
MergeResult(Result, FSamples.addTotalSamples(NumSamples));
InlineStack.push_back(&FSamples);
@@ -352,8 +363,8 @@ SampleProfileReaderBinary::readProfile(FunctionSamples &FProfile) {
if (std::error_code EC = FName.getError())
return EC;
- FunctionSamples &CalleeProfile =
- FProfile.functionSamplesAt(LineLocation(*LineOffset, *Discriminator));
+ FunctionSamples &CalleeProfile = FProfile.functionSamplesAt(
+ LineLocation(*LineOffset, *Discriminator))[*FName];
CalleeProfile.setName(*FName);
if (std::error_code EC = readProfile(CalleeProfile))
return EC;
@@ -625,7 +636,7 @@ std::error_code SampleProfileReaderGCC::readOneFunctionProfile(
uint32_t LineOffset = Offset >> 16;
uint32_t Discriminator = Offset & 0xffff;
FProfile = &CallerProfile->functionSamplesAt(
- LineLocation(LineOffset, Discriminator));
+ LineLocation(LineOffset, Discriminator))[Name];
}
FProfile->setName(Name);
@@ -681,11 +692,9 @@ std::error_code SampleProfileReaderGCC::readOneFunctionProfile(
if (!GcovBuffer.readInt64(TargetCount))
return sampleprof_error::truncated;
- if (Update) {
- FunctionSamples &TargetProfile = Profiles[TargetName];
- TargetProfile.addCalledTargetSamples(LineOffset, Discriminator,
- TargetName, TargetCount);
- }
+ if (Update)
+ FProfile->addCalledTargetSamples(LineOffset, Discriminator,
+ TargetName, TargetCount);
}
}
diff --git a/contrib/llvm/lib/ProfileData/SampleProfWriter.cpp b/contrib/llvm/lib/ProfileData/SampleProfWriter.cpp
index 4fa71288f8d9..b91b6fb7c7ad 100644
--- a/contrib/llvm/lib/ProfileData/SampleProfWriter.cpp
+++ b/contrib/llvm/lib/ProfileData/SampleProfWriter.cpp
@@ -18,16 +18,23 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ProfileData/ProfileCommon.h"
+#include "llvm/ProfileData/SampleProf.h"
#include "llvm/ProfileData/SampleProfWriter.h"
-#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/LEB128.h"
-#include "llvm/Support/LineIterator.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/Regex.h"
+#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
+#include <cstdint>
+#include <memory>
+#include <system_error>
+#include <utility>
+#include <vector>
-using namespace llvm::sampleprof;
using namespace llvm;
+using namespace sampleprof;
/// \brief Write samples to a text file.
///
@@ -61,20 +68,21 @@ std::error_code SampleProfileWriterText::write(const FunctionSamples &S) {
OS << "\n";
}
- SampleSorter<LineLocation, FunctionSamples> SortedCallsiteSamples(
+ SampleSorter<LineLocation, FunctionSamplesMap> SortedCallsiteSamples(
S.getCallsiteSamples());
Indent += 1;
- for (const auto &I : SortedCallsiteSamples.get()) {
- LineLocation Loc = I->first;
- const FunctionSamples &CalleeSamples = I->second;
- OS.indent(Indent);
- if (Loc.Discriminator == 0)
- OS << Loc.LineOffset << ": ";
- else
- OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
- if (std::error_code EC = write(CalleeSamples))
- return EC;
- }
+ for (const auto &I : SortedCallsiteSamples.get())
+ for (const auto &FS : I->second) {
+ LineLocation Loc = I->first;
+ const FunctionSamples &CalleeSamples = FS.second;
+ OS.indent(Indent);
+ if (Loc.Discriminator == 0)
+ OS << Loc.LineOffset << ": ";
+ else
+ OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
+ if (std::error_code EC = write(CalleeSamples))
+ return EC;
+ }
Indent -= 1;
return sampleprof_error::success;
@@ -102,11 +110,12 @@ void SampleProfileWriterBinary::addNames(const FunctionSamples &S) {
}
// Recursively add all the names for inlined callsites.
- for (const auto &J : S.getCallsiteSamples()) {
- const FunctionSamples &CalleeSamples = J.second;
- addName(CalleeSamples.getName());
- addNames(CalleeSamples);
- }
+ for (const auto &J : S.getCallsiteSamples())
+ for (const auto &FS : J.second) {
+ const FunctionSamples &CalleeSamples = FS.second;
+ addName(CalleeSamples.getName());
+ addNames(CalleeSamples);
+ }
}
std::error_code SampleProfileWriterBinary::writeHeader(
@@ -180,14 +189,15 @@ std::error_code SampleProfileWriterBinary::writeBody(const FunctionSamples &S) {
// Recursively emit all the callsite samples.
encodeULEB128(S.getCallsiteSamples().size(), OS);
- for (const auto &J : S.getCallsiteSamples()) {
- LineLocation Loc = J.first;
- const FunctionSamples &CalleeSamples = J.second;
- encodeULEB128(Loc.LineOffset, OS);
- encodeULEB128(Loc.Discriminator, OS);
- if (std::error_code EC = writeBody(CalleeSamples))
- return EC;
- }
+ for (const auto &J : S.getCallsiteSamples())
+ for (const auto &FS : J.second) {
+ LineLocation Loc = J.first;
+ const FunctionSamples &CalleeSamples = FS.second;
+ encodeULEB128(Loc.LineOffset, OS);
+ encodeULEB128(Loc.Discriminator, OS);
+ if (std::error_code EC = writeBody(CalleeSamples))
+ return EC;
+ }
return sampleprof_error::success;
}