Skip to content

Commit 98cce00

Browse files
committed
llvm-profdata: Reduce memory usage by using Error callback rather than member
Reduces llvm-profdata memory usage on a large profile from 7.8GB to 5.1GB. The ProfData API now supports reporting all the errors/warnings rather than only the first, though llvm-profdata ignores everything after the first for now to preserve existing behavior. (if there's a desire for other behavior, happy to implement that - but might be as well left for a separate patch) Reviewers: davidxl Differential Revision: https://reviews.llvm.org/D35149 llvm-svn: 307516
1 parent 625cc0e commit 98cce00

File tree

7 files changed

+164
-149
lines changed

7 files changed

+164
-149
lines changed

llvm/include/llvm/ProfileData/InstrProf.h

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -581,16 +581,15 @@ struct InstrProfValueSiteRecord {
581581

582582
/// Merge data from another InstrProfValueSiteRecord
583583
/// Optionally scale merged counts by \p Weight.
584-
void merge(SoftInstrProfErrors &SIPE, InstrProfValueSiteRecord &Input,
585-
uint64_t Weight = 1);
584+
void merge(InstrProfValueSiteRecord &Input, uint64_t Weight,
585+
function_ref<void(instrprof_error)> Warn);
586586
/// Scale up value profile data counts.
587-
void scale(SoftInstrProfErrors &SIPE, uint64_t Weight);
587+
void scale(uint64_t Weight, function_ref<void(instrprof_error)> Warn);
588588
};
589589

590590
/// Profiling information for a single function.
591591
struct InstrProfRecord {
592592
std::vector<uint64_t> Counts;
593-
SoftInstrProfErrors SIPE;
594593

595594
InstrProfRecord() = default;
596595
InstrProfRecord(std::vector<uint64_t> Counts) : Counts(std::move(Counts)) {}
@@ -653,11 +652,12 @@ struct InstrProfRecord {
653652

654653
/// Merge the counts in \p Other into this one.
655654
/// Optionally scale merged counts by \p Weight.
656-
void merge(InstrProfRecord &Other, uint64_t Weight = 1);
655+
void merge(InstrProfRecord &Other, uint64_t Weight,
656+
function_ref<void(instrprof_error)> Warn);
657657

658658
/// Scale up profile counts (including value profile data) by
659659
/// \p Weight.
660-
void scale(uint64_t Weight);
660+
void scale(uint64_t Weight, function_ref<void(instrprof_error)> Warn);
661661

662662
/// Sort value profile data (per site) by count.
663663
void sortValueData() {
@@ -675,9 +675,6 @@ struct InstrProfRecord {
675675
/// Clear value data entries
676676
void clearValueData() { ValueData = nullptr; }
677677

678-
/// Get the error contained within the record's soft error counter.
679-
Error takeError() { return SIPE.takeError(); }
680-
681678
private:
682679
struct ValueProfData {
683680
std::vector<InstrProfValueSiteRecord> IndirectCallSites;
@@ -729,11 +726,13 @@ struct InstrProfRecord {
729726

730727
// Merge Value Profile data from Src record to this record for ValueKind.
731728
// Scale merged value counts by \p Weight.
732-
void mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src,
733-
uint64_t Weight);
729+
void mergeValueProfData(uint32_t ValkeKind, InstrProfRecord &Src,
730+
uint64_t Weight,
731+
function_ref<void(instrprof_error)> Warn);
734732

735733
// Scale up value profile data count.
736-
void scaleValueProfData(uint32_t ValueKind, uint64_t Weight);
734+
void scaleValueProfData(uint32_t ValueKind, uint64_t Weight,
735+
function_ref<void(instrprof_error)> Warn);
737736
};
738737

739738
struct NamedInstrProfRecord : InstrProfRecord {

llvm/include/llvm/ProfileData/InstrProfWriter.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,15 @@ class InstrProfWriter {
5151
/// Add function counts for the given function. If there are already counts
5252
/// for this function and the hash and number of counts match, each counter is
5353
/// summed. Optionally scale counts by \p Weight.
54-
Error addRecord(NamedInstrProfRecord &&I, uint64_t Weight = 1);
54+
void addRecord(NamedInstrProfRecord &&I, uint64_t Weight,
55+
function_ref<void(Error)> Warn);
56+
void addRecord(NamedInstrProfRecord &&I, function_ref<void(Error)> Warn) {
57+
addRecord(std::move(I), 1, Warn);
58+
}
5559

5660
/// Merge existing function counts from the given writer.
57-
Error mergeRecordsFromWriter(InstrProfWriter &&IPW);
61+
void mergeRecordsFromWriter(InstrProfWriter &&IPW,
62+
function_ref<void(Error)> Warn);
5863

5964
/// Write the profile to \c OS
6065
void write(raw_fd_ostream &OS);
@@ -87,8 +92,8 @@ class InstrProfWriter {
8792
void setOutputSparse(bool Sparse);
8893

8994
private:
90-
Error addRecord(StringRef Name, uint64_t Hash, InstrProfRecord &&I,
91-
uint64_t Weight = 1);
95+
void addRecord(StringRef Name, uint64_t Hash, InstrProfRecord &&I,
96+
uint64_t Weight, function_ref<void(Error)> Warn);
9297
bool shouldEncodeData(const ProfilingData &PD);
9398
void writeImpl(ProfOStream &OS);
9499
};

llvm/lib/ProfileData/InstrProf.cpp

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -460,9 +460,9 @@ Error readPGOFuncNameStrings(StringRef NameStrings, InstrProfSymtab &Symtab) {
460460
return Error::success();
461461
}
462462

463-
void InstrProfValueSiteRecord::merge(SoftInstrProfErrors &SIPE,
464-
InstrProfValueSiteRecord &Input,
465-
uint64_t Weight) {
463+
void InstrProfValueSiteRecord::merge(InstrProfValueSiteRecord &Input,
464+
uint64_t Weight,
465+
function_ref<void(instrprof_error)> Warn) {
466466
this->sortByTargetValues();
467467
Input.sortByTargetValues();
468468
auto I = ValueData.begin();
@@ -475,33 +475,33 @@ void InstrProfValueSiteRecord::merge(SoftInstrProfErrors &SIPE,
475475
bool Overflowed;
476476
I->Count = SaturatingMultiplyAdd(J->Count, Weight, I->Count, &Overflowed);
477477
if (Overflowed)
478-
SIPE.addError(instrprof_error::counter_overflow);
478+
Warn(instrprof_error::counter_overflow);
479479
++I;
480480
continue;
481481
}
482482
ValueData.insert(I, *J);
483483
}
484484
}
485485

486-
void InstrProfValueSiteRecord::scale(SoftInstrProfErrors &SIPE,
487-
uint64_t Weight) {
486+
void InstrProfValueSiteRecord::scale(uint64_t Weight,
487+
function_ref<void(instrprof_error)> Warn) {
488488
for (auto I = ValueData.begin(), IE = ValueData.end(); I != IE; ++I) {
489489
bool Overflowed;
490490
I->Count = SaturatingMultiply(I->Count, Weight, &Overflowed);
491491
if (Overflowed)
492-
SIPE.addError(instrprof_error::counter_overflow);
492+
Warn(instrprof_error::counter_overflow);
493493
}
494494
}
495495

496496
// Merge Value Profile data from Src record to this record for ValueKind.
497497
// Scale merged value counts by \p Weight.
498-
void InstrProfRecord::mergeValueProfData(uint32_t ValueKind,
499-
InstrProfRecord &Src,
500-
uint64_t Weight) {
498+
void InstrProfRecord::mergeValueProfData(
499+
uint32_t ValueKind, InstrProfRecord &Src, uint64_t Weight,
500+
function_ref<void(instrprof_error)> Warn) {
501501
uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
502502
uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);
503503
if (ThisNumValueSites != OtherNumValueSites) {
504-
SIPE.addError(instrprof_error::value_site_count_mismatch);
504+
Warn(instrprof_error::value_site_count_mismatch);
505505
return;
506506
}
507507
if (!ThisNumValueSites)
@@ -511,14 +511,15 @@ void InstrProfRecord::mergeValueProfData(uint32_t ValueKind,
511511
MutableArrayRef<InstrProfValueSiteRecord> OtherSiteRecords =
512512
Src.getValueSitesForKind(ValueKind);
513513
for (uint32_t I = 0; I < ThisNumValueSites; I++)
514-
ThisSiteRecords[I].merge(SIPE, OtherSiteRecords[I], Weight);
514+
ThisSiteRecords[I].merge(OtherSiteRecords[I], Weight, Warn);
515515
}
516516

517-
void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight) {
517+
void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight,
518+
function_ref<void(instrprof_error)> Warn) {
518519
// If the number of counters doesn't match we either have bad data
519520
// or a hash collision.
520521
if (Counts.size() != Other.Counts.size()) {
521-
SIPE.addError(instrprof_error::count_mismatch);
522+
Warn(instrprof_error::count_mismatch);
522523
return;
523524
}
524525

@@ -527,27 +528,30 @@ void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight) {
527528
Counts[I] =
528529
SaturatingMultiplyAdd(Other.Counts[I], Weight, Counts[I], &Overflowed);
529530
if (Overflowed)
530-
SIPE.addError(instrprof_error::counter_overflow);
531+
Warn(instrprof_error::counter_overflow);
531532
}
532533

533534
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
534-
mergeValueProfData(Kind, Other, Weight);
535+
mergeValueProfData(Kind, Other, Weight, Warn);
535536
}
536537

537-
void InstrProfRecord::scaleValueProfData(uint32_t ValueKind, uint64_t Weight) {
538+
void InstrProfRecord::scaleValueProfData(
539+
uint32_t ValueKind, uint64_t Weight,
540+
function_ref<void(instrprof_error)> Warn) {
538541
for (auto &R : getValueSitesForKind(ValueKind))
539-
R.scale(SIPE, Weight);
542+
R.scale(Weight, Warn);
540543
}
541544

542-
void InstrProfRecord::scale(uint64_t Weight) {
545+
void InstrProfRecord::scale(uint64_t Weight,
546+
function_ref<void(instrprof_error)> Warn) {
543547
for (auto &Count : this->Counts) {
544548
bool Overflowed;
545549
Count = SaturatingMultiply(Count, Weight, &Overflowed);
546550
if (Overflowed)
547-
SIPE.addError(instrprof_error::counter_overflow);
551+
Warn(instrprof_error::counter_overflow);
548552
}
549553
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
550-
scaleValueProfData(Kind, Weight);
554+
scaleValueProfData(Kind, Weight, Warn);
551555
}
552556

553557
// Map indirect call target name hash to name string.

llvm/lib/ProfileData/InstrProfWriter.cpp

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,14 +176,16 @@ void InstrProfWriter::setOutputSparse(bool Sparse) {
176176
this->Sparse = Sparse;
177177
}
178178

179-
Error InstrProfWriter::addRecord(NamedInstrProfRecord &&I, uint64_t Weight) {
179+
void InstrProfWriter::addRecord(NamedInstrProfRecord &&I, uint64_t Weight,
180+
function_ref<void(Error)> Warn) {
180181
auto Name = I.Name;
181182
auto Hash = I.Hash;
182-
return addRecord(Name, Hash, std::move(I), Weight);
183+
addRecord(Name, Hash, std::move(I), Weight, Warn);
183184
}
184185

185-
Error InstrProfWriter::addRecord(StringRef Name, uint64_t Hash,
186-
InstrProfRecord &&I, uint64_t Weight) {
186+
void InstrProfWriter::addRecord(StringRef Name, uint64_t Hash,
187+
InstrProfRecord &&I, uint64_t Weight,
188+
function_ref<void(Error)> Warn) {
187189
auto &ProfileDataMap = FunctionData[Name];
188190

189191
bool NewFunc;
@@ -192,27 +194,28 @@ Error InstrProfWriter::addRecord(StringRef Name, uint64_t Hash,
192194
ProfileDataMap.insert(std::make_pair(Hash, InstrProfRecord()));
193195
InstrProfRecord &Dest = Where->second;
194196

197+
auto MapWarn = [&](instrprof_error E) {
198+
Warn(make_error<InstrProfError>(E));
199+
};
200+
195201
if (NewFunc) {
196202
// We've never seen a function with this name and hash, add it.
197203
Dest = std::move(I);
198204
if (Weight > 1)
199-
Dest.scale(Weight);
205+
Dest.scale(Weight, MapWarn);
200206
} else {
201207
// We're updating a function we've seen before.
202-
Dest.merge(I, Weight);
208+
Dest.merge(I, Weight, MapWarn);
203209
}
204210

205211
Dest.sortValueData();
206-
207-
return Dest.takeError();
208212
}
209213

210-
Error InstrProfWriter::mergeRecordsFromWriter(InstrProfWriter &&IPW) {
214+
void InstrProfWriter::mergeRecordsFromWriter(InstrProfWriter &&IPW,
215+
function_ref<void(Error)> Warn) {
211216
for (auto &I : IPW.FunctionData)
212217
for (auto &Func : I.getValue())
213-
if (Error E = addRecord(I.getKey(), Func.first, std::move(Func.second)))
214-
return E;
215-
return Error::success();
218+
addRecord(I.getKey(), Func.first, std::move(Func.second), 1, Warn);
216219
}
217220

218221
bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) {

llvm/tools/llvm-profdata/llvm-profdata.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,23 +159,36 @@ static void loadInput(const WeightedFile &Input, WriterContext *WC) {
159159

160160
for (auto &I : *Reader) {
161161
const StringRef FuncName = I.Name;
162-
if (Error E = WC->Writer.addRecord(std::move(I), Input.Weight)) {
162+
bool Reported = false;
163+
WC->Writer.addRecord(std::move(I), Input.Weight, [&](Error E) {
164+
if (Reported) {
165+
consumeError(std::move(E));
166+
return;
167+
}
168+
Reported = true;
163169
// Only show hint the first time an error occurs.
164170
instrprof_error IPE = InstrProfError::take(std::move(E));
165171
std::unique_lock<std::mutex> ErrGuard{WC->ErrLock};
166172
bool firstTime = WC->WriterErrorCodes.insert(IPE).second;
167173
handleMergeWriterError(make_error<InstrProfError>(IPE), Input.Filename,
168174
FuncName, firstTime);
169-
}
175+
});
170176
}
171177
if (Reader->hasError())
172178
WC->Err = Reader->getError();
173179
}
174180

175181
/// Merge the \p Src writer context into \p Dst.
176182
static void mergeWriterContexts(WriterContext *Dst, WriterContext *Src) {
177-
if (Error E = Dst->Writer.mergeRecordsFromWriter(std::move(Src->Writer)))
183+
bool Reported = false;
184+
Dst->Writer.mergeRecordsFromWriter(std::move(Src->Writer), [&](Error E) {
185+
if (Reported) {
186+
consumeError(std::move(E));
187+
return;
188+
}
189+
Reported = true;
178190
Dst->Err = std::move(E);
191+
});
179192
}
180193

181194
static void mergeInstrProfile(const WeightedFileVector &Inputs,

0 commit comments

Comments
 (0)