SamplePGO - Reduce memory utilization by 10x.
authorDiego Novillo <dnovillo@google.com>
Fri, 11 Dec 2015 23:21:38 +0000 (23:21 +0000)
committerDiego Novillo <dnovillo@google.com>
Fri, 11 Dec 2015 23:21:38 +0000 (23:21 +0000)
DenseMap is the wrong data structure to use for sample records and call
sites.  The keys are too large, causing massive core memory growth when
reading profiles.

Before this patch, a 21Mb input profile was causing the compiler to grow
to 3Gb in memory.  By switching to std::map, the compiler now grows to
300Mb in memory.

There still are some opportunities for memory footprint reduction. I'll
be looking at those next.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@255389 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ProfileData/SampleProf.h
include/llvm/ProfileData/SampleProfReader.h
lib/Transforms/IPO/SampleProfile.cpp

index a7b22c73548087fe15996d2fe2323553cd4dd992..f62f79064c4e654f11f9f7454625e8bdfcbd08ae 100644 (file)
 #ifndef LLVM_PROFILEDATA_SAMPLEPROF_H_
 #define LLVM_PROFILEDATA_SAMPLEPROF_H_
 
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/raw_ostream.h"
+
+#include <map>
 #include <system_error>
 
 namespace llvm {
@@ -105,57 +106,6 @@ struct CallsiteLocation : public LineLocation {
 
 raw_ostream &operator<<(raw_ostream &OS, const CallsiteLocation &Loc);
 
-} // End namespace sampleprof
-
-template <> struct DenseMapInfo<sampleprof::LineLocation> {
-  typedef DenseMapInfo<uint32_t> OffsetInfo;
-  typedef DenseMapInfo<uint32_t> DiscriminatorInfo;
-  static inline sampleprof::LineLocation getEmptyKey() {
-    return sampleprof::LineLocation(OffsetInfo::getEmptyKey(),
-                                    DiscriminatorInfo::getEmptyKey());
-  }
-  static inline sampleprof::LineLocation getTombstoneKey() {
-    return sampleprof::LineLocation(OffsetInfo::getTombstoneKey(),
-                                    DiscriminatorInfo::getTombstoneKey());
-  }
-  static inline unsigned getHashValue(sampleprof::LineLocation Val) {
-    return DenseMapInfo<std::pair<uint32_t, uint32_t>>::getHashValue(
-        std::pair<uint32_t, uint32_t>(Val.LineOffset, Val.Discriminator));
-  }
-  static inline bool isEqual(sampleprof::LineLocation LHS,
-                             sampleprof::LineLocation RHS) {
-    return LHS.LineOffset == RHS.LineOffset &&
-           LHS.Discriminator == RHS.Discriminator;
-  }
-};
-
-template <> struct DenseMapInfo<sampleprof::CallsiteLocation> {
-  typedef DenseMapInfo<uint32_t> OffsetInfo;
-  typedef DenseMapInfo<uint32_t> DiscriminatorInfo;
-  typedef DenseMapInfo<StringRef> CalleeNameInfo;
-  static inline sampleprof::CallsiteLocation getEmptyKey() {
-    return sampleprof::CallsiteLocation(OffsetInfo::getEmptyKey(),
-                                        DiscriminatorInfo::getEmptyKey(), "");
-  }
-  static inline sampleprof::CallsiteLocation getTombstoneKey() {
-    return sampleprof::CallsiteLocation(OffsetInfo::getTombstoneKey(),
-                                        DiscriminatorInfo::getTombstoneKey(),
-                                        "");
-  }
-  static inline unsigned getHashValue(sampleprof::CallsiteLocation Val) {
-    return DenseMapInfo<std::pair<uint32_t, uint32_t>>::getHashValue(
-        std::pair<uint32_t, uint32_t>(Val.LineOffset, Val.Discriminator));
-  }
-  static inline bool isEqual(sampleprof::CallsiteLocation LHS,
-                             sampleprof::CallsiteLocation RHS) {
-    return LHS.LineOffset == RHS.LineOffset &&
-           LHS.Discriminator == RHS.Discriminator &&
-           LHS.CalleeName.equals(RHS.CalleeName);
-  }
-};
-
-namespace sampleprof {
-
 /// Representation of a single sample record.
 ///
 /// A sample record is represented by a positive integer value, which
@@ -176,9 +126,7 @@ public:
   ///
   /// Sample counts accumulate using saturating arithmetic, to avoid wrapping
   /// around unsigned integers.
-  void addSamples(uint64_t S) {
-    NumSamples = SaturatingAdd(NumSamples, S);
-  }
+  void addSamples(uint64_t S) { NumSamples = SaturatingAdd(NumSamples, S); }
 
   /// Add called function \p F with samples \p S.
   ///
@@ -212,9 +160,9 @@ private:
 
 raw_ostream &operator<<(raw_ostream &OS, const SampleRecord &Sample);
 
-typedef DenseMap<LineLocation, SampleRecord> BodySampleMap;
+typedef std::map<LineLocation, SampleRecord> BodySampleMap;
 class FunctionSamples;
-typedef DenseMap<CallsiteLocation, FunctionSamples> CallsiteSampleMap;
+typedef std::map<CallsiteLocation, FunctionSamples> CallsiteSampleMap;
 
 /// Representation of the samples collected for a function.
 ///
@@ -345,10 +293,10 @@ raw_ostream &operator<<(raw_ostream &OS, const FunctionSamples &FS);
 /// order of LocationT.
 template <class LocationT, class SampleT> class SampleSorter {
 public:
-  typedef detail::DenseMapPair<LocationT, SampleT> SamplesWithLoc;
+  typedef std::pair<const LocationT, SampleT> SamplesWithLoc;
   typedef SmallVector<const SamplesWithLoc *, 20> SamplesWithLocList;
 
-  SampleSorter(const DenseMap<LocationT, SampleT> &Samples) {
+  SampleSorter(const std::map<LocationT, SampleT> &Samples) {
     for (const auto &I : Samples)
       V.push_back(&I);
     std::stable_sort(V.begin(), V.end(),
index 9762813264f491f861e7098e385328a315486a23..6db0fbb0e7abf750fcf09b1f433a4958cf2e6be8 100644 (file)
 #ifndef LLVM_PROFILEDATA_SAMPLEPROFREADER_H
 #define LLVM_PROFILEDATA_SAMPLEPROFREADER_H
 
-#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
index 2ce1fcece41f089005a4fe42e8886f81e0fa10f0..928d92ef9d121cc0451a7eaf28a64c63d16d6ba5 100644 (file)
@@ -223,7 +223,7 @@ public:
   }
 
 private:
-  typedef DenseMap<LineLocation, unsigned> BodySampleCoverageMap;
+  typedef std::map<LineLocation, unsigned> BodySampleCoverageMap;
   typedef DenseMap<const FunctionSamples *, BodySampleCoverageMap>
       FunctionSamplesCoverageMap;