[llvm] r270136 - Move ProfileSummary to IR.
Easwaran Raman via llvm-commits
llvm-commits at lists.llvm.org
Thu May 19 14:07:13 PDT 2016
Author: eraman
Date: Thu May 19 16:07:12 2016
New Revision: 270136
URL: http://llvm.org/viewvc/llvm-project?rev=270136&view=rev
Log:
Move ProfileSummary to IR.
This splits ProfileSummary into two classes: a ProfileSummary class that has methods to convert from/to metadata and a ProfileSummaryBuilder class that computes the profiles summary which is in ProfileData.
Differential Revision: http://reviews.llvm.org/D20314
Added:
llvm/trunk/include/llvm/IR/ProfileSummary.h
llvm/trunk/lib/IR/ProfileSummary.cpp
- copied, changed from r270110, llvm/trunk/lib/ProfileData/ProfileSummary.cpp
llvm/trunk/lib/ProfileData/ProfileSummaryBuilder.cpp
Removed:
llvm/trunk/lib/ProfileData/ProfileSummary.cpp
Modified:
llvm/trunk/include/llvm/ProfileData/ProfileCommon.h
llvm/trunk/lib/IR/CMakeLists.txt
llvm/trunk/lib/ProfileData/CMakeLists.txt
llvm/trunk/lib/ProfileData/InstrProfReader.cpp
llvm/trunk/lib/ProfileData/InstrProfWriter.cpp
llvm/trunk/lib/ProfileData/SampleProfReader.cpp
llvm/trunk/lib/ProfileData/SampleProfWriter.cpp
llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp
Added: llvm/trunk/include/llvm/IR/ProfileSummary.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ProfileSummary.h?rev=270136&view=auto
==============================================================================
--- llvm/trunk/include/llvm/IR/ProfileSummary.h (added)
+++ llvm/trunk/include/llvm/IR/ProfileSummary.h Thu May 19 16:07:12 2016
@@ -0,0 +1,129 @@
+//===-- ProfileSummary.h - Profile summary data structure. ------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the profile summary data structure.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_SUPPORT_PROFILE_SUMMARY_H
+#define LLVM_SUPPORT_PROFILE_SUMMARY_H
+
+#include <cstdint>
+#include <vector>
+
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+
+class LLVMContext;
+class Metadata;
+class MDTuple;
+class MDNode;
+
+// The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets.
+// The semantics of counts depend on the type of profile. For instrumentation
+// profile, counts are block counts and for sample profile, counts are
+// per-line samples. Given a target counts percentile, we compute the minimum
+// number of counts needed to reach this target and the minimum among these
+// counts.
+struct ProfileSummaryEntry {
+ uint32_t Cutoff; ///< The required percentile of counts.
+ uint64_t MinCount; ///< The minimum count for this percentile.
+ uint64_t NumCounts; ///< Number of counts >= the minimum count.
+ ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinCount,
+ uint64_t TheNumCounts)
+ : Cutoff(TheCutoff), MinCount(TheMinCount), NumCounts(TheNumCounts) {}
+};
+
+typedef std::vector<ProfileSummaryEntry> SummaryEntryVector;
+
+class ProfileSummary {
+public:
+ enum Kind { PSK_Instr, PSK_Sample };
+
+private:
+ const Kind PSK;
+ static const char *KindStr[2];
+
+protected:
+ SummaryEntryVector DetailedSummary;
+ uint64_t TotalCount, MaxCount, MaxFunctionCount;
+ uint32_t NumCounts, NumFunctions;
+ ProfileSummary(Kind K, SummaryEntryVector DetailedSummary,
+ uint64_t TotalCount, uint64_t MaxCount,
+ uint64_t MaxFunctionCount, uint32_t NumCounts,
+ uint32_t NumFunctions)
+ : PSK(K), DetailedSummary(DetailedSummary), TotalCount(TotalCount),
+ MaxCount(MaxCount), MaxFunctionCount(MaxFunctionCount),
+ NumCounts(NumCounts), NumFunctions(NumFunctions) {}
+ ~ProfileSummary() = default;
+ /// \brief Return metadata specific to the profile format.
+ /// Derived classes implement this method to return a vector of Metadata.
+ virtual std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) = 0;
+ /// \brief Return detailed summary as metadata.
+ Metadata *getDetailedSummaryMD(LLVMContext &Context);
+
+public:
+ static const int Scale = 1000000;
+ Kind getKind() const { return PSK; }
+ const char *getKindStr() const { return KindStr[PSK]; }
+ /// \brief Return summary information as metadata.
+ Metadata *getMD(LLVMContext &Context);
+ /// \brief Construct profile summary from metdata.
+ static ProfileSummary *getFromMD(Metadata *MD);
+ SummaryEntryVector &getDetailedSummary() { return DetailedSummary; }
+ uint32_t getNumFunctions() { return NumFunctions; }
+ uint64_t getMaxFunctionCount() { return MaxFunctionCount; }
+};
+
+class InstrProfSummary final : public ProfileSummary {
+ uint64_t MaxInternalBlockCount;
+
+protected:
+ std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) override;
+
+public:
+ InstrProfSummary(uint64_t TotalCount, uint64_t MaxBlockCount,
+ uint64_t MaxInternalBlockCount, uint64_t MaxFunctionCount,
+ uint32_t NumBlocks, uint32_t NumFunctions,
+ SummaryEntryVector Summary)
+ : ProfileSummary(PSK_Instr, Summary, TotalCount, MaxBlockCount,
+ MaxFunctionCount, NumBlocks, NumFunctions),
+ MaxInternalBlockCount(MaxInternalBlockCount) {}
+ static bool classof(const ProfileSummary *PS) {
+ return PS->getKind() == PSK_Instr;
+ }
+ uint32_t getNumBlocks() { return NumCounts; }
+ uint64_t getTotalCount() { return TotalCount; }
+ uint64_t getMaxBlockCount() { return MaxCount; }
+ uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }
+};
+
+class SampleProfileSummary final : public ProfileSummary {
+protected:
+ std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) override;
+
+public:
+ uint32_t getNumLinesWithSamples() { return NumCounts; }
+ uint64_t getTotalSamples() { return TotalCount; }
+ uint64_t getMaxSamplesPerLine() { return MaxCount; }
+ SampleProfileSummary(uint64_t TotalSamples, uint64_t MaxSamplesPerLine,
+ uint64_t MaxFunctionCount, int32_t NumLinesWithSamples,
+ uint32_t NumFunctions,
+ SummaryEntryVector DetailedSummary)
+ : ProfileSummary(PSK_Sample, DetailedSummary, TotalSamples,
+ MaxSamplesPerLine, MaxFunctionCount, NumLinesWithSamples,
+ NumFunctions) {}
+ static bool classof(const ProfileSummary *PS) {
+ return PS->getKind() == PSK_Sample;
+ }
+};
+
+} // end namespace llvm
+#endif
Modified: llvm/trunk/include/llvm/ProfileData/ProfileCommon.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/ProfileCommon.h?rev=270136&r1=270135&r2=270136&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/ProfileCommon.h (original)
+++ llvm/trunk/include/llvm/ProfileData/ProfileCommon.h Thu May 19 16:07:12 2016
@@ -20,7 +20,7 @@
#include <map>
#include <vector>
-#include "llvm/Support/Casting.h"
+#include "llvm/IR/ProfileSummary.h"
#include "llvm/Support/Error.h"
namespace llvm {
@@ -40,134 +40,54 @@ class MDNode;
inline const char *getHotSectionPrefix() { return ".hot"; }
inline const char *getUnlikelySectionPrefix() { return ".unlikely"; }
-// The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets.
-// The semantics of counts depend on the type of profile. For instrumentation
-// profile, counts are block counts and for sample profile, counts are
-// per-line samples. Given a target counts percentile, we compute the minimum
-// number of counts needed to reach this target and the minimum among these
-// counts.
-struct ProfileSummaryEntry {
- uint32_t Cutoff; ///< The required percentile of counts.
- uint64_t MinCount; ///< The minimum count for this percentile.
- uint64_t NumCounts; ///< Number of counts >= the minimum count.
- ProfileSummaryEntry(uint32_t TheCutoff, uint64_t TheMinCount,
- uint64_t TheNumCounts)
- : Cutoff(TheCutoff), MinCount(TheMinCount), NumCounts(TheNumCounts) {}
-};
-
-typedef std::vector<ProfileSummaryEntry> SummaryEntryVector;
-
-class ProfileSummary {
-public:
- enum Kind { PSK_Instr, PSK_Sample };
+class ProfileSummaryBuilder {
private:
- const Kind PSK;
- static const char *KindStr[2];
// 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
// counts.
std::map<uint64_t, uint32_t, std::greater<uint64_t>> CountFrequencies;
+ std::vector<uint32_t> DetailedSummaryCutoffs;
+
protected:
SummaryEntryVector DetailedSummary;
- std::vector<uint32_t> DetailedSummaryCutoffs;
- uint64_t TotalCount, MaxCount, MaxFunctionCount;
- uint32_t NumCounts, NumFunctions;
- ProfileSummary(Kind K, std::vector<uint32_t> Cutoffs)
- : PSK(K), DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxCount(0),
+ ProfileSummaryBuilder(std::vector<uint32_t> Cutoffs)
+ : DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxCount(0),
MaxFunctionCount(0), NumCounts(0), NumFunctions(0) {}
- ProfileSummary(Kind K)
- : PSK(K), TotalCount(0), MaxCount(0), MaxFunctionCount(0), NumCounts(0),
- NumFunctions(0) {}
- ProfileSummary(Kind K, SummaryEntryVector DetailedSummary,
- uint64_t TotalCount, uint64_t MaxCount,
- uint64_t MaxFunctionCount, uint32_t NumCounts,
- uint32_t NumFunctions)
- : PSK(K), DetailedSummary(DetailedSummary), TotalCount(TotalCount),
- MaxCount(MaxCount), MaxFunctionCount(MaxFunctionCount),
- NumCounts(NumCounts), NumFunctions(NumFunctions) {}
- ~ProfileSummary() = default;
inline void addCount(uint64_t Count);
- /// \brief Return metadata specific to the profile format.
- /// Derived classes implement this method to return a vector of Metadata.
- virtual std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) = 0;
- /// \brief Return detailed summary as metadata.
- Metadata *getDetailedSummaryMD(LLVMContext &Context);
+ ~ProfileSummaryBuilder() = default;
+ void computeDetailedSummary();
+ uint64_t TotalCount, MaxCount, MaxFunctionCount;
+ uint32_t NumCounts, NumFunctions;
public:
- static const int Scale = 1000000;
- Kind getKind() const { return PSK; }
- const char *getKindStr() const { return KindStr[PSK]; }
- // \brief Returns true if F is a hot function.
- static bool isFunctionHot(const Function *F);
- // \brief Returns true if F is unlikley executed.
- static bool isFunctionUnlikely(const Function *F);
- inline SummaryEntryVector &getDetailedSummary();
- void computeDetailedSummary();
/// \brief A vector of useful cutoff values for detailed summary.
static const std::vector<uint32_t> DefaultCutoffs;
- /// \brief Return summary information as metadata.
- Metadata *getMD(LLVMContext &Context);
- /// \brief Construct profile summary from metdata.
- static ProfileSummary *getFromMD(Metadata *MD);
- uint32_t getNumFunctions() { return NumFunctions; }
- uint64_t getMaxFunctionCount() { return MaxFunctionCount; }
};
-class InstrProfSummary final : public ProfileSummary {
+class InstrProfSummaryBuilder final : public ProfileSummaryBuilder {
uint64_t MaxInternalBlockCount;
inline void addEntryCount(uint64_t Count);
inline void addInternalCount(uint64_t Count);
-protected:
- std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) override;
-
public:
- InstrProfSummary(std::vector<uint32_t> Cutoffs)
- : ProfileSummary(PSK_Instr, Cutoffs), MaxInternalBlockCount(0) {}
- InstrProfSummary(const IndexedInstrProf::Summary &S);
- InstrProfSummary(uint64_t TotalCount, uint64_t MaxBlockCount,
- uint64_t MaxInternalBlockCount, uint64_t MaxFunctionCount,
- uint32_t NumBlocks, uint32_t NumFunctions,
- SummaryEntryVector Summary)
- : ProfileSummary(PSK_Instr, Summary, TotalCount, MaxBlockCount,
- MaxFunctionCount, NumBlocks, NumFunctions),
- MaxInternalBlockCount(MaxInternalBlockCount) {}
- static bool classof(const ProfileSummary *PS) {
- return PS->getKind() == PSK_Instr;
- }
+ InstrProfSummaryBuilder(std::vector<uint32_t> Cutoffs)
+ : ProfileSummaryBuilder(Cutoffs), MaxInternalBlockCount(0) {}
void addRecord(const InstrProfRecord &);
- uint32_t getNumBlocks() { return NumCounts; }
- uint64_t getTotalCount() { return TotalCount; }
- uint64_t getMaxBlockCount() { return MaxCount; }
- uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }
+ InstrProfSummary *getSummary();
};
-class SampleProfileSummary final : public ProfileSummary {
-protected:
- std::vector<Metadata *> getFormatSpecificMD(LLVMContext &Context) override;
+class SampleProfileSummaryBuilder final : public ProfileSummaryBuilder {
public:
- uint32_t getNumLinesWithSamples() { return NumCounts; }
- uint64_t getTotalSamples() { return TotalCount; }
- uint64_t getMaxSamplesPerLine() { return MaxCount; }
void addRecord(const sampleprof::FunctionSamples &FS);
- SampleProfileSummary(std::vector<uint32_t> Cutoffs)
- : ProfileSummary(PSK_Sample, Cutoffs) {}
- SampleProfileSummary(uint64_t TotalSamples, uint64_t MaxSamplesPerLine,
- uint64_t MaxFunctionCount, int32_t NumLinesWithSamples,
- uint32_t NumFunctions,
- SummaryEntryVector DetailedSummary)
- : ProfileSummary(PSK_Sample, DetailedSummary, TotalSamples,
- MaxSamplesPerLine, MaxFunctionCount, NumLinesWithSamples,
- NumFunctions) {}
- static bool classof(const ProfileSummary *PS) {
- return PS->getKind() == PSK_Sample;
- }
+ SampleProfileSummaryBuilder(std::vector<uint32_t> Cutoffs)
+ : ProfileSummaryBuilder(Cutoffs) {}
+ SampleProfileSummary *getSummary();
};
// This is called when a count is seen in the profile.
-void ProfileSummary::addCount(uint64_t Count) {
+void ProfileSummaryBuilder::addCount(uint64_t Count) {
TotalCount += Count;
if (Count > MaxCount)
MaxCount = Count;
@@ -175,11 +95,6 @@ void ProfileSummary::addCount(uint64_t C
CountFrequencies[Count]++;
}
-SummaryEntryVector &ProfileSummary::getDetailedSummary() {
- if (!DetailedSummaryCutoffs.empty() && DetailedSummary.empty())
- computeDetailedSummary();
- return DetailedSummary;
-}
} // end namespace llvm
#endif
Modified: llvm/trunk/lib/IR/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/CMakeLists.txt?rev=270136&r1=270135&r2=270136&view=diff
==============================================================================
--- llvm/trunk/lib/IR/CMakeLists.txt (original)
+++ llvm/trunk/lib/IR/CMakeLists.txt Thu May 19 16:07:12 2016
@@ -43,6 +43,7 @@ add_llvm_library(LLVMCore
Pass.cpp
PassManager.cpp
PassRegistry.cpp
+ ProfileSummary.cpp
Statepoint.cpp
Type.cpp
TypeFinder.cpp
Copied: llvm/trunk/lib/IR/ProfileSummary.cpp (from r270110, llvm/trunk/lib/ProfileData/ProfileSummary.cpp)
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/ProfileSummary.cpp?p2=llvm/trunk/lib/IR/ProfileSummary.cpp&p1=llvm/trunk/lib/ProfileData/ProfileSummary.cpp&r1=270110&r2=270136&rev=270136&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/ProfileSummary.cpp (original)
+++ llvm/trunk/lib/IR/ProfileSummary.cpp Thu May 19 16:07:12 2016
@@ -1,4 +1,4 @@
-//=-- Profilesummary.cpp - Profile summary computation ----------------------=//
+//=-- Profilesummary.cpp - Profile summary support --------------------------=//
//
// The LLVM Compiler Infrastructure
//
@@ -7,134 +7,23 @@
//
//===----------------------------------------------------------------------===//
//
-// This file contains support for computing profile summary data.
+// This file contains support for converting profile summary data from/to
+// metadata.
//
//===----------------------------------------------------------------------===//
+#include "llvm/IR/ProfileSummary.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Type.h"
-#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/ProfileData/ProfileCommon.h"
-#include "llvm/ProfileData/SampleProf.h"
#include "llvm/Support/Casting.h"
using namespace llvm;
-// A set of cutoff values. Each value, when divided by ProfileSummary::Scale
-// (which is 1000000) is a desired percentile of total counts.
-const std::vector<uint32_t> ProfileSummary::DefaultCutoffs(
- {10000, /* 1% */
- 100000, /* 10% */
- 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,
- 900000, 950000, 990000, 999000, 999900, 999990, 999999});
const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
-void InstrProfSummary::addRecord(const InstrProfRecord &R) {
- // The first counter is not necessarily an entry count for IR
- // instrumentation profiles.
- // Eventually MaxFunctionCount will become obsolete and this can be
- // removed.
- addEntryCount(R.Counts[0]);
- for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
- addInternalCount(R.Counts[I]);
-}
-
-// To compute the detailed summary, we consider each line containing samples as
-// equivalent to a block with a count in the instrumented profile.
-void SampleProfileSummary::addRecord(const sampleprof::FunctionSamples &FS) {
- NumFunctions++;
- if (FS.getHeadSamples() > MaxFunctionCount)
- MaxFunctionCount = FS.getHeadSamples();
- for (const auto &I : FS.getBodySamples())
- addCount(I.second.getSamples());
-}
-
-// The argument to this method is a vector of cutoff percentages and the return
-// value is a vector of (Cutoff, MinCount, NumCounts) triplets.
-void ProfileSummary::computeDetailedSummary() {
- if (DetailedSummaryCutoffs.empty())
- return;
- auto Iter = CountFrequencies.begin();
- auto End = CountFrequencies.end();
- std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
-
- uint32_t CountsSeen = 0;
- uint64_t CurrSum = 0, Count = 0;
-
- for (uint32_t Cutoff : DetailedSummaryCutoffs) {
- assert(Cutoff <= 999999);
- APInt Temp(128, TotalCount);
- APInt N(128, Cutoff);
- APInt D(128, ProfileSummary::Scale);
- Temp *= N;
- Temp = Temp.sdiv(D);
- uint64_t DesiredCount = Temp.getZExtValue();
- assert(DesiredCount <= TotalCount);
- while (CurrSum < DesiredCount && Iter != End) {
- Count = Iter->first;
- uint32_t Freq = Iter->second;
- CurrSum += (Count * Freq);
- CountsSeen += Freq;
- Iter++;
- }
- assert(CurrSum >= DesiredCount);
- ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen};
- DetailedSummary.push_back(PSE);
- }
-}
-
-// Returns true if the function is a hot function.
-bool ProfileSummary::isFunctionHot(const Function *F) {
- // FIXME: update when summary data is stored in module's metadata.
- return false;
-}
-
-// Returns true if the function is a cold function.
-bool ProfileSummary::isFunctionUnlikely(const Function *F) {
- if (F->hasFnAttribute(Attribute::Cold)) {
- return true;
- }
- if (!F->getEntryCount()) {
- return false;
- }
- // FIXME: update when summary data is stored in module's metadata.
- return (*F->getEntryCount()) == 0;
-}
-
-InstrProfSummary::InstrProfSummary(const IndexedInstrProf::Summary &S)
- : ProfileSummary(PSK_Instr),
- MaxInternalBlockCount(
- S.get(IndexedInstrProf::Summary::MaxInternalBlockCount)) {
-
- TotalCount = S.get(IndexedInstrProf::Summary::TotalBlockCount);
- MaxCount = S.get(IndexedInstrProf::Summary::MaxBlockCount);
- MaxFunctionCount = S.get(IndexedInstrProf::Summary::MaxFunctionCount);
- NumCounts = S.get(IndexedInstrProf::Summary::TotalNumBlocks);
- NumFunctions = S.get(IndexedInstrProf::Summary::TotalNumFunctions);
-
- for (unsigned I = 0; I < S.NumCutoffEntries; I++) {
- const IndexedInstrProf::Summary::Entry &Ent = S.getEntry(I);
- DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
- Ent.NumBlocks);
- }
-}
-
-void InstrProfSummary::addEntryCount(uint64_t Count) {
- addCount(Count);
- NumFunctions++;
- if (Count > MaxFunctionCount)
- MaxFunctionCount = Count;
-}
-
-void InstrProfSummary::addInternalCount(uint64_t Count) {
- addCount(Count);
- if (Count > MaxInternalBlockCount)
- MaxInternalBlockCount = Count;
-}
-
// Return an MDTuple with two elements. The first element is a string Key and
// the second is a uint64_t Value.
static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
Modified: llvm/trunk/lib/ProfileData/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/CMakeLists.txt?rev=270136&r1=270135&r2=270136&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/CMakeLists.txt (original)
+++ llvm/trunk/lib/ProfileData/CMakeLists.txt Thu May 19 16:07:12 2016
@@ -2,7 +2,7 @@ add_llvm_library(LLVMProfileData
InstrProf.cpp
InstrProfReader.cpp
InstrProfWriter.cpp
- ProfileSummary.cpp
+ ProfileSummaryBuilder.cpp
SampleProf.cpp
SampleProfReader.cpp
SampleProfWriter.cpp
Modified: llvm/trunk/lib/ProfileData/InstrProfReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfReader.cpp?rev=270136&r1=270135&r2=270136&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/InstrProfReader.cpp (original)
+++ llvm/trunk/lib/ProfileData/InstrProfReader.cpp Thu May 19 16:07:12 2016
@@ -576,6 +576,7 @@ bool IndexedInstrProfReader::hasFormat(c
const unsigned char *
IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
const unsigned char *Cur) {
+ using namespace IndexedInstrProf;
using namespace support;
if (Version >= IndexedInstrProf::Version4) {
const IndexedInstrProf::Summary *SummaryInLE =
@@ -594,15 +595,28 @@ IndexedInstrProfReader::readSummary(Inde
for (unsigned I = 0; I < SummarySize / sizeof(uint64_t); I++)
Dst[I] = endian::byte_swap<uint64_t, little>(Src[I]);
+ llvm::SummaryEntryVector DetailedSummary;
+ for (unsigned I = 0; I < SummaryData->NumCutoffEntries; I++) {
+ const IndexedInstrProf::Summary::Entry &Ent = SummaryData->getEntry(I);
+ DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
+ Ent.NumBlocks);
+ }
// initialize InstrProfSummary using the SummaryData from disk.
- this->Summary = llvm::make_unique<InstrProfSummary>(*(SummaryData.get()));
+ this->Summary = llvm::make_unique<InstrProfSummary>(
+ SummaryData->get(Summary::TotalBlockCount),
+ SummaryData->get(Summary::MaxBlockCount),
+ SummaryData->get(Summary::MaxInternalBlockCount),
+ SummaryData->get(Summary::MaxFunctionCount),
+ SummaryData->get(Summary::TotalNumBlocks),
+ SummaryData->get(Summary::TotalNumFunctions), DetailedSummary);
return Cur + SummarySize;
} else {
// For older version of profile data, we need to compute on the fly:
using namespace IndexedInstrProf;
- this->Summary =
- llvm::make_unique<InstrProfSummary>(ProfileSummary::DefaultCutoffs);
- this->Summary->computeDetailedSummary();
+ InstrProfSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
+ // FIXME: This only computes an empty summary. Need to call addRecord for
+ // all InstrProfRecords to get the correct summary.
+ this->Summary.reset(Builder.getSummary());
return Cur;
}
}
Modified: llvm/trunk/lib/ProfileData/InstrProfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfWriter.cpp?rev=270136&r1=270135&r2=270136&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/InstrProfWriter.cpp (original)
+++ llvm/trunk/lib/ProfileData/InstrProfWriter.cpp Thu May 19 16:07:12 2016
@@ -84,7 +84,7 @@ public:
typedef uint64_t offset_type;
support::endianness ValueProfDataEndianness;
- InstrProfSummary *TheProfileSummary;
+ InstrProfSummaryBuilder *SummaryBuilder;
InstrProfRecordWriterTrait() : ValueProfDataEndianness(support::little) {}
static hash_value_type ComputeHash(key_type_ref K) {
@@ -123,7 +123,7 @@ public:
endian::Writer<little> LE(Out);
for (const auto &ProfileData : *V) {
const InstrProfRecord &ProfRecord = ProfileData.second;
- TheProfileSummary->addRecord(ProfRecord);
+ SummaryBuilder->addRecord(ProfRecord);
LE.write<uint64_t>(ProfileData.first); // Function hash
LE.write<uint64_t>(ProfRecord.Counts.size());
@@ -215,8 +215,8 @@ void InstrProfWriter::writeImpl(ProfOStr
OnDiskChainedHashTableGenerator<InstrProfRecordWriterTrait> Generator;
using namespace IndexedInstrProf;
- InstrProfSummary PS(ProfileSummary::DefaultCutoffs);
- InfoObj->TheProfileSummary = &PS;
+ InstrProfSummaryBuilder ISB(ProfileSummaryBuilder::DefaultCutoffs);
+ InfoObj->SummaryBuilder = &ISB;
// Populate the hash table generator.
for (const auto &I : FunctionData)
@@ -245,7 +245,7 @@ void InstrProfWriter::writeImpl(ProfOStr
OS.write(0);
// Reserve space to write profile summary data.
- uint32_t NumEntries = ProfileSummary::DefaultCutoffs.size();
+ uint32_t NumEntries = ProfileSummaryBuilder::DefaultCutoffs.size();
uint32_t SummarySize = Summary::getSize(Summary::NumKinds, NumEntries);
// Remember the summary offset.
uint64_t SummaryOffset = OS.tell();
@@ -260,8 +260,9 @@ void InstrProfWriter::writeImpl(ProfOStr
IndexedInstrProf::allocSummary(SummarySize);
// Compute the Summary and copy the data to the data
// structure to be serialized out (to disk or buffer).
- setSummary(TheSummary.get(), PS);
- InfoObj->TheProfileSummary = 0;
+ InstrProfSummary *IPS = ISB.getSummary();
+ setSummary(TheSummary.get(), *IPS);
+ InfoObj->SummaryBuilder = 0;
// Now do the final patch:
PatchItem PatchItems[] = {
Removed: llvm/trunk/lib/ProfileData/ProfileSummary.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/ProfileSummary.cpp?rev=270135&view=auto
==============================================================================
--- llvm/trunk/lib/ProfileData/ProfileSummary.cpp (original)
+++ llvm/trunk/lib/ProfileData/ProfileSummary.cpp (removed)
@@ -1,368 +0,0 @@
-//=-- Profilesummary.cpp - Profile summary computation ----------------------=//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains support for computing profile summary data.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/IR/Attributes.h"
-#include "llvm/IR/Constants.h"
-#include "llvm/IR/Function.h"
-#include "llvm/IR/Metadata.h"
-#include "llvm/IR/Type.h"
-#include "llvm/ProfileData/InstrProf.h"
-#include "llvm/ProfileData/ProfileCommon.h"
-#include "llvm/ProfileData/SampleProf.h"
-#include "llvm/Support/Casting.h"
-
-using namespace llvm;
-
-// A set of cutoff values. Each value, when divided by ProfileSummary::Scale
-// (which is 1000000) is a desired percentile of total counts.
-const std::vector<uint32_t> ProfileSummary::DefaultCutoffs(
- {10000, /* 1% */
- 100000, /* 10% */
- 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,
- 900000, 950000, 990000, 999000, 999900, 999990, 999999});
-const char *ProfileSummary::KindStr[2] = {"InstrProf", "SampleProfile"};
-
-void InstrProfSummary::addRecord(const InstrProfRecord &R) {
- // The first counter is not necessarily an entry count for IR
- // instrumentation profiles.
- // Eventually MaxFunctionCount will become obsolete and this can be
- // removed.
- addEntryCount(R.Counts[0]);
- for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
- addInternalCount(R.Counts[I]);
-}
-
-// To compute the detailed summary, we consider each line containing samples as
-// equivalent to a block with a count in the instrumented profile.
-void SampleProfileSummary::addRecord(const sampleprof::FunctionSamples &FS) {
- NumFunctions++;
- if (FS.getHeadSamples() > MaxFunctionCount)
- MaxFunctionCount = FS.getHeadSamples();
- for (const auto &I : FS.getBodySamples())
- addCount(I.second.getSamples());
-}
-
-// The argument to this method is a vector of cutoff percentages and the return
-// value is a vector of (Cutoff, MinCount, NumCounts) triplets.
-void ProfileSummary::computeDetailedSummary() {
- if (DetailedSummaryCutoffs.empty())
- return;
- auto Iter = CountFrequencies.begin();
- auto End = CountFrequencies.end();
- std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
-
- uint32_t CountsSeen = 0;
- uint64_t CurrSum = 0, Count = 0;
-
- for (uint32_t Cutoff : DetailedSummaryCutoffs) {
- assert(Cutoff <= 999999);
- APInt Temp(128, TotalCount);
- APInt N(128, Cutoff);
- APInt D(128, ProfileSummary::Scale);
- Temp *= N;
- Temp = Temp.sdiv(D);
- uint64_t DesiredCount = Temp.getZExtValue();
- assert(DesiredCount <= TotalCount);
- while (CurrSum < DesiredCount && Iter != End) {
- Count = Iter->first;
- uint32_t Freq = Iter->second;
- CurrSum += (Count * Freq);
- CountsSeen += Freq;
- Iter++;
- }
- assert(CurrSum >= DesiredCount);
- ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen};
- DetailedSummary.push_back(PSE);
- }
-}
-
-// Returns true if the function is a hot function.
-bool ProfileSummary::isFunctionHot(const Function *F) {
- // FIXME: update when summary data is stored in module's metadata.
- return false;
-}
-
-// Returns true if the function is a cold function.
-bool ProfileSummary::isFunctionUnlikely(const Function *F) {
- if (F->hasFnAttribute(Attribute::Cold)) {
- return true;
- }
- if (!F->getEntryCount()) {
- return false;
- }
- // FIXME: update when summary data is stored in module's metadata.
- return (*F->getEntryCount()) == 0;
-}
-
-InstrProfSummary::InstrProfSummary(const IndexedInstrProf::Summary &S)
- : ProfileSummary(PSK_Instr),
- MaxInternalBlockCount(
- S.get(IndexedInstrProf::Summary::MaxInternalBlockCount)) {
-
- TotalCount = S.get(IndexedInstrProf::Summary::TotalBlockCount);
- MaxCount = S.get(IndexedInstrProf::Summary::MaxBlockCount);
- MaxFunctionCount = S.get(IndexedInstrProf::Summary::MaxFunctionCount);
- NumCounts = S.get(IndexedInstrProf::Summary::TotalNumBlocks);
- NumFunctions = S.get(IndexedInstrProf::Summary::TotalNumFunctions);
-
- for (unsigned I = 0; I < S.NumCutoffEntries; I++) {
- const IndexedInstrProf::Summary::Entry &Ent = S.getEntry(I);
- DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
- Ent.NumBlocks);
- }
-}
-
-void InstrProfSummary::addEntryCount(uint64_t Count) {
- addCount(Count);
- NumFunctions++;
- if (Count > MaxFunctionCount)
- MaxFunctionCount = Count;
-}
-
-void InstrProfSummary::addInternalCount(uint64_t Count) {
- addCount(Count);
- if (Count > MaxInternalBlockCount)
- MaxInternalBlockCount = Count;
-}
-
-// Return an MDTuple with two elements. The first element is a string Key and
-// the second is a uint64_t Value.
-static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
- uint64_t Val) {
- Type *Int64Ty = Type::getInt64Ty(Context);
- Metadata *Ops[2] = {MDString::get(Context, Key),
- ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Val))};
- return MDTuple::get(Context, Ops);
-}
-
-// Return an MDTuple with two elements. The first element is a string Key and
-// the second is a string Value.
-static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
- const char *Val) {
- Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
- return MDTuple::get(Context, Ops);
-}
-
-// This returns an MDTuple representing the detiled summary. The tuple has two
-// elements: a string "DetailedSummary" and an MDTuple representing the value
-// of the detailed summary. Each element of this tuple is again an MDTuple whose
-// elements are the (Cutoff, MinCount, NumCounts) triplet of the
-// DetailedSummaryEntry.
-Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
- std::vector<Metadata *> Entries;
- Type *Int32Ty = Type::getInt32Ty(Context);
- Type *Int64Ty = Type::getInt64Ty(Context);
- for (auto &Entry : DetailedSummary) {
- Metadata *EntryMD[3] = {
- ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)),
- ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)),
- ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
- Entries.push_back(MDTuple::get(Context, EntryMD));
- }
- Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
- MDTuple::get(Context, Entries)};
- return MDTuple::get(Context, Ops);
-}
-
-// This returns an MDTuple representing this ProfileSummary object. The first
-// entry of this tuple is another MDTuple of two elements: a string
-// "ProfileFormat" and a string representing the format ("InstrProf" or
-// "SampleProfile"). The rest of the elements of the outer MDTuple are specific
-// to the kind of profile summary as returned by getFormatSpecificMD.
-Metadata *ProfileSummary::getMD(LLVMContext &Context) {
- std::vector<Metadata *> Components;
- Components.push_back(getKeyValMD(Context, "ProfileFormat", getKindStr()));
- std::vector<Metadata *> Res = getFormatSpecificMD(Context);
- Components.insert(Components.end(), Res.begin(), Res.end());
- return MDTuple::get(Context, Components);
-}
-
-// Returns a vector of MDTuples specific to InstrProfSummary. The first six
-// elements of this vector are (Key, Val) pairs of the six scalar fields of
-// InstrProfSummary (TotalCount, MaxBlockCount, MaxInternalBlockCount,
-// MaxFunctionCount, NumBlocks, NumFunctions). The last element of this vector
-// is an MDTuple returned by getDetailedSummaryMD.
-std::vector<Metadata *>
-InstrProfSummary::getFormatSpecificMD(LLVMContext &Context) {
- std::vector<Metadata *> Components;
-
- Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount()));
- Components.push_back(
- getKeyValMD(Context, "MaxBlockCount", getMaxBlockCount()));
- Components.push_back(getKeyValMD(Context, "MaxInternalBlockCount",
- getMaxInternalBlockCount()));
- Components.push_back(
- getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
- Components.push_back(getKeyValMD(Context, "NumBlocks", getNumBlocks()));
- Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions()));
-
- Components.push_back(getDetailedSummaryMD(Context));
- return Components;
-}
-
-std::vector<Metadata *>
-SampleProfileSummary::getFormatSpecificMD(LLVMContext &Context) {
- std::vector<Metadata *> Components;
-
- Components.push_back(getKeyValMD(Context, "TotalSamples", getTotalSamples()));
- Components.push_back(
- getKeyValMD(Context, "MaxSamplesPerLine", getMaxSamplesPerLine()));
- Components.push_back(
- getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
- Components.push_back(
- getKeyValMD(Context, "NumLinesWithSamples", getNumLinesWithSamples()));
- Components.push_back(getKeyValMD(Context, "NumFunctions", NumFunctions));
-
- Components.push_back(getDetailedSummaryMD(Context));
- return Components;
-}
-
-// Parse an MDTuple representing (Key, Val) pair.
-static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
- if (!MD)
- return false;
- if (MD->getNumOperands() != 2)
- return false;
- MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
- ConstantAsMetadata *ValMD = dyn_cast<ConstantAsMetadata>(MD->getOperand(1));
- if (!KeyMD || !ValMD)
- return false;
- if (!KeyMD->getString().equals(Key))
- return false;
- Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
- return true;
-}
-
-// Check if an MDTuple represents a (Key, Val) pair.
-static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
- if (!MD || MD->getNumOperands() != 2)
- return false;
- MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
- MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1));
- if (!KeyMD || !ValMD)
- return false;
- if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
- return false;
- return true;
-}
-
-// Parse an MDTuple representing detailed summary.
-static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
- if (!MD || MD->getNumOperands() != 2)
- return false;
- MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
- if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
- return false;
- MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1));
- if (!EntriesMD)
- return false;
- for (auto &&MDOp : EntriesMD->operands()) {
- MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp);
- if (!EntryMD || EntryMD->getNumOperands() != 3)
- return false;
- ConstantAsMetadata *Op0 =
- dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0));
- ConstantAsMetadata *Op1 =
- dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1));
- ConstantAsMetadata *Op2 =
- dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2));
-
- if (!Op0 || !Op1 || !Op2)
- return false;
- Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(),
- cast<ConstantInt>(Op1->getValue())->getZExtValue(),
- cast<ConstantInt>(Op2->getValue())->getZExtValue());
- }
- return true;
-}
-
-// Parse an MDTuple representing an InstrProfSummary object.
-static ProfileSummary *getInstrProfSummaryFromMD(MDTuple *Tuple) {
- uint64_t NumBlocks, TotalCount, NumFunctions, MaxFunctionCount, MaxBlockCount,
- MaxInternalBlockCount;
- SummaryEntryVector Summary;
-
- if (Tuple->getNumOperands() != 8)
- return nullptr;
-
- // Skip operand 0 which has been already parsed in the caller
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalCount",
- TotalCount))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxBlockCount",
- MaxBlockCount))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxInternalBlockCount",
- MaxInternalBlockCount))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "MaxFunctionCount",
- MaxFunctionCount))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumBlocks", NumBlocks))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(6)), "NumFunctions",
- NumFunctions))
- return nullptr;
- if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(7)), Summary))
- return nullptr;
- return new InstrProfSummary(TotalCount, MaxBlockCount, MaxInternalBlockCount,
- MaxFunctionCount, NumBlocks, NumFunctions,
- Summary);
-}
-
-// Parse an MDTuple representing a SampleProfileSummary object.
-static ProfileSummary *getSampleProfileSummaryFromMD(MDTuple *Tuple) {
- uint64_t TotalSamples, MaxSamplesPerLine, MaxFunctionCount,
- NumLinesWithSamples, NumFunctions;
- SummaryEntryVector Summary;
-
- if (Tuple->getNumOperands() != 7)
- return nullptr;
-
- // Skip operand 0 which has been already parsed in the caller
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(1)), "TotalSamples",
- TotalSamples))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(2)), "MaxSamplesPerLine",
- MaxSamplesPerLine))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(3)), "MaxFunctionCount",
- MaxFunctionCount))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(4)), "NumLinesWithSamples",
- NumLinesWithSamples))
- return nullptr;
- if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(5)), "NumFunctions",
- NumFunctions))
- return nullptr;
- if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(6)), Summary))
- return nullptr;
- return new SampleProfileSummary(TotalSamples, MaxSamplesPerLine,
- MaxFunctionCount, NumLinesWithSamples,
- NumFunctions, Summary);
-}
-
-ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
- if (!isa<MDTuple>(MD))
- return nullptr;
- MDTuple *Tuple = cast<MDTuple>(MD);
- auto &FormatMD = Tuple->getOperand(0);
- if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
- "SampleProfile"))
- return getSampleProfileSummaryFromMD(Tuple);
- else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
- "InstrProf"))
- return getInstrProfSummaryFromMD(Tuple);
- else
- return nullptr;
-}
Added: llvm/trunk/lib/ProfileData/ProfileSummaryBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/ProfileSummaryBuilder.cpp?rev=270136&view=auto
==============================================================================
--- llvm/trunk/lib/ProfileData/ProfileSummaryBuilder.cpp (added)
+++ llvm/trunk/lib/ProfileData/ProfileSummaryBuilder.cpp Thu May 19 16:07:12 2016
@@ -0,0 +1,113 @@
+//=-- ProfilesummaryBuilder.cpp - Profile summary computation ---------------=//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file contains support for computing profile summary data.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/Attributes.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Metadata.h"
+#include "llvm/IR/Type.h"
+#include "llvm/ProfileData/InstrProf.h"
+#include "llvm/ProfileData/ProfileCommon.h"
+#include "llvm/ProfileData/SampleProf.h"
+#include "llvm/Support/Casting.h"
+
+using namespace llvm;
+
+// A set of cutoff values. Each value, when divided by ProfileSummary::Scale
+// (which is 1000000) is a desired percentile of total counts.
+const std::vector<uint32_t> ProfileSummaryBuilder::DefaultCutoffs(
+ {10000, /* 1% */
+ 100000, /* 10% */
+ 200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,
+ 900000, 950000, 990000, 999000, 999900, 999990, 999999});
+
+void InstrProfSummaryBuilder::addRecord(const InstrProfRecord &R) {
+ // The first counter is not necessarily an entry count for IR
+ // instrumentation profiles.
+ // Eventually MaxFunctionCount will become obsolete and this can be
+ // removed.
+ addEntryCount(R.Counts[0]);
+ for (size_t I = 1, E = R.Counts.size(); I < E; ++I)
+ addInternalCount(R.Counts[I]);
+}
+
+// To compute the detailed summary, we consider each line containing samples as
+// equivalent to a block with a count in the instrumented profile.
+void SampleProfileSummaryBuilder::addRecord(
+ const sampleprof::FunctionSamples &FS) {
+ NumFunctions++;
+ if (FS.getHeadSamples() > MaxFunctionCount)
+ MaxFunctionCount = FS.getHeadSamples();
+ for (const auto &I : FS.getBodySamples())
+ addCount(I.second.getSamples());
+}
+
+// The argument to this method is a vector of cutoff percentages and the return
+// value is a vector of (Cutoff, MinCount, NumCounts) triplets.
+void ProfileSummaryBuilder::computeDetailedSummary() {
+ if (DetailedSummaryCutoffs.empty())
+ return;
+ auto Iter = CountFrequencies.begin();
+ auto End = CountFrequencies.end();
+ std::sort(DetailedSummaryCutoffs.begin(), DetailedSummaryCutoffs.end());
+
+ uint32_t CountsSeen = 0;
+ uint64_t CurrSum = 0, Count = 0;
+
+ for (uint32_t Cutoff : DetailedSummaryCutoffs) {
+ assert(Cutoff <= 999999);
+ APInt Temp(128, TotalCount);
+ APInt N(128, Cutoff);
+ APInt D(128, ProfileSummary::Scale);
+ Temp *= N;
+ Temp = Temp.sdiv(D);
+ uint64_t DesiredCount = Temp.getZExtValue();
+ assert(DesiredCount <= TotalCount);
+ while (CurrSum < DesiredCount && Iter != End) {
+ Count = Iter->first;
+ uint32_t Freq = Iter->second;
+ CurrSum += (Count * Freq);
+ CountsSeen += Freq;
+ Iter++;
+ }
+ assert(CurrSum >= DesiredCount);
+ ProfileSummaryEntry PSE = {Cutoff, Count, CountsSeen};
+ DetailedSummary.push_back(PSE);
+ }
+}
+
+SampleProfileSummary *SampleProfileSummaryBuilder::getSummary() {
+ computeDetailedSummary();
+ return new SampleProfileSummary(TotalCount, MaxCount, MaxFunctionCount,
+ NumCounts, NumFunctions, DetailedSummary);
+}
+
+InstrProfSummary *InstrProfSummaryBuilder::getSummary() {
+ computeDetailedSummary();
+ return new InstrProfSummary(TotalCount, MaxCount, MaxInternalBlockCount,
+ MaxFunctionCount, NumCounts, NumFunctions,
+ DetailedSummary);
+}
+
+void InstrProfSummaryBuilder::addEntryCount(uint64_t Count) {
+ addCount(Count);
+ NumFunctions++;
+ if (Count > MaxFunctionCount)
+ MaxFunctionCount = Count;
+}
+
+void InstrProfSummaryBuilder::addInternalCount(uint64_t Count) {
+ addCount(Count);
+ if (Count > MaxInternalBlockCount)
+ MaxInternalBlockCount = Count;
+}
Modified: llvm/trunk/lib/ProfileData/SampleProfReader.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/SampleProfReader.cpp?rev=270136&r1=270135&r2=270136&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/SampleProfReader.cpp (original)
+++ llvm/trunk/lib/ProfileData/SampleProfReader.cpp Thu May 19 16:07:12 2016
@@ -793,10 +793,10 @@ SampleProfileReader::create(std::unique_
// For text and GCC file formats, we compute the summary after reading the
// profile. Binary format has the profile summary in its header.
void SampleProfileReader::computeSummary() {
- Summary.reset(new SampleProfileSummary(ProfileSummary::DefaultCutoffs));
+ SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
for (const auto &I : Profiles) {
const FunctionSamples &Profile = I.second;
- Summary->addRecord(Profile);
+ Builder.addRecord(Profile);
}
- Summary->computeDetailedSummary();
+ Summary.reset(Builder.getSummary());
}
Modified: llvm/trunk/lib/ProfileData/SampleProfWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/SampleProfWriter.cpp?rev=270136&r1=270135&r2=270136&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/SampleProfWriter.cpp (original)
+++ llvm/trunk/lib/ProfileData/SampleProfWriter.cpp Thu May 19 16:07:12 2016
@@ -255,10 +255,10 @@ SampleProfileWriter::create(std::unique_
void SampleProfileWriter::computeSummary(
const StringMap<FunctionSamples> &ProfileMap) {
- Summary.reset(new SampleProfileSummary(ProfileSummary::DefaultCutoffs));
+ SampleProfileSummaryBuilder Builder(ProfileSummaryBuilder::DefaultCutoffs);
for (const auto &I : ProfileMap) {
const FunctionSamples &Profile = I.second;
- Summary->addRecord(Profile);
+ Builder.addRecord(Profile);
}
- Summary->computeDetailedSummary();
+ Summary.reset(Builder.getSummary());
}
Modified: llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp?rev=270136&r1=270135&r2=270136&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp (original)
+++ llvm/trunk/tools/llvm-profdata/llvm-profdata.cpp Thu May 19 16:07:12 2016
@@ -281,7 +281,7 @@ static int showInstrProfile(std::string
if (ShowDetailedSummary && DetailedSummaryCutoffs.empty()) {
Cutoffs = {800000, 900000, 950000, 990000, 999000, 999900, 999990};
}
- InstrProfSummary PS(Cutoffs);
+ InstrProfSummaryBuilder Builder(Cutoffs);
if (Error E = ReaderOrErr.takeError())
exitWithError(std::move(E), Filename);
@@ -302,7 +302,7 @@ static int showInstrProfile(std::string
}
assert(Func.Counts.size() > 0 && "function missing entry counter");
- PS.addRecord(Func);
+ Builder.addRecord(Func);
if (Show) {
@@ -353,18 +353,19 @@ static int showInstrProfile(std::string
if (ShowCounts && TextFormat)
return 0;
-
+ std::unique_ptr<InstrProfSummary> PS(Builder.getSummary());
if (ShowAllFunctions || !ShowFunction.empty())
OS << "Functions shown: " << ShownFunctions << "\n";
- OS << "Total functions: " << PS.getNumFunctions() << "\n";
- OS << "Maximum function count: " << PS.getMaxFunctionCount() << "\n";
- OS << "Maximum internal block count: " << PS.getMaxInternalBlockCount() << "\n";
+ OS << "Total functions: " << PS->getNumFunctions() << "\n";
+ OS << "Maximum function count: " << PS->getMaxFunctionCount() << "\n";
+ OS << "Maximum internal block count: " << PS->getMaxInternalBlockCount()
+ << "\n";
if (ShowDetailedSummary) {
OS << "Detailed summary:\n";
- OS << "Total number of blocks: " << PS.getNumBlocks() << "\n";
- OS << "Total count: " << PS.getTotalCount() << "\n";
- for (auto Entry : PS.getDetailedSummary()) {
+ OS << "Total number of blocks: " << PS->getNumBlocks() << "\n";
+ OS << "Total count: " << PS->getTotalCount() << "\n";
+ for (auto Entry : PS->getDetailedSummary()) {
OS << Entry.NumCounts << " blocks with count >= " << Entry.MinCount
<< " account for "
<< format("%0.6g", (float)Entry.Cutoff / ProfileSummary::Scale * 100)
More information about the llvm-commits
mailing list