From: Diego Novillo Date: Fri, 11 Dec 2015 23:21:38 +0000 (+0000) Subject: SamplePGO - Reduce memory utilization by 10x. X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=31b250abad3b61969ceb4000bf735339b1cc54dc;p=oota-llvm.git SamplePGO - Reduce memory utilization by 10x. 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 --- diff --git a/include/llvm/ProfileData/SampleProf.h b/include/llvm/ProfileData/SampleProf.h index a7b22c73548..f62f79064c4 100644 --- a/include/llvm/ProfileData/SampleProf.h +++ b/include/llvm/ProfileData/SampleProf.h @@ -15,12 +15,13 @@ #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 #include 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 { - typedef DenseMapInfo OffsetInfo; - typedef DenseMapInfo 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>::getHashValue( - std::pair(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 { - typedef DenseMapInfo OffsetInfo; - typedef DenseMapInfo DiscriminatorInfo; - typedef DenseMapInfo 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>::getHashValue( - std::pair(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 BodySampleMap; +typedef std::map BodySampleMap; class FunctionSamples; -typedef DenseMap CallsiteSampleMap; +typedef std::map 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 SampleSorter { public: - typedef detail::DenseMapPair SamplesWithLoc; + typedef std::pair SamplesWithLoc; typedef SmallVector SamplesWithLocList; - SampleSorter(const DenseMap &Samples) { + SampleSorter(const std::map &Samples) { for (const auto &I : Samples) V.push_back(&I); std::stable_sort(V.begin(), V.end(), diff --git a/include/llvm/ProfileData/SampleProfReader.h b/include/llvm/ProfileData/SampleProfReader.h index 9762813264f..6db0fbb0e7a 100644 --- a/include/llvm/ProfileData/SampleProfReader.h +++ b/include/llvm/ProfileData/SampleProfReader.h @@ -184,7 +184,6 @@ #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" diff --git a/lib/Transforms/IPO/SampleProfile.cpp b/lib/Transforms/IPO/SampleProfile.cpp index 2ce1fcece41..928d92ef9d1 100644 --- a/lib/Transforms/IPO/SampleProfile.cpp +++ b/lib/Transforms/IPO/SampleProfile.cpp @@ -223,7 +223,7 @@ public: } private: - typedef DenseMap BodySampleCoverageMap; + typedef std::map BodySampleCoverageMap; typedef DenseMap FunctionSamplesCoverageMap;