[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