forked from OSchip/llvm-project
[llvm-profdata] Add merge() to InstrProfRecord
Summary: This change refactors two aspects of InstrProfRecord: 1) Add a merge() method to InstrProfRecord (previously InstrProfWriter combineInstrProfRecords()) in order to better encapsulate this functionality and to make the InstrProfRecord and SampleRecord APIs more consistent. 2) Make InstrProfRecord mergeValueProfData() a private method since it is only ever called internally by merge(). Reviewers: dnovillo, bogner, davidxl Subscribers: silvas, vsk, llvm-commits Differential Revision: http://reviews.llvm.org/D14786 llvm-svn: 253695
This commit is contained in:
parent
19ff5602da
commit
a731829788
|
@ -265,9 +265,9 @@ struct InstrProfRecord {
|
|||
inline void addValueData(uint32_t ValueKind, uint32_t Site,
|
||||
InstrProfValueData *VData, uint32_t N,
|
||||
ValueMapType *HashKeys);
|
||||
/// Merge Value Profile data from Src record to this record for ValueKind.
|
||||
inline instrprof_error mergeValueProfData(uint32_t ValueKind,
|
||||
InstrProfRecord &Src);
|
||||
|
||||
/// Merge the counts in \p Other into this one.
|
||||
inline instrprof_error merge(InstrProfRecord &Other);
|
||||
|
||||
/// Used by InstrProfWriter: update the value strings to commoned strings in
|
||||
/// the writer instance.
|
||||
|
@ -317,6 +317,21 @@ private:
|
|||
}
|
||||
return Value;
|
||||
}
|
||||
|
||||
// Merge Value Profile data from Src record to this record for ValueKind.
|
||||
instrprof_error mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src) {
|
||||
uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
|
||||
uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);
|
||||
if (ThisNumValueSites != OtherNumValueSites)
|
||||
return instrprof_error::value_site_count_mismatch;
|
||||
std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
|
||||
getValueSitesForKind(ValueKind);
|
||||
std::vector<InstrProfValueSiteRecord> &OtherSiteRecords =
|
||||
Src.getValueSitesForKind(ValueKind);
|
||||
for (uint32_t I = 0; I < ThisNumValueSites; I++)
|
||||
ThisSiteRecords[I].mergeValueData(OtherSiteRecords[I]);
|
||||
return instrprof_error::success;
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t InstrProfRecord::getNumValueKinds() const {
|
||||
|
@ -382,21 +397,6 @@ void InstrProfRecord::reserveSites(uint32_t ValueKind, uint32_t NumValueSites) {
|
|||
ValueSites.reserve(NumValueSites);
|
||||
}
|
||||
|
||||
instrprof_error InstrProfRecord::mergeValueProfData(uint32_t ValueKind,
|
||||
InstrProfRecord &Src) {
|
||||
uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
|
||||
uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);
|
||||
if (ThisNumValueSites != OtherNumValueSites)
|
||||
return instrprof_error::value_site_count_mismatch;
|
||||
std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
|
||||
getValueSitesForKind(ValueKind);
|
||||
std::vector<InstrProfValueSiteRecord> &OtherSiteRecords =
|
||||
Src.getValueSitesForKind(ValueKind);
|
||||
for (uint32_t I = 0; I < ThisNumValueSites; I++)
|
||||
ThisSiteRecords[I].mergeValueData(OtherSiteRecords[I]);
|
||||
return instrprof_error::success;
|
||||
}
|
||||
|
||||
void InstrProfRecord::updateStrings(InstrProfStringTable *StrTab) {
|
||||
if (!StrTab)
|
||||
return;
|
||||
|
@ -407,6 +407,27 @@ void InstrProfRecord::updateStrings(InstrProfStringTable *StrTab) {
|
|||
VData.Value = (uint64_t)StrTab->insertString((const char *)VData.Value);
|
||||
}
|
||||
|
||||
instrprof_error InstrProfRecord::merge(InstrProfRecord &Other) {
|
||||
// If the number of counters doesn't match we either have bad data
|
||||
// or a hash collision.
|
||||
if (Counts.size() != Other.Counts.size())
|
||||
return instrprof_error::count_mismatch;
|
||||
|
||||
for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {
|
||||
if (Counts[I] + Other.Counts[I] < Counts[I])
|
||||
return instrprof_error::counter_overflow;
|
||||
Counts[I] += Other.Counts[I];
|
||||
}
|
||||
|
||||
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
|
||||
instrprof_error result = mergeValueProfData(Kind, Other);
|
||||
if (result != instrprof_error::success)
|
||||
return result;
|
||||
}
|
||||
|
||||
return instrprof_error::success;
|
||||
}
|
||||
|
||||
inline support::endianness getHostEndianness() {
|
||||
return sys::IsLittleEndianHost ? support::little : support::big;
|
||||
}
|
||||
|
|
|
@ -87,32 +87,6 @@ public:
|
|||
};
|
||||
}
|
||||
|
||||
static std::error_code combineInstrProfRecords(InstrProfRecord &Dest,
|
||||
InstrProfRecord &Source,
|
||||
uint64_t &MaxFunctionCount) {
|
||||
// If the number of counters doesn't match we either have bad data
|
||||
// or a hash collision.
|
||||
if (Dest.Counts.size() != Source.Counts.size())
|
||||
return instrprof_error::count_mismatch;
|
||||
|
||||
for (size_t I = 0, E = Source.Counts.size(); I < E; ++I) {
|
||||
if (Dest.Counts[I] + Source.Counts[I] < Dest.Counts[I])
|
||||
return instrprof_error::counter_overflow;
|
||||
Dest.Counts[I] += Source.Counts[I];
|
||||
}
|
||||
|
||||
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
|
||||
if (std::error_code EC = Dest.mergeValueProfData(Kind, Source))
|
||||
return EC;
|
||||
}
|
||||
|
||||
// We keep track of the max function count as we go for simplicity.
|
||||
if (Dest.Counts[0] > MaxFunctionCount)
|
||||
MaxFunctionCount = Dest.Counts[0];
|
||||
|
||||
return instrprof_error::success;
|
||||
}
|
||||
|
||||
// Internal interface for testing purpose only.
|
||||
void InstrProfWriter::setValueProfDataEndianness(
|
||||
support::endianness Endianness) {
|
||||
|
@ -127,19 +101,27 @@ std::error_code InstrProfWriter::addRecord(InstrProfRecord &&I) {
|
|||
updateStringTableReferences(I);
|
||||
auto &ProfileDataMap = FunctionData[I.Name];
|
||||
|
||||
auto Where = ProfileDataMap.find(I.Hash);
|
||||
if (Where == ProfileDataMap.end()) {
|
||||
bool NewFunc;
|
||||
ProfilingData::iterator Where;
|
||||
std::tie(Where, NewFunc) =
|
||||
ProfileDataMap.insert(std::make_pair(I.Hash, InstrProfRecord()));
|
||||
InstrProfRecord &Dest = Where->second;
|
||||
if (NewFunc) {
|
||||
// We've never seen a function with this name and hash, add it.
|
||||
ProfileDataMap[I.Hash] = I;
|
||||
|
||||
// We keep track of the max function count as we go for simplicity.
|
||||
if (I.Counts[0] > MaxFunctionCount)
|
||||
MaxFunctionCount = I.Counts[0];
|
||||
return instrprof_error::success;
|
||||
Dest = std::move(I);
|
||||
} else {
|
||||
// We're updating a function we've seen before.
|
||||
instrprof_error MergeResult = Dest.merge(I);
|
||||
if (MergeResult != instrprof_error::success) {
|
||||
return MergeResult;
|
||||
}
|
||||
}
|
||||
|
||||
// We're updating a function we've seen before.
|
||||
return combineInstrProfRecords(Where->second, I, MaxFunctionCount);
|
||||
// We keep track of the max function count as we go for simplicity.
|
||||
if (Dest.Counts[0] > MaxFunctionCount)
|
||||
MaxFunctionCount = Dest.Counts[0];
|
||||
|
||||
return instrprof_error::success;
|
||||
}
|
||||
|
||||
std::pair<uint64_t, uint64_t> InstrProfWriter::writeImpl(raw_ostream &OS) {
|
||||
|
|
Loading…
Reference in New Issue