[llvm] r306631 - llvm-profdata: Indirect infrequently used fields to reduce memory usage
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 28 19:51:58 PDT 2017
Author: dblaikie
Date: Wed Jun 28 19:51:58 2017
New Revision: 306631
URL: http://llvm.org/viewvc/llvm-project?rev=306631&view=rev
Log:
llvm-profdata: Indirect infrequently used fields to reduce memory usage
Examining a large profile example, it seems relatively few records have
non-empty IndirectCall and MemOP data, so indirecting these through a
unique_ptr (non-null only when they are non-empty) Reduces memory usage
on this particular example from 14GB to 10GB according to valgrind's
massif.
I suspect it'd still be worth moving InstrProfWriter to its own data
structure that had Counts and the indirected IndirectCall+MemOP, and did
not include the Name, Hash, or Error fields. This would reduce the size
of this dominant data structure by half of this new, lower amount.
(Name(2), Hash(1), Error(1) ~= Counts(vector, 3), ValueProfData
(unique_ptr, 1))
-> From code review feedback, might actually refactor InstrProfRecord
itself to have a sub-struct with all the counts, and use that from
InstrProfWriter, rather than InstrProfWriter owning its own data
structure for this.
Reviewers: davidxl
Differential Revision: https://reviews.llvm.org/D34694
Modified:
llvm/trunk/include/llvm/ProfileData/InstrProf.h
llvm/trunk/lib/ProfileData/InstrProf.cpp
Modified: llvm/trunk/include/llvm/ProfileData/InstrProf.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ProfileData/InstrProf.h?rev=306631&r1=306630&r2=306631&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ProfileData/InstrProf.h (original)
+++ llvm/trunk/include/llvm/ProfileData/InstrProf.h Wed Jun 28 19:51:58 2017
@@ -598,6 +598,28 @@ struct InstrProfRecord {
InstrProfRecord() = default;
InstrProfRecord(StringRef Name, uint64_t Hash, std::vector<uint64_t> Counts)
: Name(Name), Hash(Hash), Counts(std::move(Counts)) {}
+ InstrProfRecord(InstrProfRecord &&) = default;
+ InstrProfRecord(const InstrProfRecord &RHS)
+ : Name(RHS.Name), Hash(RHS.Hash), Counts(RHS.Counts), SIPE(RHS.SIPE),
+ ValueData(RHS.ValueData
+ ? llvm::make_unique<ValueProfData>(*RHS.ValueData)
+ : nullptr) {}
+ InstrProfRecord &operator=(InstrProfRecord &&) = default;
+ InstrProfRecord &operator=(const InstrProfRecord &RHS) {
+ Name = RHS.Name;
+ Hash = RHS.Hash;
+ Counts = RHS.Counts;
+ SIPE = RHS.SIPE;
+ if (!RHS.ValueData) {
+ ValueData = nullptr;
+ return *this;
+ }
+ if (!ValueData)
+ ValueData = llvm::make_unique<ValueProfData>(*RHS.ValueData);
+ else
+ *ValueData = *RHS.ValueData;
+ return *this;
+ }
using ValueMapType = std::vector<std::pair<uint64_t, uint64_t>>;
@@ -647,12 +669,9 @@ struct InstrProfRecord {
/// Sort value profile data (per site) by count.
void sortValueData() {
- for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
- std::vector<InstrProfValueSiteRecord> &SiteRecords =
- getValueSitesForKind(Kind);
- for (auto &SR : SiteRecords)
+ for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
+ for (auto &SR : getValueSitesForKind(Kind))
SR.sortByCount();
- }
}
/// Clear value data entries and edge counters.
@@ -662,36 +681,54 @@ struct InstrProfRecord {
}
/// Clear value data entries
- void clearValueData() {
- for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
- getValueSitesForKind(Kind).clear();
- }
+ void clearValueData() { ValueData = nullptr; }
/// Get the error contained within the record's soft error counter.
Error takeError() { return SIPE.takeError(); }
private:
- std::vector<InstrProfValueSiteRecord> IndirectCallSites;
- std::vector<InstrProfValueSiteRecord> MemOPSizes;
+ struct ValueProfData {
+ std::vector<InstrProfValueSiteRecord> IndirectCallSites;
+ std::vector<InstrProfValueSiteRecord> MemOPSizes;
+ };
+ std::unique_ptr<ValueProfData> ValueData;
- const std::vector<InstrProfValueSiteRecord> &
+ MutableArrayRef<InstrProfValueSiteRecord>
+ getValueSitesForKind(uint32_t ValueKind) {
+ // Cast to /add/ const (should be an implicit_cast, ideally, if that's ever
+ // implemented in LLVM) to call the const overload of this function, then
+ // cast away the constness from the result.
+ auto AR = const_cast<const InstrProfRecord *>(this)->getValueSitesForKind(
+ ValueKind);
+ return makeMutableArrayRef(
+ const_cast<InstrProfValueSiteRecord *>(AR.data()), AR.size());
+ }
+ ArrayRef<InstrProfValueSiteRecord>
getValueSitesForKind(uint32_t ValueKind) const {
+ if (!ValueData)
+ return None;
switch (ValueKind) {
case IPVK_IndirectCallTarget:
- return IndirectCallSites;
+ return ValueData->IndirectCallSites;
case IPVK_MemOPSize:
- return MemOPSizes;
+ return ValueData->MemOPSizes;
default:
llvm_unreachable("Unknown value kind!");
}
- return IndirectCallSites;
}
std::vector<InstrProfValueSiteRecord> &
- getValueSitesForKind(uint32_t ValueKind) {
- return const_cast<std::vector<InstrProfValueSiteRecord> &>(
- const_cast<const InstrProfRecord *>(this)
- ->getValueSitesForKind(ValueKind));
+ getOrCreateValueSitesForKind(uint32_t ValueKind) {
+ if (!ValueData)
+ ValueData = llvm::make_unique<ValueProfData>();
+ switch (ValueKind) {
+ case IPVK_IndirectCallTarget:
+ return ValueData->IndirectCallSites;
+ case IPVK_MemOPSize:
+ return ValueData->MemOPSizes;
+ default:
+ llvm_unreachable("Unknown value kind!");
+ }
}
// Map indirect call target name hash to name string.
@@ -765,9 +802,9 @@ uint64_t InstrProfRecord::getValueForSit
}
void InstrProfRecord::reserveSites(uint32_t ValueKind, uint32_t NumValueSites) {
- std::vector<InstrProfValueSiteRecord> &ValueSites =
- getValueSitesForKind(ValueKind);
- ValueSites.reserve(NumValueSites);
+ if (!NumValueSites)
+ return;
+ getOrCreateValueSitesForKind(ValueKind).reserve(NumValueSites);
}
inline support::endianness getHostEndianness() {
Modified: llvm/trunk/lib/ProfileData/InstrProf.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ProfileData/InstrProf.cpp?rev=306631&r1=306630&r2=306631&view=diff
==============================================================================
--- llvm/trunk/lib/ProfileData/InstrProf.cpp (original)
+++ llvm/trunk/lib/ProfileData/InstrProf.cpp Wed Jun 28 19:51:58 2017
@@ -504,9 +504,11 @@ void InstrProfRecord::mergeValueProfData
SIPE.addError(instrprof_error::value_site_count_mismatch);
return;
}
+ if (!ThisNumValueSites)
+ return;
std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
- getValueSitesForKind(ValueKind);
- std::vector<InstrProfValueSiteRecord> &OtherSiteRecords =
+ getOrCreateValueSitesForKind(ValueKind);
+ MutableArrayRef<InstrProfValueSiteRecord> OtherSiteRecords =
Src.getValueSitesForKind(ValueKind);
for (uint32_t I = 0; I < ThisNumValueSites; I++)
ThisSiteRecords[I].merge(SIPE, OtherSiteRecords[I], Weight);
@@ -533,11 +535,8 @@ void InstrProfRecord::merge(InstrProfRec
}
void InstrProfRecord::scaleValueProfData(uint32_t ValueKind, uint64_t Weight) {
- uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
- std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
- getValueSitesForKind(ValueKind);
- for (uint32_t I = 0; I < ThisNumValueSites; I++)
- ThisSiteRecords[I].scale(SIPE, Weight);
+ for (auto &R : getValueSitesForKind(ValueKind))
+ R.scale(SIPE, Weight);
}
void InstrProfRecord::scale(uint64_t Weight) {
@@ -583,7 +582,7 @@ void InstrProfRecord::addValueData(uint3
VData[I].Value = remapValue(VData[I].Value, ValueKind, ValueMap);
}
std::vector<InstrProfValueSiteRecord> &ValueSites =
- getValueSitesForKind(ValueKind);
+ getOrCreateValueSitesForKind(ValueKind);
if (N == 0)
ValueSites.emplace_back();
else
More information about the llvm-commits
mailing list