LLVM  4.0.0
InstrProfReader.cpp
Go to the documentation of this file.
1 //=-- InstrProfReader.cpp - Instrumented profiling reader -------------------=//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains support for reading profiling data for clang's
11 // instrumentation based PGO and coverage.
12 //
13 //===----------------------------------------------------------------------===//
14 
16 #include "llvm/ADT/STLExtras.h"
17 #include <cassert>
18 
19 using namespace llvm;
20 
22 setupMemoryBuffer(const Twine &Path) {
25  if (std::error_code EC = BufferOrErr.getError())
26  return errorCodeToError(EC);
27  return std::move(BufferOrErr.get());
28 }
29 
31  return Reader.readHeader();
32 }
33 
36  // Set up the buffer to read.
37  auto BufferOrError = setupMemoryBuffer(Path);
38  if (Error E = BufferOrError.takeError())
39  return std::move(E);
40  return InstrProfReader::create(std::move(BufferOrError.get()));
41 }
42 
44 InstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
45  // Sanity check the buffer.
46  if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
47  return make_error<InstrProfError>(instrprof_error::too_large);
48 
49  if (Buffer->getBufferSize() == 0)
50  return make_error<InstrProfError>(instrprof_error::empty_raw_profile);
51 
52  std::unique_ptr<InstrProfReader> Result;
53  // Create the reader.
55  Result.reset(new IndexedInstrProfReader(std::move(Buffer)));
56  else if (RawInstrProfReader64::hasFormat(*Buffer))
57  Result.reset(new RawInstrProfReader64(std::move(Buffer)));
58  else if (RawInstrProfReader32::hasFormat(*Buffer))
59  Result.reset(new RawInstrProfReader32(std::move(Buffer)));
60  else if (TextInstrProfReader::hasFormat(*Buffer))
61  Result.reset(new TextInstrProfReader(std::move(Buffer)));
62  else
63  return make_error<InstrProfError>(instrprof_error::unrecognized_format);
64 
65  // Initialize the reader and return the result.
66  if (Error E = initializeReader(*Result))
67  return std::move(E);
68 
69  return std::move(Result);
70 }
71 
74  // Set up the buffer to read.
75  auto BufferOrError = setupMemoryBuffer(Path);
76  if (Error E = BufferOrError.takeError())
77  return std::move(E);
78  return IndexedInstrProfReader::create(std::move(BufferOrError.get()));
79 }
80 
81 
83 IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
84  // Sanity check the buffer.
85  if (Buffer->getBufferSize() > std::numeric_limits<unsigned>::max())
86  return make_error<InstrProfError>(instrprof_error::too_large);
87 
88  // Create the reader.
90  return make_error<InstrProfError>(instrprof_error::bad_magic);
91  auto Result = llvm::make_unique<IndexedInstrProfReader>(std::move(Buffer));
92 
93  // Initialize the reader and return the result.
94  if (Error E = initializeReader(*Result))
95  return std::move(E);
96 
97  return std::move(Result);
98 }
99 
100 void InstrProfIterator::Increment() {
101  if (auto E = Reader->readNextRecord(Record)) {
102  // Handle errors in the reader.
103  InstrProfError::take(std::move(E));
104  *this = InstrProfIterator();
105  }
106 }
107 
109  // Verify that this really looks like plain ASCII text by checking a
110  // 'reasonable' number of characters (up to profile magic size).
111  size_t count = std::min(Buffer.getBufferSize(), sizeof(uint64_t));
112  StringRef buffer = Buffer.getBufferStart();
113  return count == 0 ||
114  std::all_of(buffer.begin(), buffer.begin() + count,
115  [](char c) { return ::isprint(c) || ::isspace(c); });
116 }
117 
118 // Read the profile variant flag from the header: ":FE" means this is a FE
119 // generated profile. ":IR" means this is an IR level profile. Other strings
120 // with a leading ':' will be reported an error format.
122  Symtab.reset(new InstrProfSymtab());
123  bool IsIRInstr = false;
124  if (!Line->startswith(":")) {
125  IsIRLevelProfile = false;
126  return success();
127  }
128  StringRef Str = (Line)->substr(1);
129  if (Str.equals_lower("ir"))
130  IsIRInstr = true;
131  else if (Str.equals_lower("fe"))
132  IsIRInstr = false;
133  else
135 
136  ++Line;
137  IsIRLevelProfile = IsIRInstr;
138  return success();
139 }
140 
141 Error
142 TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
143 
144 #define CHECK_LINE_END(Line) \
145  if (Line.is_at_end()) \
146  return error(instrprof_error::truncated);
147 #define READ_NUM(Str, Dst) \
148  if ((Str).getAsInteger(10, (Dst))) \
149  return error(instrprof_error::malformed);
150 #define VP_READ_ADVANCE(Val) \
151  CHECK_LINE_END(Line); \
152  uint32_t Val; \
153  READ_NUM((*Line), (Val)); \
154  Line++;
155 
156  if (Line.is_at_end())
157  return success();
158 
159  uint32_t NumValueKinds;
160  if (Line->getAsInteger(10, NumValueKinds)) {
161  // No value profile data
162  return success();
163  }
164  if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)
166  Line++;
167 
168  for (uint32_t VK = 0; VK < NumValueKinds; VK++) {
169  VP_READ_ADVANCE(ValueKind);
170  if (ValueKind > IPVK_Last)
172  VP_READ_ADVANCE(NumValueSites);
173  if (!NumValueSites)
174  continue;
175 
176  Record.reserveSites(VK, NumValueSites);
177  for (uint32_t S = 0; S < NumValueSites; S++) {
178  VP_READ_ADVANCE(NumValueData);
179 
180  std::vector<InstrProfValueData> CurrentValues;
181  for (uint32_t V = 0; V < NumValueData; V++) {
182  CHECK_LINE_END(Line);
183  std::pair<StringRef, StringRef> VD = Line->rsplit(':');
184  uint64_t TakenCount, Value;
185  if (VK == IPVK_IndirectCallTarget) {
186  Symtab->addFuncName(VD.first);
187  Value = IndexedInstrProf::ComputeHash(VD.first);
188  } else {
189  READ_NUM(VD.first, Value);
190  }
191  READ_NUM(VD.second, TakenCount);
192  CurrentValues.push_back({Value, TakenCount});
193  Line++;
194  }
195  Record.addValueData(VK, S, CurrentValues.data(), NumValueData, nullptr);
196  }
197  }
198  return success();
199 
200 #undef CHECK_LINE_END
201 #undef READ_NUM
202 #undef VP_READ_ADVANCE
203 }
204 
206  // Skip empty lines and comments.
207  while (!Line.is_at_end() && (Line->empty() || Line->startswith("#")))
208  ++Line;
209  // If we hit EOF while looking for a name, we're done.
210  if (Line.is_at_end()) {
211  Symtab->finalizeSymtab();
212  return error(instrprof_error::eof);
213  }
214 
215  // Read the function name.
216  Record.Name = *Line++;
217  Symtab->addFuncName(Record.Name);
218 
219  // Read the function hash.
220  if (Line.is_at_end())
222  if ((Line++)->getAsInteger(0, Record.Hash))
224 
225  // Read the number of counters.
226  uint64_t NumCounters;
227  if (Line.is_at_end())
229  if ((Line++)->getAsInteger(10, NumCounters))
231  if (NumCounters == 0)
233 
234  // Read each counter and fill our internal storage with the values.
235  Record.Counts.clear();
236  Record.Counts.reserve(NumCounters);
237  for (uint64_t I = 0; I < NumCounters; ++I) {
238  if (Line.is_at_end())
240  uint64_t Count;
241  if ((Line++)->getAsInteger(10, Count))
243  Record.Counts.push_back(Count);
244  }
245 
246  // Check if value profile data exists and read it if so.
247  if (Error E = readValueProfileData(Record))
248  return E;
249 
250  // This is needed to avoid two pass parsing because llvm-profdata
251  // does dumping while reading.
252  Symtab->finalizeSymtab();
253  return success();
254 }
255 
256 template <class IntPtrT>
258  if (DataBuffer.getBufferSize() < sizeof(uint64_t))
259  return false;
260  uint64_t Magic =
261  *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart());
262  return RawInstrProf::getMagic<IntPtrT>() == Magic ||
263  sys::getSwappedBytes(RawInstrProf::getMagic<IntPtrT>()) == Magic;
264 }
265 
266 template <class IntPtrT>
268  if (!hasFormat(*DataBuffer))
270  if (DataBuffer->getBufferSize() < sizeof(RawInstrProf::Header))
272  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(
273  DataBuffer->getBufferStart());
274  ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
275  return readHeader(*Header);
276 }
277 
278 template <class IntPtrT>
279 Error RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) {
280  const char *End = DataBuffer->getBufferEnd();
281  // Skip zero padding between profiles.
282  while (CurrentPos != End && *CurrentPos == 0)
283  ++CurrentPos;
284  // If there's nothing left, we're done.
285  if (CurrentPos == End)
286  return make_error<InstrProfError>(instrprof_error::eof);
287  // If there isn't enough space for another header, this is probably just
288  // garbage at the end of the file.
289  if (CurrentPos + sizeof(RawInstrProf::Header) > End)
290  return make_error<InstrProfError>(instrprof_error::malformed);
291  // The writer ensures each profile is padded to start at an aligned address.
292  if (reinterpret_cast<size_t>(CurrentPos) % alignof(uint64_t))
293  return make_error<InstrProfError>(instrprof_error::malformed);
294  // The magic should have the same byte order as in the previous header.
295  uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos);
296  if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
297  return make_error<InstrProfError>(instrprof_error::bad_magic);
298 
299  // There's another profile to read, so we need to process the header.
300  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(CurrentPos);
301  return readHeader(*Header);
302 }
303 
304 template <class IntPtrT>
306  if (Error E = Symtab.create(StringRef(NamesStart, NamesSize)))
307  return error(std::move(E));
308  for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I != DataEnd; ++I) {
309  const IntPtrT FPtr = swap(I->FunctionPointer);
310  if (!FPtr)
311  continue;
312  Symtab.mapAddress(FPtr, I->NameRef);
313  }
314  Symtab.finalizeSymtab();
315  return success();
316 }
317 
318 template <class IntPtrT>
320  const RawInstrProf::Header &Header) {
321  Version = swap(Header.Version);
322  if (GET_VERSION(Version) != RawInstrProf::Version)
324 
325  CountersDelta = swap(Header.CountersDelta);
326  NamesDelta = swap(Header.NamesDelta);
327  auto DataSize = swap(Header.DataSize);
328  auto CountersSize = swap(Header.CountersSize);
329  NamesSize = swap(Header.NamesSize);
330  ValueKindLast = swap(Header.ValueKindLast);
331 
332  auto DataSizeInBytes = DataSize * sizeof(RawInstrProf::ProfileData<IntPtrT>);
333  auto PaddingSize = getNumPaddingBytes(NamesSize);
334 
335  ptrdiff_t DataOffset = sizeof(RawInstrProf::Header);
336  ptrdiff_t CountersOffset = DataOffset + DataSizeInBytes;
337  ptrdiff_t NamesOffset = CountersOffset + sizeof(uint64_t) * CountersSize;
338  ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
339 
340  auto *Start = reinterpret_cast<const char *>(&Header);
341  if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
343 
344  Data = reinterpret_cast<const RawInstrProf::ProfileData<IntPtrT> *>(
345  Start + DataOffset);
346  DataEnd = Data + DataSize;
347  CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
348  NamesStart = Start + NamesOffset;
349  ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset);
350 
351  std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
352  if (Error E = createSymtab(*NewSymtab.get()))
353  return E;
354 
355  Symtab = std::move(NewSymtab);
356  return success();
357 }
358 
359 template <class IntPtrT>
361  Record.Name = getName(Data->NameRef);
362  return success();
363 }
364 
365 template <class IntPtrT>
367  Record.Hash = swap(Data->FuncHash);
368  return success();
369 }
370 
371 template <class IntPtrT>
373  InstrProfRecord &Record) {
374  uint32_t NumCounters = swap(Data->NumCounters);
375  IntPtrT CounterPtr = Data->CounterPtr;
376  if (NumCounters == 0)
378 
379  auto RawCounts = makeArrayRef(getCounter(CounterPtr), NumCounters);
380  auto *NamesStartAsCounter = reinterpret_cast<const uint64_t *>(NamesStart);
381 
382  // Check bounds.
383  if (RawCounts.data() < CountersStart ||
384  RawCounts.data() + RawCounts.size() > NamesStartAsCounter)
386 
387  if (ShouldSwapBytes) {
388  Record.Counts.clear();
389  Record.Counts.reserve(RawCounts.size());
390  for (uint64_t Count : RawCounts)
391  Record.Counts.push_back(swap(Count));
392  } else
393  Record.Counts = RawCounts;
394 
395  return success();
396 }
397 
398 template <class IntPtrT>
400  InstrProfRecord &Record) {
401 
402  Record.clearValueData();
403  CurValueDataSize = 0;
404  // Need to match the logic in value profile dumper code in compiler-rt:
405  uint32_t NumValueKinds = 0;
406  for (uint32_t I = 0; I < IPVK_Last + 1; I++)
407  NumValueKinds += (Data->NumValueSites[I] != 0);
408 
409  if (!NumValueKinds)
410  return success();
411 
413  ValueProfData::getValueProfData(
414  ValueDataStart, (const unsigned char *)DataBuffer->getBufferEnd(),
415  getDataEndianness());
416 
417  if (Error E = VDataPtrOrErr.takeError())
418  return E;
419 
420  // Note that besides deserialization, this also performs the conversion for
421  // indirect call targets. The function pointers from the raw profile are
422  // remapped into function name hashes.
423  VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
424  CurValueDataSize = VDataPtrOrErr.get()->getSize();
425  return success();
426 }
427 
428 template <class IntPtrT>
430  if (atEnd())
431  // At this point, ValueDataStart field points to the next header.
432  if (Error E = readNextHeader(getNextHeaderPos()))
433  return E;
434 
435  // Read name ad set it in Record.
436  if (Error E = readName(Record))
437  return E;
438 
439  // Read FuncHash and set it in Record.
440  if (Error E = readFuncHash(Record))
441  return E;
442 
443  // Read raw counts and set Record.
444  if (Error E = readRawCounts(Record))
445  return E;
446 
447  // Read value data and set Record.
448  if (Error E = readValueProfilingData(Record))
449  return E;
450 
451  // Iterate.
452  advanceData();
453  return success();
454 }
455 
456 namespace llvm {
457 template class RawInstrProfReader<uint32_t>;
458 template class RawInstrProfReader<uint64_t>;
459 }
460 
463  return IndexedInstrProf::ComputeHash(HashType, K);
464 }
465 
468 
470  const unsigned char *&D, const unsigned char *const End) {
472  ValueProfData::getValueProfData(D, End, ValueProfDataEndianness);
473 
474  if (VDataPtrOrErr.takeError())
475  return false;
476 
477  VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), nullptr);
478  D += VDataPtrOrErr.get()->TotalSize;
479 
480  return true;
481 }
482 
484  offset_type N) {
485  // Check if the data is corrupt. If so, don't try to read it.
486  if (N % sizeof(uint64_t))
487  return data_type();
488 
489  DataBuffer.clear();
490  std::vector<uint64_t> CounterBuffer;
491 
492  using namespace support;
493  const unsigned char *End = D + N;
494  while (D < End) {
495  // Read hash.
496  if (D + sizeof(uint64_t) >= End)
497  return data_type();
498  uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(D);
499 
500  // Initialize number of counters for GET_VERSION(FormatVersion) == 1.
501  uint64_t CountsSize = N / sizeof(uint64_t) - 1;
502  // If format version is different then read the number of counters.
503  if (GET_VERSION(FormatVersion) != IndexedInstrProf::ProfVersion::Version1) {
504  if (D + sizeof(uint64_t) > End)
505  return data_type();
506  CountsSize = endian::readNext<uint64_t, little, unaligned>(D);
507  }
508  // Read counter values.
509  if (D + CountsSize * sizeof(uint64_t) > End)
510  return data_type();
511 
512  CounterBuffer.clear();
513  CounterBuffer.reserve(CountsSize);
514  for (uint64_t J = 0; J < CountsSize; ++J)
515  CounterBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D));
516 
517  DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer));
518 
519  // Read value profiling data.
520  if (GET_VERSION(FormatVersion) > IndexedInstrProf::ProfVersion::Version2 &&
521  !readValueProfilingData(D, End)) {
522  DataBuffer.clear();
523  return data_type();
524  }
525  }
526  return DataBuffer;
527 }
528 
529 template <typename HashTableImpl>
531  StringRef FuncName, ArrayRef<InstrProfRecord> &Data) {
532  auto Iter = HashTable->find(FuncName);
533  if (Iter == HashTable->end())
534  return make_error<InstrProfError>(instrprof_error::unknown_function);
535 
536  Data = (*Iter);
537  if (Data.empty())
538  return make_error<InstrProfError>(instrprof_error::malformed);
539 
540  return Error::success();
541 }
542 
543 template <typename HashTableImpl>
546  if (atEnd())
547  return make_error<InstrProfError>(instrprof_error::eof);
548 
549  Data = *RecordIterator;
550 
551  if (Data.empty())
552  return make_error<InstrProfError>(instrprof_error::malformed);
553 
554  return Error::success();
555 }
556 
557 template <typename HashTableImpl>
559  const unsigned char *Buckets, const unsigned char *const Payload,
560  const unsigned char *const Base, IndexedInstrProf::HashT HashType,
561  uint64_t Version) {
562  FormatVersion = Version;
563  HashTable.reset(HashTableImpl::Create(
564  Buckets, Payload, Base,
565  typename HashTableImpl::InfoType(HashType, Version)));
566  RecordIterator = HashTable->data_begin();
567 }
568 
570  if (DataBuffer.getBufferSize() < 8)
571  return false;
572  using namespace support;
573  uint64_t Magic =
574  endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart());
575  // Verify that it's magical.
576  return Magic == IndexedInstrProf::Magic;
577 }
578 
579 const unsigned char *
580 IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
581  const unsigned char *Cur) {
582  using namespace IndexedInstrProf;
583  using namespace support;
584  if (Version >= IndexedInstrProf::Version4) {
585  const IndexedInstrProf::Summary *SummaryInLE =
586  reinterpret_cast<const IndexedInstrProf::Summary *>(Cur);
587  uint64_t NFields =
588  endian::byte_swap<uint64_t, little>(SummaryInLE->NumSummaryFields);
589  uint64_t NEntries =
590  endian::byte_swap<uint64_t, little>(SummaryInLE->NumCutoffEntries);
591  uint32_t SummarySize =
592  IndexedInstrProf::Summary::getSize(NFields, NEntries);
593  std::unique_ptr<IndexedInstrProf::Summary> SummaryData =
594  IndexedInstrProf::allocSummary(SummarySize);
595 
596  const uint64_t *Src = reinterpret_cast<const uint64_t *>(SummaryInLE);
597  uint64_t *Dst = reinterpret_cast<uint64_t *>(SummaryData.get());
598  for (unsigned I = 0; I < SummarySize / sizeof(uint64_t); I++)
599  Dst[I] = endian::byte_swap<uint64_t, little>(Src[I]);
600 
601  llvm::SummaryEntryVector DetailedSummary;
602  for (unsigned I = 0; I < SummaryData->NumCutoffEntries; I++) {
603  const IndexedInstrProf::Summary::Entry &Ent = SummaryData->getEntry(I);
604  DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
605  Ent.NumBlocks);
606  }
607  // initialize InstrProfSummary using the SummaryData from disk.
608  this->Summary = llvm::make_unique<ProfileSummary>(
609  ProfileSummary::PSK_Instr, DetailedSummary,
610  SummaryData->get(Summary::TotalBlockCount),
611  SummaryData->get(Summary::MaxBlockCount),
612  SummaryData->get(Summary::MaxInternalBlockCount),
613  SummaryData->get(Summary::MaxFunctionCount),
614  SummaryData->get(Summary::TotalNumBlocks),
615  SummaryData->get(Summary::TotalNumFunctions));
616  return Cur + SummarySize;
617  } else {
618  // For older version of profile data, we need to compute on the fly:
619  using namespace IndexedInstrProf;
621  // FIXME: This only computes an empty summary. Need to call addRecord for
622  // all InstrProfRecords to get the correct summary.
623  this->Summary = Builder.getSummary();
624  return Cur;
625  }
626 }
627 
629  const unsigned char *Start =
630  (const unsigned char *)DataBuffer->getBufferStart();
631  const unsigned char *Cur = Start;
632  if ((const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
634 
635  using namespace support;
636 
637  auto *Header = reinterpret_cast<const IndexedInstrProf::Header *>(Cur);
638  Cur += sizeof(IndexedInstrProf::Header);
639 
640  // Check the magic number.
641  uint64_t Magic = endian::byte_swap<uint64_t, little>(Header->Magic);
642  if (Magic != IndexedInstrProf::Magic)
644 
645  // Read the version.
646  uint64_t FormatVersion = endian::byte_swap<uint64_t, little>(Header->Version);
647  if (GET_VERSION(FormatVersion) >
650 
651  Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur);
652 
653  // Read the hash type and start offset.
654  IndexedInstrProf::HashT HashType = static_cast<IndexedInstrProf::HashT>(
655  endian::byte_swap<uint64_t, little>(Header->HashType));
656  if (HashType > IndexedInstrProf::HashT::Last)
658 
659  uint64_t HashOffset = endian::byte_swap<uint64_t, little>(Header->HashOffset);
660 
661  // The rest of the file is an on disk hash table.
662  InstrProfReaderIndexBase *IndexPtr = nullptr;
664  Start + HashOffset, Cur, Start, HashType, FormatVersion);
665  Index.reset(IndexPtr);
666  return success();
667 }
668 
670  if (Symtab.get())
671  return *Symtab.get();
672 
673  std::unique_ptr<InstrProfSymtab> NewSymtab = make_unique<InstrProfSymtab>();
674  Index->populateSymtab(*NewSymtab.get());
675 
676  Symtab = std::move(NewSymtab);
677  return *Symtab.get();
678 }
679 
682  uint64_t FuncHash) {
684  Error Err = Index->getRecords(FuncName, Data);
685  if (Err)
686  return std::move(Err);
687  // Found it. Look for counters with the right hash.
688  for (unsigned I = 0, E = Data.size(); I < E; ++I) {
689  // Check for a match and fill the vector if there is one.
690  if (Data[I].Hash == FuncHash) {
691  return std::move(Data[I]);
692  }
693  }
695 }
696 
698  uint64_t FuncHash,
699  std::vector<uint64_t> &Counts) {
700  Expected<InstrProfRecord> Record = getInstrProfRecord(FuncName, FuncHash);
701  if (Error E = Record.takeError())
702  return error(std::move(E));
703 
704  Counts = Record.get().Counts;
705  return success();
706 }
707 
709  static unsigned RecordIndex = 0;
710 
712 
713  Error E = Index->getRecords(Data);
714  if (E)
715  return error(std::move(E));
716 
717  Record = Data[RecordIndex++];
718  if (RecordIndex >= Data.size()) {
719  Index->advanceToNextKey();
720  RecordIndex = 0;
721  }
722  return success();
723 }
Error getRecords(ArrayRef< InstrProfRecord > &Data) override
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:494
#define VP_READ_ADVANCE(Val)
std::error_code getError() const
Definition: ErrorOr.h:169
Error readNextRecord(InstrProfRecord &Record) override
Read a single record.
Represents either an error or a value T.
Definition: ErrorOr.h:68
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:416
Error readHeader() override
Read the header. Required before reading first record.
static uint32_t getSize(uint32_t NumSumFields, uint32_t NumCutoffEntries)
Definition: InstrProf.h:852
const char * getBufferStart() const
Definition: MemoryBuffer.h:55
uint64_t MinBlockCount
The minimum execution count for this percentile.
Definition: InstrProf.h:823
static bool hasFormat(const MemoryBuffer &DataBuffer)
Return true if the given buffer is in an indexed instrprof format.
static instrprof_error take(Error E)
Consume an Error and return the raw enum value contained within it.
Definition: InstrProf.h:330
LLVM_NODISCARD bool equals_lower(StringRef RHS) const
equals_lower - Check for string equality, ignoring case.
Definition: StringRef.h:173
Error error(instrprof_error Err)
Set the current error and return same.
AddrHashMap & getAddrHashMap()
Definition: InstrProf.h:479
std::unique_ptr< Summary > allocSummary(uint32_t TotalSize)
Definition: InstrProf.h:893
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
Definition: ProfileCommon.h:66
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:736
InstrProfSymtab & getSymtab() override
Return the PGO symtab.
Error takeError()
Take ownership of the stored error.
Error readNextRecord(InstrProfRecord &Record) override
Read a single record.
void reserveSites(uint32_t ValueKind, uint32_t NumValueSites)
Reserve space for NumValueSites sites.
Definition: InstrProf.h:736
Error readHeader() override
Read the header.
data_type ReadData(StringRef K, const unsigned char *D, offset_type N)
const uint64_t Magic
Definition: InstrProf.h:777
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
virtual Error readNextRecord(InstrProfRecord &Record)=0
Read a single record.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
static Expected< std::unique_ptr< InstrProfReader > > create(const Twine &Path)
Factory method to create an appropriately typed reader for the given instrprof file.
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:440
static GCRegistry::Add< StatepointGC > D("statepoint-example","an example strategy for statepoint")
InstrProfLookupTrait::data_type data_type
static StringRef getName(Value *V)
RawInstrProfReader< uint32_t > RawInstrProfReader32
Tagged union holding either a T or a Error.
InstrProfLookupTrait::offset_type offset_type
void mapAddress(uint64_t Addr, uint64_t MD5Val)
Map a function address to its name's MD5 hash.
Definition: InstrProf.h:476
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:264
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if the given buffer is in text instrprof format.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
auto count(R &&Range, const E &Element) -> typename std::iterator_traits< decltype(std::begin(Range))>::difference_type
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:791
const uint64_t Version
Definition: InstrProf.h:908
Reader for the simple text based instrprof format.
uint64_t NumBlocks
Number of blocks >= the minumum execution count.
Definition: InstrProf.h:824
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
static bool hasFormat(const MemoryBuffer &DataBuffer)
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with etc Experimental Use value profile to guide fuzzing Number of simultaneous worker processes to run the jobs If min(jobs, NumberOfCpuCores()/2)\" is used.") FUZZER_FLAG_INT(reload
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
iterator begin() const
Definition: StringRef.h:103
hash_value_type ComputeHash(StringRef K)
Base class and interface for reading profiling data of any known instrprof format.
uint64_t Cutoff
The required percentile of total execution count.
Definition: InstrProf.h:821
bool is_at_end() const
Return true if we're an "end" iterator or have reached EOF.
Definition: LineIterator.h:53
LLVM_NODISCARD std::pair< StringRef, StringRef > rsplit(char Separator) const
Split into two substrings around the last occurrence of a separator character.
Definition: StringRef.h:787
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
bool readValueProfilingData(const unsigned char *&D, const unsigned char *const End)
std::unique_ptr< InstrProfSymtab > Symtab
static const unsigned End
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:136
uint64_t ComputeHash(StringRef K)
Definition: InstrProf.h:803
#define CHECK_LINE_END(Line)
#define READ_NUM(Str, Dst)
void addValueData(uint32_t ValueKind, uint32_t Site, InstrProfValueData *VData, uint32_t N, ValueMapType *ValueMap)
Add ValueData for ValueKind at value Site.
Definition: InstrProf.cpp:458
void clearValueData()
Clear value data entries.
Definition: InstrProf.h:639
static const char *const Magic
Definition: Archive.cpp:25
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Path)
static ErrorSuccess success()
Create a success value.
Reader for the raw instrprof binary format from runtime.
reference get()
Returns a reference to the stored T value.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:40
InstrProfReaderIndex(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, IndexedInstrProf::HashT HashType, uint64_t Version)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:586
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
unsigned char getSwappedBytes(unsigned char C)
Definition: SwapByteOrder.h:72
size_t getBufferSize() const
Definition: MemoryBuffer.h:57
success
Parameters (see the expansion example below): (the builder, addr, loaded, new_val, ordering, /* OUT.
RawInstrProfReader< uint64_t > RawInstrProfReader64
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, int64_t FileSize=-1, bool RequiresNullTerminator=true)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
std::vector< uint64_t > Counts
Definition: InstrProf.h:587
Error readHeader() override
Read the file header.
Error readNextRecord(InstrProfRecord &Record) override
Read a single record.
virtual Error readHeader()=0
Read the header. Required before reading first record.
Profiling information for a single function.
Definition: InstrProf.h:581
Expected< InstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash)
Return the pointer to InstrProfRecord associated with FuncName and FuncHash.
ArrayRef< InstrProfRecord > data_type
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
LLVM Value Representation.
Definition: Value.h:71
static Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path)
Factory method to create an indexed reader.
Lightweight error class with error context and mandatory checking.
Error error(const Twine &Message)
std::string Hash(const Unit &U)
Definition: FuzzerSHA1.cpp:216
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
Reader for the indexed binary instrprof format.
const uint64_t Version
Definition: InstrProf.h:799
reference get()
Definition: ErrorOr.h:166
Error success()
Clear the current error and return a successful one.
Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash, std::vector< uint64_t > &Counts)
Fill Counts with the profile data for the given function name.
std::vector< ProfileSummaryEntry > SummaryEntryVector
static Error initializeReader(InstrProfReader &Reader)