Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit e0a7f28

Browse files
committed
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@253695 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent c9180bf commit e0a7f28

File tree

2 files changed

+57
-54
lines changed

2 files changed

+57
-54
lines changed

include/llvm/ProfileData/InstrProf.h

Lines changed: 39 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,9 @@ struct InstrProfRecord {
265265
inline void addValueData(uint32_t ValueKind, uint32_t Site,
266266
InstrProfValueData *VData, uint32_t N,
267267
ValueMapType *HashKeys);
268-
/// Merge Value Profile data from Src record to this record for ValueKind.
269-
inline instrprof_error mergeValueProfData(uint32_t ValueKind,
270-
InstrProfRecord &Src);
268+
269+
/// Merge the counts in \p Other into this one.
270+
inline instrprof_error merge(InstrProfRecord &Other);
271271

272272
/// Used by InstrProfWriter: update the value strings to commoned strings in
273273
/// the writer instance.
@@ -317,6 +317,21 @@ struct InstrProfRecord {
317317
}
318318
return Value;
319319
}
320+
321+
// Merge Value Profile data from Src record to this record for ValueKind.
322+
instrprof_error mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src) {
323+
uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
324+
uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);
325+
if (ThisNumValueSites != OtherNumValueSites)
326+
return instrprof_error::value_site_count_mismatch;
327+
std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
328+
getValueSitesForKind(ValueKind);
329+
std::vector<InstrProfValueSiteRecord> &OtherSiteRecords =
330+
Src.getValueSitesForKind(ValueKind);
331+
for (uint32_t I = 0; I < ThisNumValueSites; I++)
332+
ThisSiteRecords[I].mergeValueData(OtherSiteRecords[I]);
333+
return instrprof_error::success;
334+
}
320335
};
321336

322337
uint32_t InstrProfRecord::getNumValueKinds() const {
@@ -382,21 +397,6 @@ void InstrProfRecord::reserveSites(uint32_t ValueKind, uint32_t NumValueSites) {
382397
ValueSites.reserve(NumValueSites);
383398
}
384399

385-
instrprof_error InstrProfRecord::mergeValueProfData(uint32_t ValueKind,
386-
InstrProfRecord &Src) {
387-
uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
388-
uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);
389-
if (ThisNumValueSites != OtherNumValueSites)
390-
return instrprof_error::value_site_count_mismatch;
391-
std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
392-
getValueSitesForKind(ValueKind);
393-
std::vector<InstrProfValueSiteRecord> &OtherSiteRecords =
394-
Src.getValueSitesForKind(ValueKind);
395-
for (uint32_t I = 0; I < ThisNumValueSites; I++)
396-
ThisSiteRecords[I].mergeValueData(OtherSiteRecords[I]);
397-
return instrprof_error::success;
398-
}
399-
400400
void InstrProfRecord::updateStrings(InstrProfStringTable *StrTab) {
401401
if (!StrTab)
402402
return;
@@ -407,6 +407,27 @@ void InstrProfRecord::updateStrings(InstrProfStringTable *StrTab) {
407407
VData.Value = (uint64_t)StrTab->insertString((const char *)VData.Value);
408408
}
409409

410+
instrprof_error InstrProfRecord::merge(InstrProfRecord &Other) {
411+
// If the number of counters doesn't match we either have bad data
412+
// or a hash collision.
413+
if (Counts.size() != Other.Counts.size())
414+
return instrprof_error::count_mismatch;
415+
416+
for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {
417+
if (Counts[I] + Other.Counts[I] < Counts[I])
418+
return instrprof_error::counter_overflow;
419+
Counts[I] += Other.Counts[I];
420+
}
421+
422+
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
423+
instrprof_error result = mergeValueProfData(Kind, Other);
424+
if (result != instrprof_error::success)
425+
return result;
426+
}
427+
428+
return instrprof_error::success;
429+
}
430+
410431
inline support::endianness getHostEndianness() {
411432
return sys::IsLittleEndianHost ? support::little : support::big;
412433
}

lib/ProfileData/InstrProfWriter.cpp

Lines changed: 18 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -87,32 +87,6 @@ class InstrProfRecordTrait {
8787
};
8888
}
8989

90-
static std::error_code combineInstrProfRecords(InstrProfRecord &Dest,
91-
InstrProfRecord &Source,
92-
uint64_t &MaxFunctionCount) {
93-
// If the number of counters doesn't match we either have bad data
94-
// or a hash collision.
95-
if (Dest.Counts.size() != Source.Counts.size())
96-
return instrprof_error::count_mismatch;
97-
98-
for (size_t I = 0, E = Source.Counts.size(); I < E; ++I) {
99-
if (Dest.Counts[I] + Source.Counts[I] < Dest.Counts[I])
100-
return instrprof_error::counter_overflow;
101-
Dest.Counts[I] += Source.Counts[I];
102-
}
103-
104-
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
105-
if (std::error_code EC = Dest.mergeValueProfData(Kind, Source))
106-
return EC;
107-
}
108-
109-
// We keep track of the max function count as we go for simplicity.
110-
if (Dest.Counts[0] > MaxFunctionCount)
111-
MaxFunctionCount = Dest.Counts[0];
112-
113-
return instrprof_error::success;
114-
}
115-
11690
// Internal interface for testing purpose only.
11791
void InstrProfWriter::setValueProfDataEndianness(
11892
support::endianness Endianness) {
@@ -127,19 +101,27 @@ std::error_code InstrProfWriter::addRecord(InstrProfRecord &&I) {
127101
updateStringTableReferences(I);
128102
auto &ProfileDataMap = FunctionData[I.Name];
129103

130-
auto Where = ProfileDataMap.find(I.Hash);
131-
if (Where == ProfileDataMap.end()) {
104+
bool NewFunc;
105+
ProfilingData::iterator Where;
106+
std::tie(Where, NewFunc) =
107+
ProfileDataMap.insert(std::make_pair(I.Hash, InstrProfRecord()));
108+
InstrProfRecord &Dest = Where->second;
109+
if (NewFunc) {
132110
// We've never seen a function with this name and hash, add it.
133-
ProfileDataMap[I.Hash] = I;
134-
135-
// We keep track of the max function count as we go for simplicity.
136-
if (I.Counts[0] > MaxFunctionCount)
137-
MaxFunctionCount = I.Counts[0];
138-
return instrprof_error::success;
111+
Dest = std::move(I);
112+
} else {
113+
// We're updating a function we've seen before.
114+
instrprof_error MergeResult = Dest.merge(I);
115+
if (MergeResult != instrprof_error::success) {
116+
return MergeResult;
117+
}
139118
}
140119

141-
// We're updating a function we've seen before.
142-
return combineInstrProfRecords(Where->second, I, MaxFunctionCount);
120+
// We keep track of the max function count as we go for simplicity.
121+
if (Dest.Counts[0] > MaxFunctionCount)
122+
MaxFunctionCount = Dest.Counts[0];
123+
124+
return instrprof_error::success;
143125
}
144126

145127
std::pair<uint64_t, uint64_t> InstrProfWriter::writeImpl(raw_ostream &OS) {

0 commit comments

Comments
 (0)