<div dir="ltr"><div>Just to clear up some confusion (on my behalf). Autofdo v0.13 doesn't work because it outputs the "flat" text format.  However, autofdo was changed to output the hierarchical format before going to the binary format.  This version can be used (commit d1102c8).  Alternatively, you can keep an old version of llvm-profdata that understands binary version 102, and use it to convert the profile into text format.<br><br></div>Rob.<br><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 24 February 2016 at 20:18, Robert Lougher <span dir="ltr"><<a href="mailto:rob.lougher@gmail.com" target="_blank">rob.lougher@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div><div>Hi Diego,<br><br></div>Thanks for the information (and replying so quickly).  I was able to use autofdo  v0.13 to output the profile in text format and use it with LLVM.  I did have to make a minor tweak to output a space before each sample line, as the change to support hierarchical sample profiles (r248865) requires the lines to be indented.<br><br></div>Thanks,<br></div>Rob. <br><div><div class="h5"><div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On 23 February 2016 at 18:49, Diego Novillo <span dir="ltr"><<a href="mailto:dnovillo@google.com" target="_blank">dnovillo@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Yes, I'm working on it.<div><br></div><div>It's going to take me a little longer because I want to avoid the dual implementation problem we have at the moment.  Currently, the Perf converter generates the binary LLVM format, but an older version of it (no summaries).  I am adding two things that will simplify future changes:</div><div><br></div><div>1- A reader for the text format generated by autofdo's sample_merger.  This will give LLVM the capability of reading the text format generated by the autofdo tools.</div><div><br></div><div>2- On the autofdo tool side, I will make it optionally depend on LLVM itself.  This way the converter will be able to use LLVM's own ProfileData library, if it's present at configure time.</div><div><br></div><div>One option you may try in the meantime is to use v0.13 of autofdo tool (<a href="https://github.com/google/autofdo/releases/tag/v0.13" target="_blank">https://github.com/google/autofdo/releases/tag/v0.13</a>).  This used to emit the profile in LLVM's text format.  I believe that should still work.</div><span><font color="#888888"><div><br></div><div><br></div><div>Diego.</div><div><br></div></font></span></div><div><div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Feb 23, 2016 at 1:42 PM, Robert Lougher via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div>Hi,<br><br></div>I've started playing around with sample-based profiling in the last day or two.  According to the documentation, you can use the Linux perf profiler and convert the output to LLVM sample profile format using the AutoFDO "create_llvm_prof" converter.  However, this no longer works as the converter hasn't been updated to reflect these changes.  Are there any plans to fix AutoFDO?<br><br></div><div>Thanks,<br></div><div class="gmail_extra">Rob.<div><div><br><br><div class="gmail_quote">On 19 February 2016 at 03:15, Easwaran Raman via llvm-commits <span dir="ltr"><<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Author: eraman<br>
Date: Thu Feb 18 21:15:33 2016<br>
New Revision: 261304<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=261304&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=261304&view=rev</a><br>
Log:<br>
Add profile summary support for sample profile.<br>
<br>
Differential Revision: <a href="http://reviews.llvm.org/D17178" rel="noreferrer" target="_blank">http://reviews.llvm.org/D17178</a><br>
<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/ProfileData/InstrProf.h<br>
    llvm/trunk/include/llvm/ProfileData/ProfileCommon.h<br>
    llvm/trunk/include/llvm/ProfileData/SampleProf.h<br>
    llvm/trunk/include/llvm/ProfileData/SampleProfReader.h<br>
    llvm/trunk/include/llvm/ProfileData/SampleProfWriter.h<br>
    llvm/trunk/lib/ProfileData/InstrProfReader.cpp<br>
    llvm/trunk/lib/ProfileData/InstrProfWriter.cpp<br>
    llvm/trunk/lib/ProfileData/ProfileSummary.cpp<br>
    llvm/trunk/lib/ProfileData/SampleProfReader.cpp<br>
    llvm/trunk/lib/ProfileData/SampleProfWriter.cpp<br>
    llvm/trunk/test/Transforms/SampleProfile/Inputs/fnptr.binprof<br>
    llvm/trunk/unittests/ProfileData/SampleProfTest.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/ProfileData/InstrProf.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProf.h?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProf.h?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ProfileData/InstrProf.h (original)<br>
+++ llvm/trunk/include/llvm/ProfileData/InstrProf.h Thu Feb 18 21:15:33 2016<br>
@@ -681,14 +681,6 @@ struct Header {<br>
   uint64_t HashOffset;<br>
 };<br>
<br>
-static const uint32_t SummaryCutoffs[] = {<br>
-    10000,  /*  1% */<br>
-    100000, /* 10% */<br>
-    200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000,<br>
-    800000, 900000, 950000, 990000, 999000, 999900, 999990, 999999};<br>
-static const uint32_t NumSummaryCutoffs =<br>
-    sizeof(SummaryCutoffs) / sizeof(*SummaryCutoffs);<br>
-<br>
 // Profile summary data recorded in the profile data file in indexed<br>
 // format. It is introduced in version 4. The summary data follows<br>
 // right after the profile file header.<br>
<br>
Modified: llvm/trunk/include/llvm/ProfileData/ProfileCommon.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/ProfileCommon.h?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/ProfileCommon.h?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ProfileData/ProfileCommon.h (original)<br>
+++ llvm/trunk/include/llvm/ProfileData/ProfileCommon.h Thu Feb 18 21:15:33 2016<br>
@@ -24,6 +24,9 @@ namespace llvm {<br>
 namespace IndexedInstrProf {<br>
 struct Summary;<br>
 }<br>
+namespace sampleprof {<br>
+class FunctionSamples;<br>
+}<br>
 struct InstrProfRecord;<br>
 // The profile summary is one or more (Cutoff, MinCount, NumCounts) triplets.<br>
 // The semantics of counts depend on the type of profile. For instrumentation<br>
@@ -55,12 +58,18 @@ protected:<br>
       : DetailedSummaryCutoffs(Cutoffs), TotalCount(0), MaxCount(0),<br>
         NumCounts(0) {}<br>
   ProfileSummary() : TotalCount(0), MaxCount(0), NumCounts(0) {}<br>
+  ProfileSummary(std::vector<ProfileSummaryEntry> DetailedSummary,<br>
+                 uint64_t TotalCount, uint64_t MaxCount, uint32_t NumCounts)<br>
+      : DetailedSummary(DetailedSummary), TotalCount(TotalCount),<br>
+        MaxCount(MaxCount), NumCounts(NumCounts) {}<br>
   inline void addCount(uint64_t Count);<br>
<br>
 public:<br>
   static const int Scale = 1000000;<br>
   inline std::vector<ProfileSummaryEntry> &getDetailedSummary();<br>
   void computeDetailedSummary();<br>
+  /// \brief A vector of useful cutoff values for detailed summary.<br>
+  static const std::vector<uint32_t> DefaultCutoffs;<br>
 };<br>
<br>
 class InstrProfSummary : public ProfileSummary {<br>
@@ -83,6 +92,28 @@ public:<br>
   uint64_t getMaxInternalBlockCount() { return MaxInternalBlockCount; }<br>
 };<br>
<br>
+class SampleProfileSummary : public ProfileSummary {<br>
+  uint64_t MaxHeadSamples;<br>
+  uint32_t NumFunctions;<br>
+<br>
+public:<br>
+  uint32_t getNumLinesWithSamples() { return NumCounts; }<br>
+  uint64_t getTotalSamples() { return TotalCount; }<br>
+  uint32_t getNumFunctions() { return NumFunctions; }<br>
+  uint64_t getMaxHeadSamples() { return MaxHeadSamples; }<br>
+  uint64_t getMaxSamplesPerLine() { return MaxCount; }<br>
+  void addRecord(const sampleprof::FunctionSamples &FS);<br>
+  SampleProfileSummary(std::vector<uint32_t> Cutoffs)<br>
+      : ProfileSummary(Cutoffs), MaxHeadSamples(0), NumFunctions(0) {}<br>
+  SampleProfileSummary(uint64_t TotalSamples, uint64_t MaxSamplesPerLine,<br>
+                       uint64_t MaxHeadSamples, int32_t NumLinesWithSamples,<br>
+                       uint32_t NumFunctions,<br>
+                       std::vector<ProfileSummaryEntry> DetailedSummary)<br>
+      : ProfileSummary(DetailedSummary, TotalSamples, MaxSamplesPerLine,<br>
+                       NumLinesWithSamples),<br>
+        MaxHeadSamples(MaxHeadSamples), NumFunctions(NumFunctions) {}<br>
+};<br>
+<br>
 // This is called when a count is seen in the profile.<br>
 void ProfileSummary::addCount(uint64_t Count) {<br>
   TotalCount += Count;<br>
<br>
Modified: llvm/trunk/include/llvm/ProfileData/SampleProf.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/SampleProf.h?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/SampleProf.h?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ProfileData/SampleProf.h (original)<br>
+++ llvm/trunk/include/llvm/ProfileData/SampleProf.h Thu Feb 18 21:15:33 2016<br>
@@ -74,7 +74,7 @@ static inline uint64_t SPMagic() {<br>
          uint64_t('2') << (64 - 56) | uint64_t(0xff);<br>
 }<br>
<br>
-static inline uint64_t SPVersion() { return 102; }<br>
+static inline uint64_t SPVersion() { return 103; }<br>
<br>
 /// Represents the relative location of an instruction.<br>
 ///<br>
<br>
Modified: llvm/trunk/include/llvm/ProfileData/SampleProfReader.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/SampleProfReader.h?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/SampleProfReader.h?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ProfileData/SampleProfReader.h (original)<br>
+++ llvm/trunk/include/llvm/ProfileData/SampleProfReader.h Thu Feb 18 21:15:33 2016<br>
@@ -129,6 +129,30 @@<br>
 // VERSION (uint32_t)<br>
 //    File format version number computed by SPVersion()<br>
 //<br>
+// SUMMARY<br>
+//    TOTAL_COUNT (uint64_t)<br>
+//        Total number of samples in the profile.<br>
+//    MAX_COUNT (uint64_t)<br>
+//        Maximum value of samples on a line.<br>
+//    MAX_HEAD_SAMPLES (uint64_t)<br>
+//        Maximum number of head samples.<br>
+//    NUM_COUNTS (uint64_t)<br>
+//        Number of lines with samples.<br>
+//    NUM_FUNCTIONS (uint64_t)<br>
+//        Number of functions with samples.<br>
+//    NUM_DETAILED_SUMMARY_ENTRIES (size_t)<br>
+//        Number of entries in detailed summary<br>
+//    DETAILED_SUMMARY<br>
+//        A list of detailed summary entry. Each entry consists of<br>
+//        CUTOFF (uint32_t)<br>
+//            Required percentile of total sample count expressed as a fraction<br>
+//            multiplied by 1000000.<br>
+//        MIN_COUNT (uint64_t)<br>
+//            The minimum number of samples required to reach the target<br>
+//            CUTOFF.<br>
+//        NUM_COUNTS (uint64_t)<br>
+//            Number of samples to get to the desrired percentile.<br>
+//<br>
 // NAME TABLE<br>
 //    SIZE (uint32_t)<br>
 //        Number of entries in the name table.<br>
@@ -190,6 +214,7 @@<br>
 #include "llvm/IR/DiagnosticInfo.h"<br>
 #include "llvm/IR/Function.h"<br>
 #include "llvm/IR/LLVMContext.h"<br>
+#include "llvm/ProfileData/ProfileCommon.h"<br>
 #include "llvm/ProfileData/SampleProf.h"<br>
 #include "llvm/Support/Debug.h"<br>
 #include "llvm/Support/ErrorHandling.h"<br>
@@ -270,6 +295,9 @@ public:<br>
   static ErrorOr<std::unique_ptr<SampleProfileReader>><br>
   create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C);<br>
<br>
+  /// \brief Return the profile summary.<br>
+  SampleProfileSummary &getSummary() { return *(Summary.get()); }<br>
+<br>
 protected:<br>
   /// \brief Map every function to its associated profile.<br>
   ///<br>
@@ -283,6 +311,12 @@ protected:<br>
<br>
   /// \brief Memory buffer holding the profile file.<br>
   std::unique_ptr<MemoryBuffer> Buffer;<br>
+<br>
+  /// \brief Profile summary information.<br>
+  std::unique_ptr<SampleProfileSummary> Summary;<br>
+<br>
+  /// \brief Compute summary for this profile.<br>
+  void computeSummary();<br>
 };<br>
<br>
 class SampleProfileReaderText : public SampleProfileReader {<br>
@@ -348,6 +382,12 @@ protected:<br>
<br>
   /// Function name table.<br>
   std::vector<StringRef> NameTable;<br>
+<br>
+private:<br>
+  std::error_code readSummaryEntry(std::vector<ProfileSummaryEntry> &Entries);<br>
+<br>
+  /// \brief Read profile summary.<br>
+  std::error_code readSummary();<br>
 };<br>
<br>
 typedef SmallVector<FunctionSamples *, 10> InlineCallStack;<br>
<br>
Modified: llvm/trunk/include/llvm/ProfileData/SampleProfWriter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/SampleProfWriter.h?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/SampleProfWriter.h?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/ProfileData/SampleProfWriter.h (original)<br>
+++ llvm/trunk/include/llvm/ProfileData/SampleProfWriter.h Thu Feb 18 21:15:33 2016<br>
@@ -15,6 +15,7 @@<br>
<br>
 #include "llvm/ADT/MapVector.h"<br>
 #include "llvm/ADT/StringRef.h"<br>
+#include "llvm/ProfileData/ProfileCommon.h"<br>
 #include "llvm/ProfileData/SampleProf.h"<br>
 #include "llvm/Support/ErrorOr.h"<br>
 #include "llvm/Support/FileSystem.h"<br>
@@ -42,7 +43,6 @@ public:<br>
   std::error_code write(const StringMap<FunctionSamples> &ProfileMap) {<br>
     if (std::error_code EC = writeHeader(ProfileMap))<br>
       return EC;<br>
-<br>
     for (const auto &I : ProfileMap) {<br>
       StringRef FName = I.first();<br>
       const FunctionSamples &Profile = I.second;<br>
@@ -75,6 +75,12 @@ protected:<br>
<br>
   /// \brief Output stream where to emit the profile to.<br>
   std::unique_ptr<raw_ostream> OutputStream;<br>
+<br>
+  /// \brief Profile summary.<br>
+  std::unique_ptr<SampleProfileSummary> Summary;<br>
+<br>
+  /// \brief Compute summary for this profile.<br>
+  void computeSummary(const StringMap<FunctionSamples> &ProfileMap);<br>
 };<br>
<br>
 /// \brief Sample-based profile writer (text format).<br>
@@ -113,6 +119,7 @@ protected:<br>
<br>
   std::error_code<br>
   writeHeader(const StringMap<FunctionSamples> &ProfileMap) override;<br>
+  std::error_code writeSummary();<br>
   std::error_code writeNameIdx(StringRef FName);<br>
   std::error_code writeBody(StringRef FName, const FunctionSamples &S);<br>
<br>
<br>
Modified: llvm/trunk/lib/ProfileData/InstrProfReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfReader.cpp?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfReader.cpp?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ProfileData/InstrProfReader.cpp (original)<br>
+++ llvm/trunk/lib/ProfileData/InstrProfReader.cpp Thu Feb 18 21:15:33 2016<br>
@@ -595,9 +595,8 @@ IndexedInstrProfReader::readSummary(Inde<br>
   } else {<br>
     // For older version of profile data, we need to compute on the fly:<br>
     using namespace IndexedInstrProf;<br>
-    std::vector<uint32_t> Cutoffs(&SummaryCutoffs[0],<br>
-                                  &SummaryCutoffs[NumSummaryCutoffs]);<br>
-    this->Summary = llvm::make_unique<InstrProfSummary>(Cutoffs);<br>
+    this->Summary =<br>
+        llvm::make_unique<InstrProfSummary>(ProfileSummary::DefaultCutoffs);<br>
     this->Summary->computeDetailedSummary();<br>
     return Cur;<br>
   }<br>
<br>
Modified: llvm/trunk/lib/ProfileData/InstrProfWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfWriter.cpp?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProfWriter.cpp?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ProfileData/InstrProfWriter.cpp (original)<br>
+++ llvm/trunk/lib/ProfileData/InstrProfWriter.cpp Thu Feb 18 21:15:33 2016<br>
@@ -217,9 +217,7 @@ void InstrProfWriter::writeImpl(ProfOStr<br>
   OnDiskChainedHashTableGenerator<InstrProfRecordWriterTrait> Generator;<br>
<br>
   using namespace IndexedInstrProf;<br>
-  std::vector<uint32_t> Cutoffs(&SummaryCutoffs[0],<br>
-                                &SummaryCutoffs[NumSummaryCutoffs]);<br>
-  InstrProfSummary PS(Cutoffs);<br>
+  InstrProfSummary PS(ProfileSummary::DefaultCutoffs);<br>
   InfoObj->TheProfileSummary = &PS;<br>
<br>
   // Populate the hash table generator.<br>
@@ -249,7 +247,7 @@ void InstrProfWriter::writeImpl(ProfOStr<br>
   OS.write(0);<br>
<br>
   // Reserve space to write profile summary data.<br>
-  uint32_t NumEntries = Cutoffs.size();<br>
+  uint32_t NumEntries = ProfileSummary::DefaultCutoffs.size();<br>
   uint32_t SummarySize = Summary::getSize(Summary::NumKinds, NumEntries);<br>
   // Remember the summary offset.<br>
   uint64_t SummaryOffset = OS.tell();<br>
<br>
Modified: llvm/trunk/lib/ProfileData/ProfileSummary.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/ProfileSummary.cpp?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/ProfileSummary.cpp?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ProfileData/ProfileSummary.cpp (original)<br>
+++ llvm/trunk/lib/ProfileData/ProfileSummary.cpp Thu Feb 18 21:15:33 2016<br>
@@ -11,17 +11,36 @@<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
<br>
-#include "llvm/ProfileData/ProfileCommon.h"<br>
 #include "llvm/ProfileData/InstrProf.h"<br>
+#include "llvm/ProfileData/ProfileCommon.h"<br>
+#include "llvm/ProfileData/SampleProf.h"<br>
<br>
 using namespace llvm;<br>
<br>
+// A set of cutoff values. Each value, when divided by ProfileSummary::Scale<br>
+// (which is 1000000) is a desired percentile of total counts.<br>
+const std::vector<uint32_t> ProfileSummary::DefaultCutoffs(<br>
+    {10000,  /*  1% */<br>
+     100000, /* 10% */<br>
+     200000, 300000, 400000, 500000, 600000, 500000, 600000, 700000, 800000,<br>
+     900000, 950000, 990000, 999000, 999900, 999990, 999999});<br>
+<br>
 void InstrProfSummary::addRecord(const InstrProfRecord &R) {<br>
   addEntryCount(R.Counts[0]);<br>
   for (size_t I = 1, E = R.Counts.size(); I < E; ++I)<br>
     addInternalCount(R.Counts[I]);<br>
 }<br>
<br>
+// To compute the detailed summary, we consider each line containing samples as<br>
+// equivalent to a block with a count in the instrumented profile.<br>
+void SampleProfileSummary::addRecord(const sampleprof::FunctionSamples &FS) {<br>
+  NumFunctions++;<br>
+  if (FS.getHeadSamples() > MaxHeadSamples)<br>
+    MaxHeadSamples = FS.getHeadSamples();<br>
+  for (const auto &I : FS.getBodySamples())<br>
+    addCount(I.second.getSamples());<br>
+}<br>
+<br>
 // The argument to this method is a vector of cutoff percentages and the return<br>
 // value is a vector of (Cutoff, MinCount, NumCounts) triplets.<br>
 void ProfileSummary::computeDetailedSummary() {<br>
<br>
Modified: llvm/trunk/lib/ProfileData/SampleProfReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/SampleProfReader.cpp?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/SampleProfReader.cpp?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ProfileData/SampleProfReader.cpp (original)<br>
+++ llvm/trunk/lib/ProfileData/SampleProfReader.cpp Thu Feb 18 21:15:33 2016<br>
@@ -22,6 +22,7 @@<br>
<br>
 #include "llvm/ProfileData/SampleProfReader.h"<br>
 #include "llvm/ADT/DenseMap.h"<br>
+#include "llvm/ADT/STLExtras.h"<br>
 #include "llvm/ADT/SmallVector.h"<br>
 #include "llvm/Support/Debug.h"<br>
 #include "llvm/Support/ErrorOr.h"<br>
@@ -220,6 +221,8 @@ std::error_code SampleProfileReaderText:<br>
       }<br>
     }<br>
   }<br>
+  if (Result == sampleprof_error::success)<br>
+    computeSummary();<br>
<br>
   return Result;<br>
 }<br>
@@ -400,6 +403,9 @@ std::error_code SampleProfileReaderBinar<br>
   else if (*Version != SPVersion())<br>
     return sampleprof_error::unsupported_version;<br>
<br>
+  if (std::error_code EC = readSummary())<br>
+    return EC;<br>
+<br>
   // Read the name table.<br>
   auto Size = readNumber<uint32_t>();<br>
   if (std::error_code EC = Size.getError())<br>
@@ -415,6 +421,62 @@ std::error_code SampleProfileReaderBinar<br>
   return sampleprof_error::success;<br>
 }<br>
<br>
+std::error_code SampleProfileReaderBinary::readSummaryEntry(<br>
+    std::vector<ProfileSummaryEntry> &Entries) {<br>
+  auto Cutoff = readNumber<uint64_t>();<br>
+  if (std::error_code EC = Cutoff.getError())<br>
+    return EC;<br>
+<br>
+  auto MinBlockCount = readNumber<uint64_t>();<br>
+  if (std::error_code EC = MinBlockCount.getError())<br>
+    return EC;<br>
+<br>
+  auto NumBlocks = readNumber<uint64_t>();<br>
+  if (std::error_code EC = NumBlocks.getError())<br>
+    return EC;<br>
+<br>
+  Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);<br>
+  return sampleprof_error::success;<br>
+}<br>
+<br>
+std::error_code SampleProfileReaderBinary::readSummary() {<br>
+  auto TotalCount = readNumber<uint64_t>();<br>
+  if (std::error_code EC = TotalCount.getError())<br>
+    return EC;<br>
+<br>
+  auto MaxBlockCount = readNumber<uint64_t>();<br>
+  if (std::error_code EC = MaxBlockCount.getError())<br>
+    return EC;<br>
+<br>
+  auto MaxFunctionCount = readNumber<uint64_t>();<br>
+  if (std::error_code EC = MaxFunctionCount.getError())<br>
+    return EC;<br>
+<br>
+  auto NumBlocks = readNumber<uint64_t>();<br>
+  if (std::error_code EC = NumBlocks.getError())<br>
+    return EC;<br>
+<br>
+  auto NumFunctions = readNumber<uint64_t>();<br>
+  if (std::error_code EC = NumFunctions.getError())<br>
+    return EC;<br>
+<br>
+  auto NumSummaryEntries = readNumber<uint64_t>();<br>
+  if (std::error_code EC = NumSummaryEntries.getError())<br>
+    return EC;<br>
+<br>
+  std::vector<ProfileSummaryEntry> Entries;<br>
+  for (unsigned i = 0; i < *NumSummaryEntries; i++) {<br>
+    std::error_code EC = readSummaryEntry(Entries);<br>
+    if (EC != sampleprof_error::success)<br>
+      return EC;<br>
+  }<br>
+  Summary = llvm::make_unique<SampleProfileSummary>(<br>
+      *TotalCount, *MaxBlockCount, *MaxFunctionCount, *NumBlocks, *NumFunctions,<br>
+      Entries);<br>
+<br>
+  return sampleprof_error::success;<br>
+}<br>
+<br>
 bool SampleProfileReaderBinary::hasFormat(const MemoryBuffer &Buffer) {<br>
   const uint8_t *Data =<br>
       reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());<br>
@@ -518,6 +580,7 @@ std::error_code SampleProfileReaderGCC::<br>
     if (std::error_code EC = readOneFunctionProfile(Stack, true, 0))<br>
       return EC;<br>
<br>
+  computeSummary();<br>
   return sampleprof_error::success;<br>
 }<br>
<br>
@@ -725,3 +788,14 @@ SampleProfileReader::create(std::unique_<br>
<br>
   return std::move(Reader);<br>
 }<br>
+<br>
+// For text and GCC file formats, we compute the summary after reading the<br>
+// profile. Binary format has the profile summary in its header.<br>
+void SampleProfileReader::computeSummary() {<br>
+  Summary.reset(new SampleProfileSummary(ProfileSummary::DefaultCutoffs));<br>
+  for (const auto &I : Profiles) {<br>
+    const FunctionSamples &Profile = I.second;<br>
+    Summary->addRecord(Profile);<br>
+  }<br>
+  Summary->computeDetailedSummary();<br>
+}<br>
<br>
Modified: llvm/trunk/lib/ProfileData/SampleProfWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/SampleProfWriter.cpp?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/SampleProfWriter.cpp?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/ProfileData/SampleProfWriter.cpp (original)<br>
+++ llvm/trunk/lib/ProfileData/SampleProfWriter.cpp Thu Feb 18 21:15:33 2016<br>
@@ -120,6 +120,10 @@ std::error_code SampleProfileWriterBinar<br>
   encodeULEB128(SPMagic(), OS);<br>
   encodeULEB128(SPVersion(), OS);<br>
<br>
+  computeSummary(ProfileMap);<br>
+  if (auto EC = writeSummary())<br>
+    return EC;<br>
+<br>
   // Generate the name table for all the functions referenced in the profile.<br>
   for (const auto &I : ProfileMap) {<br>
     addName(I.first());<br>
@@ -132,10 +136,25 @@ std::error_code SampleProfileWriterBinar<br>
     OS << N.first;<br>
     encodeULEB128(0, OS);<br>
   }<br>
-<br>
   return sampleprof_error::success;<br>
 }<br>
<br>
+std::error_code SampleProfileWriterBinary::writeSummary() {<br>
+  auto &OS = *OutputStream;<br>
+  encodeULEB128(Summary->getTotalSamples(), OS);<br>
+  encodeULEB128(Summary->getMaxSamplesPerLine(), OS);<br>
+  encodeULEB128(Summary->getMaxHeadSamples(), OS);<br>
+  encodeULEB128(Summary->getNumLinesWithSamples(), OS);<br>
+  encodeULEB128(Summary->getNumFunctions(), OS);<br>
+  std::vector<ProfileSummaryEntry> &Entries = Summary->getDetailedSummary();<br>
+  encodeULEB128(Entries.size(), OS);<br>
+  for (auto Entry : Entries) {<br>
+    encodeULEB128(Entry.Cutoff, OS);<br>
+    encodeULEB128(Entry.MinCount, OS);<br>
+    encodeULEB128(Entry.NumCounts, OS);<br>
+  }<br>
+  return sampleprof_error::success;<br>
+}<br>
 std::error_code SampleProfileWriterBinary::writeBody(StringRef FName,<br>
                                                      const FunctionSamples &S) {<br>
   auto &OS = *OutputStream;<br>
@@ -238,3 +257,13 @@ SampleProfileWriter::create(std::unique_<br>
<br>
   return std::move(Writer);<br>
 }<br>
+<br>
+void SampleProfileWriter::computeSummary(<br>
+    const StringMap<FunctionSamples> &ProfileMap) {<br>
+  Summary.reset(new SampleProfileSummary(ProfileSummary::DefaultCutoffs));<br>
+  for (const auto &I : ProfileMap) {<br>
+    const FunctionSamples &Profile = I.second;<br>
+    Summary->addRecord(Profile);<br>
+  }<br>
+  Summary->computeDetailedSummary();<br>
+}<br>
<br>
Modified: llvm/trunk/test/Transforms/SampleProfile/Inputs/fnptr.binprof<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SampleProfile/Inputs/fnptr.binprof?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SampleProfile/Inputs/fnptr.binprof?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
Binary files llvm/trunk/test/Transforms/SampleProfile/Inputs/fnptr.binprof (original) and llvm/trunk/test/Transforms/SampleProfile/Inputs/fnptr.binprof Thu Feb 18 21:15:33 2016 differ<br>
<br>
Modified: llvm/trunk/unittests/ProfileData/SampleProfTest.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ProfileData/SampleProfTest.cpp?rev=261304&r1=261303&r2=261304&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ProfileData/SampleProfTest.cpp?rev=261304&r1=261303&r2=261304&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/unittests/ProfileData/SampleProfTest.cpp (original)<br>
+++ llvm/trunk/unittests/ProfileData/SampleProfTest.cpp Thu Feb 18 21:15:33 2016<br>
@@ -55,6 +55,10 @@ struct SampleProfTest : ::testing::Test<br>
     FooSamples.addTotalSamples(7711);<br>
     FooSamples.addHeadSamples(610);<br>
     FooSamples.addBodySamples(1, 0, 610);<br>
+    FooSamples.addBodySamples(2, 0, 600);<br>
+    FooSamples.addBodySamples(4, 0, 60000);<br>
+    FooSamples.addBodySamples(8, 0, 60351);<br>
+    FooSamples.addBodySamples(10, 0, 605);<br>
<br>
     StringRef BarName("_Z3bari");<br>
     FunctionSamples BarSamples;<br>
@@ -88,6 +92,32 @@ struct SampleProfTest : ::testing::Test<br>
     FunctionSamples &ReadBarSamples = ReadProfiles[BarName];<br>
     ASSERT_EQ(20301u, ReadBarSamples.getTotalSamples());<br>
     ASSERT_EQ(1437u, ReadBarSamples.getHeadSamples());<br>
+<br>
+    SampleProfileSummary &Summary = Reader->getSummary();<br>
+    ASSERT_EQ(123603u, Summary.getTotalSamples());<br>
+    ASSERT_EQ(6u, Summary.getNumLinesWithSamples());<br>
+    ASSERT_EQ(2u, Summary.getNumFunctions());<br>
+    ASSERT_EQ(1437u, Summary.getMaxHeadSamples());<br>
+    ASSERT_EQ(60351u, Summary.getMaxSamplesPerLine());<br>
+<br>
+    std::vector<ProfileSummaryEntry> &Details = Summary.getDetailedSummary();<br>
+    uint32_t Cutoff = 800000;<br>
+    auto Predicate = [&Cutoff](const ProfileSummaryEntry &PE) {<br>
+      return PE.Cutoff == Cutoff;<br>
+    };<br>
+    auto EightyPerc = std::find_if(Details.begin(), Details.end(), Predicate);<br>
+    Cutoff = 900000;<br>
+    auto NinetyPerc = std::find_if(Details.begin(), Details.end(), Predicate);<br>
+    Cutoff = 950000;<br>
+    auto NinetyFivePerc =<br>
+        std::find_if(Details.begin(), Details.end(), Predicate);<br>
+    Cutoff = 990000;<br>
+    auto NinetyNinePerc =<br>
+        std::find_if(Details.begin(), Details.end(), Predicate);<br>
+    ASSERT_EQ(60000u, EightyPerc->MinCount);<br>
+    ASSERT_EQ(60000u, NinetyPerc->MinCount);<br>
+    ASSERT_EQ(60000u, NinetyFivePerc->MinCount);<br>
+    ASSERT_EQ(610u, NinetyNinePerc->MinCount);<br>
   }<br>
 };<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div></div></div>
<br>_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
<br></blockquote></div><br></div>
</div></div></blockquote></div><br></div></div></div></div></div></div></div>
</blockquote></div><br></div>