llvm.org GIT mirror llvm / 6d6b3df
[ProfileData] Use SoftInstrProfErrors to count soft errors, NFC Differential Revision: http://reviews.llvm.org/D20082 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@269222 91177308-0d34-0410-b5e6-96231b3b80d8 Vedant Kumar 4 years ago
3 changed file(s) with 124 addition(s) and 71 deletion(s). Raw diff Collapse all Expand all
283283 return std::error_code(static_cast(E), instrprof_category());
284284 }
285285
286 inline instrprof_error MergeResult(instrprof_error &Accumulator,
287 instrprof_error Result) {
288 // Prefer first error encountered as later errors may be secondary effects of
289 // the initial problem.
290 if (Accumulator == instrprof_error::success &&
291 Result != instrprof_error::success)
292 Accumulator = Result;
293 return Accumulator;
294 }
286 class SoftInstrProfErrors {
287 /// Count the number of soft instrprof_errors encountered and keep track of
288 /// the first such error for reporting purposes.
289
290 /// The first soft error encountered.
291 instrprof_error FirstError;
292
293 /// The number of hash mismatches.
294 unsigned NumHashMismatches;
295
296 /// The number of count mismatches.
297 unsigned NumCountMismatches;
298
299 /// The number of counter overflows.
300 unsigned NumCounterOverflows;
301
302 /// The number of value site count mismatches.
303 unsigned NumValueSiteCountMismatches;
304
305 public:
306 SoftInstrProfErrors()
307 : FirstError(instrprof_error::success), NumHashMismatches(0),
308 NumCountMismatches(0), NumCounterOverflows(0),
309 NumValueSiteCountMismatches(0) {}
310
311 /// Track a soft error (\p IE) and increment its associated counter.
312 void addError(instrprof_error IE);
313
314 /// Get the number of hash mismatches.
315 unsigned getNumHashMismatches() const { return NumHashMismatches; }
316
317 /// Get the number of count mismatches.
318 unsigned getNumCountMismatches() const { return NumCountMismatches; }
319
320 /// Get the number of counter overflows.
321 unsigned getNumCounterOverflows() const { return NumCounterOverflows; }
322
323 /// Get the number of value site count mismatches.
324 unsigned getNumValueSiteCountMismatches() const {
325 return NumValueSiteCountMismatches;
326 }
327
328 /// Return an error code for the first encountered error.
329 std::error_code getError() const { return make_error_code(FirstError); }
330 };
295331
296332 namespace object {
297333 class SectionRef;
464500
465501 /// Merge data from another InstrProfValueSiteRecord
466502 /// Optionally scale merged counts by \p Weight.
467 instrprof_error merge(InstrProfValueSiteRecord &Input, uint64_t Weight = 1);
503 void merge(SoftInstrProfErrors &SIPE, InstrProfValueSiteRecord &Input,
504 uint64_t Weight = 1);
468505 /// Scale up value profile data counts.
469 instrprof_error scale(uint64_t Weight);
506 void scale(SoftInstrProfErrors &SIPE, uint64_t Weight);
470507 };
471508
472509 /// Profiling information for a single function.
473510 struct InstrProfRecord {
474 InstrProfRecord() {}
511 InstrProfRecord() : SIPE() {}
475512 InstrProfRecord(StringRef Name, uint64_t Hash, std::vector Counts)
476 : Name(Name), Hash(Hash), Counts(std::move(Counts)) {}
513 : Name(Name), Hash(Hash), Counts(std::move(Counts)), SIPE() {}
477514 StringRef Name;
478515 uint64_t Hash;
479516 std::vector Counts;
517 SoftInstrProfErrors SIPE;
480518
481519 typedef std::vector> ValueMapType;
482520
511549
512550 /// Merge the counts in \p Other into this one.
513551 /// Optionally scale merged counts by \p Weight.
514 instrprof_error merge(InstrProfRecord &Other, uint64_t Weight = 1);
552 void merge(InstrProfRecord &Other, uint64_t Weight = 1);
515553
516554 /// Scale up profile counts (including value profile data) by
517555 /// \p Weight.
518 instrprof_error scale(uint64_t Weight);
556 void scale(uint64_t Weight);
519557
520558 /// Sort value profile data (per site) by count.
521559 void sortValueData() {
531569 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
532570 getValueSitesForKind(Kind).clear();
533571 }
572
573 /// Get the error contained within the record's soft error counter.
574 std::error_code getError() const { return SIPE.getError(); }
534575
535576 private:
536577 std::vector IndirectCallSites;
558599
559600 // Merge Value Profile data from Src record to this record for ValueKind.
560601 // Scale merged value counts by \p Weight.
561 instrprof_error mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src,
562 uint64_t Weight);
602 void mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src,
603 uint64_t Weight);
563604 // Scale up value profile data count.
564 instrprof_error scaleValueProfData(uint32_t ValueKind, uint64_t Weight);
605 void scaleValueProfData(uint32_t ValueKind, uint64_t Weight);
565606 };
566607
567608 uint32_t InstrProfRecord::getNumValueKinds() const {
7979
8080 namespace llvm {
8181
82 void SoftInstrProfErrors::addError(instrprof_error IE) {
83 if (IE == instrprof_error::success)
84 return;
85
86 if (FirstError == instrprof_error::success)
87 FirstError = IE;
88
89 switch (IE) {
90 case instrprof_error::hash_mismatch:
91 ++NumHashMismatches;
92 break;
93 case instrprof_error::count_mismatch:
94 ++NumCountMismatches;
95 break;
96 case instrprof_error::counter_overflow:
97 ++NumCounterOverflows;
98 break;
99 case instrprof_error::value_site_count_mismatch:
100 ++NumValueSiteCountMismatches;
101 break;
102 default:
103 llvm_unreachable("Not a soft error");
104 }
105 }
106
82107 std::string getPGOFuncName(StringRef RawFuncName,
83108 GlobalValue::LinkageTypes Linkage,
84109 StringRef FileName,
290315 return make_error_code(instrprof_error::success);
291316 }
292317
293 instrprof_error InstrProfValueSiteRecord::merge(InstrProfValueSiteRecord &Input,
294 uint64_t Weight) {
318 void InstrProfValueSiteRecord::merge(SoftInstrProfErrors &SIPE,
319 InstrProfValueSiteRecord &Input,
320 uint64_t Weight) {
295321 this->sortByTargetValues();
296322 Input.sortByTargetValues();
297323 auto I = ValueData.begin();
298324 auto IE = ValueData.end();
299 instrprof_error Result = instrprof_error::success;
300325 for (auto J = Input.ValueData.begin(), JE = Input.ValueData.end(); J != JE;
301326 ++J) {
302327 while (I != IE && I->Value < J->Value)
305330 bool Overflowed;
306331 I->Count = SaturatingMultiplyAdd(J->Count, Weight, I->Count, &Overflowed);
307332 if (Overflowed)
308 Result = instrprof_error::counter_overflow;
333 SIPE.addError(instrprof_error::counter_overflow);
309334 ++I;
310335 continue;
311336 }
312337 ValueData.insert(I, *J);
313338 }
314 return Result;
315 }
316
317 instrprof_error InstrProfValueSiteRecord::scale(uint64_t Weight) {
318 instrprof_error Result = instrprof_error::success;
339 }
340
341 void InstrProfValueSiteRecord::scale(SoftInstrProfErrors &SIPE,
342 uint64_t Weight) {
319343 for (auto I = ValueData.begin(), IE = ValueData.end(); I != IE; ++I) {
320344 bool Overflowed;
321345 I->Count = SaturatingMultiply(I->Count, Weight, &Overflowed);
322346 if (Overflowed)
323 Result = instrprof_error::counter_overflow;
324 }
325 return Result;
347 SIPE.addError(instrprof_error::counter_overflow);
348 }
326349 }
327350
328351 // Merge Value Profile data from Src record to this record for ValueKind.
329352 // Scale merged value counts by \p Weight.
330 instrprof_error InstrProfRecord::mergeValueProfData(uint32_t ValueKind,
331 InstrProfRecord &Src,
332 uint64_t Weight) {
353 void InstrProfRecord::mergeValueProfData(uint32_t ValueKind,
354 InstrProfRecord &Src,
355 uint64_t Weight) {
333356 uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
334357 uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);
335 if (ThisNumValueSites != OtherNumValueSites)
336 return instrprof_error::value_site_count_mismatch;
358 if (ThisNumValueSites != OtherNumValueSites) {
359 SIPE.addError(instrprof_error::value_site_count_mismatch);
360 return;
361 }
337362 std::vector &ThisSiteRecords =
338363 getValueSitesForKind(ValueKind);
339364 std::vector &OtherSiteRecords =
340365 Src.getValueSitesForKind(ValueKind);
341 instrprof_error Result = instrprof_error::success;
342366 for (uint32_t I = 0; I < ThisNumValueSites; I++)
343 MergeResult(Result, ThisSiteRecords[I].merge(OtherSiteRecords[I], Weight));
344 return Result;
345 }
346
347 instrprof_error InstrProfRecord::merge(InstrProfRecord &Other,
348 uint64_t Weight) {
367 ThisSiteRecords[I].merge(SIPE, OtherSiteRecords[I], Weight);
368 }
369
370 void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight) {
349371 // If the number of counters doesn't match we either have bad data
350372 // or a hash collision.
351 if (Counts.size() != Other.Counts.size())
352 return instrprof_error::count_mismatch;
353
354 instrprof_error Result = instrprof_error::success;
373 if (Counts.size() != Other.Counts.size()) {
374 SIPE.addError(instrprof_error::count_mismatch);
375 return;
376 }
355377
356378 for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {
357379 bool Overflowed;
358380 Counts[I] =
359381 SaturatingMultiplyAdd(Other.Counts[I], Weight, Counts[I], &Overflowed);
360382 if (Overflowed)
361 Result = instrprof_error::counter_overflow;
383 SIPE.addError(instrprof_error::counter_overflow);
362384 }
363385
364386 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
365 MergeResult(Result, mergeValueProfData(Kind, Other, Weight));
366
367 return Result;
368 }
369
370 instrprof_error InstrProfRecord::scaleValueProfData(uint32_t ValueKind,
371 uint64_t Weight) {
387 mergeValueProfData(Kind, Other, Weight);
388 }
389
390 void InstrProfRecord::scaleValueProfData(uint32_t ValueKind, uint64_t Weight) {
372391 uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
373392 std::vector &ThisSiteRecords =
374393 getValueSitesForKind(ValueKind);
375 instrprof_error Result = instrprof_error::success;
376394 for (uint32_t I = 0; I < ThisNumValueSites; I++)
377 MergeResult(Result, ThisSiteRecords[I].scale(Weight));
378 return Result;
379 }
380
381 instrprof_error InstrProfRecord::scale(uint64_t Weight) {
382 instrprof_error Result = instrprof_error::success;
395 ThisSiteRecords[I].scale(SIPE, Weight);
396 }
397
398 void InstrProfRecord::scale(uint64_t Weight) {
383399 for (auto &Count : this->Counts) {
384400 bool Overflowed;
385401 Count = SaturatingMultiply(Count, Weight, &Overflowed);
386 if (Overflowed && Result == instrprof_error::success) {
387 Result = instrprof_error::counter_overflow;
388 }
402 if (Overflowed)
403 SIPE.addError(instrprof_error::counter_overflow);
389404 }
390405 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
391 MergeResult(Result, scaleValueProfData(Kind, Weight));
392
393 return Result;
406 scaleValueProfData(Kind, Weight);
394407 }
395408
396409 // Map indirect call target name hash to name string.
165165 ProfileDataMap.insert(std::make_pair(I.Hash, InstrProfRecord()));
166166 InstrProfRecord &Dest = Where->second;
167167
168 instrprof_error Result = instrprof_error::success;
169168 if (NewFunc) {
170169 // We've never seen a function with this name and hash, add it.
171170 Dest = std::move(I);
172171 // Fix up the name to avoid dangling reference.
173172 Dest.Name = FunctionData.find(Dest.Name)->getKey();
174173 if (Weight > 1)
175 Result = Dest.scale(Weight);
174 Dest.scale(Weight);
176175 } else {
177176 // We're updating a function we've seen before.
178 Result = Dest.merge(I, Weight);
177 Dest.merge(I, Weight);
179178 }
180179
181180 Dest.sortValueData();
182181
183 return Result;
182 return Dest.getError();
184183 }
185184
186185 bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) {