LLVM  14.0.0git
InstrProfReader.cpp
Go to the documentation of this file.
1 //===- InstrProfReader.cpp - Instrumented profiling reader ----------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains support for reading profiling data for clang's
10 // instrumentation based PGO and coverage.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/StringExtras.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/IR/ProfileSummary.h"
23 #include "llvm/Support/Endian.h"
24 #include "llvm/Support/Error.h"
25 #include "llvm/Support/ErrorOr.h"
29 #include <algorithm>
30 #include <cctype>
31 #include <cstddef>
32 #include <cstdint>
33 #include <limits>
34 #include <memory>
35 #include <system_error>
36 #include <utility>
37 #include <vector>
38 
39 using namespace llvm;
40 
42 setupMemoryBuffer(const Twine &Path) {
44  MemoryBuffer::getFileOrSTDIN(Path, /*IsText=*/true);
45  if (std::error_code EC = BufferOrErr.getError())
46  return errorCodeToError(EC);
47  return std::move(BufferOrErr.get());
48 }
49 
51  return Reader.readHeader();
52 }
53 
56  // Set up the buffer to read.
57  auto BufferOrError = setupMemoryBuffer(Path);
58  if (Error E = BufferOrError.takeError())
59  return std::move(E);
60  return InstrProfReader::create(std::move(BufferOrError.get()));
61 }
62 
64 InstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer) {
65  // Sanity check the buffer.
66  if (uint64_t(Buffer->getBufferSize()) > std::numeric_limits<uint64_t>::max())
67  return make_error<InstrProfError>(instrprof_error::too_large);
68 
69  if (Buffer->getBufferSize() == 0)
70  return make_error<InstrProfError>(instrprof_error::empty_raw_profile);
71 
72  std::unique_ptr<InstrProfReader> Result;
73  // Create the reader.
75  Result.reset(new IndexedInstrProfReader(std::move(Buffer)));
76  else if (RawInstrProfReader64::hasFormat(*Buffer))
77  Result.reset(new RawInstrProfReader64(std::move(Buffer)));
78  else if (RawInstrProfReader32::hasFormat(*Buffer))
79  Result.reset(new RawInstrProfReader32(std::move(Buffer)));
80  else if (TextInstrProfReader::hasFormat(*Buffer))
81  Result.reset(new TextInstrProfReader(std::move(Buffer)));
82  else
83  return make_error<InstrProfError>(instrprof_error::unrecognized_format);
84 
85  // Initialize the reader and return the result.
86  if (Error E = initializeReader(*Result))
87  return std::move(E);
88 
89  return std::move(Result);
90 }
91 
93 IndexedInstrProfReader::create(const Twine &Path, const Twine &RemappingPath) {
94  // Set up the buffer to read.
95  auto BufferOrError = setupMemoryBuffer(Path);
96  if (Error E = BufferOrError.takeError())
97  return std::move(E);
98 
99  // Set up the remapping buffer if requested.
100  std::unique_ptr<MemoryBuffer> RemappingBuffer;
101  std::string RemappingPathStr = RemappingPath.str();
102  if (!RemappingPathStr.empty()) {
103  auto RemappingBufferOrError = setupMemoryBuffer(RemappingPathStr);
104  if (Error E = RemappingBufferOrError.takeError())
105  return std::move(E);
106  RemappingBuffer = std::move(RemappingBufferOrError.get());
107  }
108 
109  return IndexedInstrProfReader::create(std::move(BufferOrError.get()),
110  std::move(RemappingBuffer));
111 }
112 
114 IndexedInstrProfReader::create(std::unique_ptr<MemoryBuffer> Buffer,
115  std::unique_ptr<MemoryBuffer> RemappingBuffer) {
116  // Sanity check the buffer.
117  if (uint64_t(Buffer->getBufferSize()) > std::numeric_limits<uint64_t>::max())
118  return make_error<InstrProfError>(instrprof_error::too_large);
119 
120  // Create the reader.
121  if (!IndexedInstrProfReader::hasFormat(*Buffer))
122  return make_error<InstrProfError>(instrprof_error::bad_magic);
123  auto Result = std::make_unique<IndexedInstrProfReader>(
124  std::move(Buffer), std::move(RemappingBuffer));
125 
126  // Initialize the reader and return the result.
127  if (Error E = initializeReader(*Result))
128  return std::move(E);
129 
130  return std::move(Result);
131 }
132 
133 void InstrProfIterator::Increment() {
134  if (auto E = Reader->readNextRecord(Record)) {
135  // Handle errors in the reader.
137  *this = InstrProfIterator();
138  }
139 }
140 
142  // Verify that this really looks like plain ASCII text by checking a
143  // 'reasonable' number of characters (up to profile magic size).
144  size_t count = std::min(Buffer.getBufferSize(), sizeof(uint64_t));
145  StringRef buffer = Buffer.getBufferStart();
146  return count == 0 ||
147  std::all_of(buffer.begin(), buffer.begin() + count,
148  [](char c) { return isPrint(c) || isSpace(c); });
149 }
150 
151 // Read the profile variant flag from the header: ":FE" means this is a FE
152 // generated profile. ":IR" means this is an IR level profile. Other strings
153 // with a leading ':' will be reported an error format.
155  Symtab.reset(new InstrProfSymtab());
156  bool IsIRInstr = false;
157  bool IsEntryFirst = false;
158  bool IsCS = false;
159 
160  while (Line->startswith(":")) {
161  StringRef Str = Line->substr(1);
162  if (Str.equals_insensitive("ir"))
163  IsIRInstr = true;
164  else if (Str.equals_insensitive("fe"))
165  IsIRInstr = false;
166  else if (Str.equals_insensitive("csir")) {
167  IsIRInstr = true;
168  IsCS = true;
169  } else if (Str.equals_insensitive("entry_first"))
170  IsEntryFirst = true;
171  else if (Str.equals_insensitive("not_entry_first"))
172  IsEntryFirst = false;
173  else
175  ++Line;
176  }
177  IsIRLevelProfile = IsIRInstr;
178  InstrEntryBBEnabled = IsEntryFirst;
179  HasCSIRLevelProfile = IsCS;
180  return success();
181 }
182 
183 Error
184 TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {
185 
186 #define CHECK_LINE_END(Line) \
187  if (Line.is_at_end()) \
188  return error(instrprof_error::truncated);
189 #define READ_NUM(Str, Dst) \
190  if ((Str).getAsInteger(10, (Dst))) \
191  return error(instrprof_error::malformed);
192 #define VP_READ_ADVANCE(Val) \
193  CHECK_LINE_END(Line); \
194  uint32_t Val; \
195  READ_NUM((*Line), (Val)); \
196  Line++;
197 
198  if (Line.is_at_end())
199  return success();
200 
201  uint32_t NumValueKinds;
202  if (Line->getAsInteger(10, NumValueKinds)) {
203  // No value profile data
204  return success();
205  }
206  if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)
208  Line++;
209 
210  for (uint32_t VK = 0; VK < NumValueKinds; VK++) {
212  if (ValueKind > IPVK_Last)
214  VP_READ_ADVANCE(NumValueSites);
215  if (!NumValueSites)
216  continue;
217 
218  Record.reserveSites(VK, NumValueSites);
219  for (uint32_t S = 0; S < NumValueSites; S++) {
220  VP_READ_ADVANCE(NumValueData);
221 
222  std::vector<InstrProfValueData> CurrentValues;
223  for (uint32_t V = 0; V < NumValueData; V++) {
224  CHECK_LINE_END(Line);
225  std::pair<StringRef, StringRef> VD = Line->rsplit(':');
226  uint64_t TakenCount, Value;
227  if (ValueKind == IPVK_IndirectCallTarget) {
228  if (InstrProfSymtab::isExternalSymbol(VD.first)) {
229  Value = 0;
230  } else {
231  if (Error E = Symtab->addFuncName(VD.first))
232  return E;
234  }
235  } else {
236  READ_NUM(VD.first, Value);
237  }
238  READ_NUM(VD.second, TakenCount);
239  CurrentValues.push_back({Value, TakenCount});
240  Line++;
241  }
242  Record.addValueData(ValueKind, S, CurrentValues.data(), NumValueData,
243  nullptr);
244  }
245  }
246  return success();
247 
248 #undef CHECK_LINE_END
249 #undef READ_NUM
250 #undef VP_READ_ADVANCE
251 }
252 
254  // Skip empty lines and comments.
255  while (!Line.is_at_end() && (Line->empty() || Line->startswith("#")))
256  ++Line;
257  // If we hit EOF while looking for a name, we're done.
258  if (Line.is_at_end()) {
259  return error(instrprof_error::eof);
260  }
261 
262  // Read the function name.
263  Record.Name = *Line++;
264  if (Error E = Symtab->addFuncName(Record.Name))
265  return error(std::move(E));
266 
267  // Read the function hash.
268  if (Line.is_at_end())
270  if ((Line++)->getAsInteger(0, Record.Hash))
272 
273  // Read the number of counters.
274  uint64_t NumCounters;
275  if (Line.is_at_end())
277  if ((Line++)->getAsInteger(10, NumCounters))
279  if (NumCounters == 0)
281 
282  // Read each counter and fill our internal storage with the values.
283  Record.Clear();
284  Record.Counts.reserve(NumCounters);
285  for (uint64_t I = 0; I < NumCounters; ++I) {
286  if (Line.is_at_end())
288  uint64_t Count;
289  if ((Line++)->getAsInteger(10, Count))
291  Record.Counts.push_back(Count);
292  }
293 
294  // Check if value profile data exists and read it if so.
295  if (Error E = readValueProfileData(Record))
296  return error(std::move(E));
297 
298  return success();
299 }
300 
301 template <class IntPtrT>
303  if (DataBuffer.getBufferSize() < sizeof(uint64_t))
304  return false;
305  uint64_t Magic =
306  *reinterpret_cast<const uint64_t *>(DataBuffer.getBufferStart());
307  return RawInstrProf::getMagic<IntPtrT>() == Magic ||
308  sys::getSwappedBytes(RawInstrProf::getMagic<IntPtrT>()) == Magic;
309 }
310 
311 template <class IntPtrT>
313  if (!hasFormat(*DataBuffer))
315  if (DataBuffer->getBufferSize() < sizeof(RawInstrProf::Header))
317  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(
318  DataBuffer->getBufferStart());
319  ShouldSwapBytes = Header->Magic != RawInstrProf::getMagic<IntPtrT>();
320  return readHeader(*Header);
321 }
322 
323 template <class IntPtrT>
324 Error RawInstrProfReader<IntPtrT>::readNextHeader(const char *CurrentPos) {
325  const char *End = DataBuffer->getBufferEnd();
326  // Skip zero padding between profiles.
327  while (CurrentPos != End && *CurrentPos == 0)
328  ++CurrentPos;
329  // If there's nothing left, we're done.
330  if (CurrentPos == End)
331  return make_error<InstrProfError>(instrprof_error::eof);
332  // If there isn't enough space for another header, this is probably just
333  // garbage at the end of the file.
334  if (CurrentPos + sizeof(RawInstrProf::Header) > End)
335  return make_error<InstrProfError>(instrprof_error::malformed);
336  // The writer ensures each profile is padded to start at an aligned address.
337  if (reinterpret_cast<size_t>(CurrentPos) % alignof(uint64_t))
338  return make_error<InstrProfError>(instrprof_error::malformed);
339  // The magic should have the same byte order as in the previous header.
340  uint64_t Magic = *reinterpret_cast<const uint64_t *>(CurrentPos);
341  if (Magic != swap(RawInstrProf::getMagic<IntPtrT>()))
342  return make_error<InstrProfError>(instrprof_error::bad_magic);
343 
344  // There's another profile to read, so we need to process the header.
345  auto *Header = reinterpret_cast<const RawInstrProf::Header *>(CurrentPos);
346  return readHeader(*Header);
347 }
348 
349 template <class IntPtrT>
351  if (Error E = Symtab.create(StringRef(NamesStart, NamesSize)))
352  return error(std::move(E));
353  for (const RawInstrProf::ProfileData<IntPtrT> *I = Data; I != DataEnd; ++I) {
354  const IntPtrT FPtr = swap(I->FunctionPointer);
355  if (!FPtr)
356  continue;
357  Symtab.mapAddress(FPtr, I->NameRef);
358  }
359  return success();
360 }
361 
362 template <class IntPtrT>
364  const RawInstrProf::Header &Header) {
365  Version = swap(Header.Version);
366  if (GET_VERSION(Version) != RawInstrProf::Version)
368 
369  BinaryIdsSize = swap(Header.BinaryIdsSize);
370  if (BinaryIdsSize % sizeof(uint64_t))
372 
373  CountersDelta = swap(Header.CountersDelta);
374  NamesDelta = swap(Header.NamesDelta);
375  auto DataSize = swap(Header.DataSize);
376  auto PaddingBytesBeforeCounters = swap(Header.PaddingBytesBeforeCounters);
377  auto CountersSize = swap(Header.CountersSize);
378  auto PaddingBytesAfterCounters = swap(Header.PaddingBytesAfterCounters);
379  NamesSize = swap(Header.NamesSize);
380  ValueKindLast = swap(Header.ValueKindLast);
381 
382  auto DataSizeInBytes = DataSize * sizeof(RawInstrProf::ProfileData<IntPtrT>);
383  auto PaddingSize = getNumPaddingBytes(NamesSize);
384 
385  // Profile data starts after profile header and binary ids if exist.
386  ptrdiff_t DataOffset = sizeof(RawInstrProf::Header) + BinaryIdsSize;
387  ptrdiff_t CountersOffset =
388  DataOffset + DataSizeInBytes + PaddingBytesBeforeCounters;
389  ptrdiff_t NamesOffset = CountersOffset + (sizeof(uint64_t) * CountersSize) +
390  PaddingBytesAfterCounters;
391  ptrdiff_t ValueDataOffset = NamesOffset + NamesSize + PaddingSize;
392 
393  auto *Start = reinterpret_cast<const char *>(&Header);
394  if (Start + ValueDataOffset > DataBuffer->getBufferEnd())
396 
397  Data = reinterpret_cast<const RawInstrProf::ProfileData<IntPtrT> *>(
398  Start + DataOffset);
399  DataEnd = Data + DataSize;
400 
401  // Binary ids start just after the header.
402  BinaryIdsStart =
403  reinterpret_cast<const uint8_t *>(&Header) + sizeof(RawInstrProf::Header);
404  CountersStart = reinterpret_cast<const uint64_t *>(Start + CountersOffset);
405  NamesStart = Start + NamesOffset;
406  ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset);
407 
408  const uint8_t *BufferEnd = (const uint8_t *)DataBuffer->getBufferEnd();
409  if (BinaryIdsStart + BinaryIdsSize > BufferEnd)
411 
412  std::unique_ptr<InstrProfSymtab> NewSymtab = std::make_unique<InstrProfSymtab>();
413  if (Error E = createSymtab(*NewSymtab.get()))
414  return E;
415 
416  Symtab = std::move(NewSymtab);
417  return success();
418 }
419 
420 template <class IntPtrT>
422  Record.Name = getName(Data->NameRef);
423  return success();
424 }
425 
426 template <class IntPtrT>
428  Record.Hash = swap(Data->FuncHash);
429  return success();
430 }
431 
432 template <class IntPtrT>
435  uint32_t NumCounters = swap(Data->NumCounters);
436  IntPtrT CounterPtr = Data->CounterPtr;
437  if (NumCounters == 0)
439 
440  auto *NamesStartAsCounter = reinterpret_cast<const uint64_t *>(NamesStart);
441  ptrdiff_t MaxNumCounters = NamesStartAsCounter - CountersStart;
442 
443  // Check bounds. Note that the counter pointer embedded in the data record
444  // may itself be corrupt.
445  if (MaxNumCounters < 0 || NumCounters > (uint32_t)MaxNumCounters)
447 
448  // We need to compute the in-buffer counter offset from the in-memory address
449  // distance. The initial CountersDelta is the in-memory address difference
450  // start(__llvm_prf_cnts)-start(__llvm_prf_data), so SrcData->CounterPtr -
451  // CountersDelta computes the offset into the in-buffer counter section.
452  //
453  // CountersDelta decreases as we advance to the next data record.
454  ptrdiff_t CounterOffset = getCounterOffset(CounterPtr);
455  CountersDelta -= sizeof(*Data);
456  if (CounterOffset < 0 || CounterOffset > MaxNumCounters ||
457  ((uint32_t)CounterOffset + NumCounters) > (uint32_t)MaxNumCounters)
459 
460  auto RawCounts = makeArrayRef(getCounter(CounterOffset), NumCounters);
461 
462  if (ShouldSwapBytes) {
463  Record.Counts.clear();
464  Record.Counts.reserve(RawCounts.size());
465  for (uint64_t Count : RawCounts)
466  Record.Counts.push_back(swap(Count));
467  } else
468  Record.Counts = RawCounts;
469 
470  return success();
471 }
472 
473 template <class IntPtrT>
476  Record.clearValueData();
477  CurValueDataSize = 0;
478  // Need to match the logic in value profile dumper code in compiler-rt:
479  uint32_t NumValueKinds = 0;
480  for (uint32_t I = 0; I < IPVK_Last + 1; I++)
481  NumValueKinds += (Data->NumValueSites[I] != 0);
482 
483  if (!NumValueKinds)
484  return success();
485 
487  ValueProfData::getValueProfData(
488  ValueDataStart, (const unsigned char *)DataBuffer->getBufferEnd(),
489  getDataEndianness());
490 
491  if (Error E = VDataPtrOrErr.takeError())
492  return E;
493 
494  // Note that besides deserialization, this also performs the conversion for
495  // indirect call targets. The function pointers from the raw profile are
496  // remapped into function name hashes.
497  VDataPtrOrErr.get()->deserializeTo(Record, Symtab.get());
498  CurValueDataSize = VDataPtrOrErr.get()->getSize();
499  return success();
500 }
501 
502 template <class IntPtrT>
504  if (atEnd())
505  // At this point, ValueDataStart field points to the next header.
506  if (Error E = readNextHeader(getNextHeaderPos()))
507  return error(std::move(E));
508 
509  // Read name ad set it in Record.
510  if (Error E = readName(Record))
511  return error(std::move(E));
512 
513  // Read FuncHash and set it in Record.
514  if (Error E = readFuncHash(Record))
515  return error(std::move(E));
516 
517  // Read raw counts and set Record.
518  if (Error E = readRawCounts(Record))
519  return error(std::move(E));
520 
521  // Read value data and set Record.
522  if (Error E = readValueProfilingData(Record))
523  return error(std::move(E));
524 
525  // Iterate.
526  advanceData();
527  return success();
528 }
529 
530 static size_t RoundUp(size_t size, size_t align) {
531  return (size + align - 1) & ~(align - 1);
532 }
533 
534 template <class IntPtrT>
536  if (BinaryIdsSize == 0)
537  return success();
538 
539  OS << "Binary IDs: \n";
540  const uint8_t *BI = BinaryIdsStart;
541  const uint8_t *BIEnd = BinaryIdsStart + BinaryIdsSize;
542  while (BI < BIEnd) {
543  size_t Remaining = BIEnd - BI;
544 
545  // There should be enough left to read the binary ID size field.
546  if (Remaining < sizeof(uint64_t))
547  return make_error<InstrProfError>(instrprof_error::malformed);
548 
549  uint64_t BinaryIdLen = swap(*reinterpret_cast<const uint64_t *>(BI));
550 
551  // There should be enough left to read the binary ID size field, and the
552  // binary ID.
553  if (Remaining < sizeof(BinaryIdLen) + BinaryIdLen)
554  return make_error<InstrProfError>(instrprof_error::malformed);
555 
556  // Increment by binary id length data type size.
557  BI += sizeof(BinaryIdLen);
558  if (BI > (const uint8_t *)DataBuffer->getBufferEnd())
559  return make_error<InstrProfError>(instrprof_error::malformed);
560 
561  for (uint64_t I = 0; I < BinaryIdLen; I++)
562  OS << format("%02x", BI[I]);
563  OS << "\n";
564 
565  // Increment by binary id data length, rounded to the next 8 bytes. This
566  // accounts for the zero-padding after each build ID.
567  BI += RoundUp(BinaryIdLen, sizeof(uint64_t));
568  if (BI > (const uint8_t *)DataBuffer->getBufferEnd())
569  return make_error<InstrProfError>(instrprof_error::malformed);
570  }
571 
572  return success();
573 }
574 
575 namespace llvm {
576 
577 template class RawInstrProfReader<uint32_t>;
578 template class RawInstrProfReader<uint64_t>;
579 
580 } // end namespace llvm
581 
584  return IndexedInstrProf::ComputeHash(HashType, K);
585 }
586 
589 
591  const unsigned char *&D, const unsigned char *const End) {
593  ValueProfData::getValueProfData(D, End, ValueProfDataEndianness);
594 
595  if (VDataPtrOrErr.takeError())
596  return false;
597 
598  VDataPtrOrErr.get()->deserializeTo(DataBuffer.back(), nullptr);
599  D += VDataPtrOrErr.get()->TotalSize;
600 
601  return true;
602 }
603 
605  offset_type N) {
606  using namespace support;
607 
608  // Check if the data is corrupt. If so, don't try to read it.
609  if (N % sizeof(uint64_t))
610  return data_type();
611 
612  DataBuffer.clear();
613  std::vector<uint64_t> CounterBuffer;
614 
615  const unsigned char *End = D + N;
616  while (D < End) {
617  // Read hash.
618  if (D + sizeof(uint64_t) >= End)
619  return data_type();
620  uint64_t Hash = endian::readNext<uint64_t, little, unaligned>(D);
621 
622  // Initialize number of counters for GET_VERSION(FormatVersion) == 1.
623  uint64_t CountsSize = N / sizeof(uint64_t) - 1;
624  // If format version is different then read the number of counters.
625  if (GET_VERSION(FormatVersion) != IndexedInstrProf::ProfVersion::Version1) {
626  if (D + sizeof(uint64_t) > End)
627  return data_type();
628  CountsSize = endian::readNext<uint64_t, little, unaligned>(D);
629  }
630  // Read counter values.
631  if (D + CountsSize * sizeof(uint64_t) > End)
632  return data_type();
633 
634  CounterBuffer.clear();
635  CounterBuffer.reserve(CountsSize);
636  for (uint64_t J = 0; J < CountsSize; ++J)
637  CounterBuffer.push_back(endian::readNext<uint64_t, little, unaligned>(D));
638 
639  DataBuffer.emplace_back(K, Hash, std::move(CounterBuffer));
640 
641  // Read value profiling data.
642  if (GET_VERSION(FormatVersion) > IndexedInstrProf::ProfVersion::Version2 &&
643  !readValueProfilingData(D, End)) {
644  DataBuffer.clear();
645  return data_type();
646  }
647  }
648  return DataBuffer;
649 }
650 
651 template <typename HashTableImpl>
654  auto Iter = HashTable->find(FuncName);
655  if (Iter == HashTable->end())
656  return make_error<InstrProfError>(instrprof_error::unknown_function);
657 
658  Data = (*Iter);
659  if (Data.empty())
660  return make_error<InstrProfError>(instrprof_error::malformed);
661 
662  return Error::success();
663 }
664 
665 template <typename HashTableImpl>
668  if (atEnd())
669  return make_error<InstrProfError>(instrprof_error::eof);
670 
671  Data = *RecordIterator;
672 
673  if (Data.empty())
674  return make_error<InstrProfError>(instrprof_error::malformed);
675 
676  return Error::success();
677 }
678 
679 template <typename HashTableImpl>
681  const unsigned char *Buckets, const unsigned char *const Payload,
682  const unsigned char *const Base, IndexedInstrProf::HashT HashType,
683  uint64_t Version) {
684  FormatVersion = Version;
685  HashTable.reset(HashTableImpl::Create(
686  Buckets, Payload, Base,
687  typename HashTableImpl::InfoType(HashType, Version)));
688  RecordIterator = HashTable->data_begin();
689 }
690 
691 namespace {
692 /// A remapper that does not apply any remappings.
693 class InstrProfReaderNullRemapper : public InstrProfReaderRemapper {
695 
696 public:
697  InstrProfReaderNullRemapper(InstrProfReaderIndexBase &Underlying)
698  : Underlying(Underlying) {}
699 
700  Error getRecords(StringRef FuncName,
702  return Underlying.getRecords(FuncName, Data);
703  }
704 };
705 }
706 
707 /// A remapper that applies remappings based on a symbol remapping file.
708 template <typename HashTableImpl>
710  : public InstrProfReaderRemapper {
711 public:
713  std::unique_ptr<MemoryBuffer> RemapBuffer,
715  : RemapBuffer(std::move(RemapBuffer)), Underlying(Underlying) {
716  }
717 
718  /// Extract the original function name from a PGO function name.
720  // We can have multiple :-separated pieces; there can be pieces both
721  // before and after the mangled name. Find the first part that starts
722  // with '_Z'; we'll assume that's the mangled name we want.
723  std::pair<StringRef, StringRef> Parts = {StringRef(), Name};
724  while (true) {
725  Parts = Parts.second.split(':');
726  if (Parts.first.startswith("_Z"))
727  return Parts.first;
728  if (Parts.second.empty())
729  return Name;
730  }
731  }
732 
733  /// Given a mangled name extracted from a PGO function name, and a new
734  /// form for that mangled name, reconstitute the name.
735  static void reconstituteName(StringRef OrigName, StringRef ExtractedName,
736  StringRef Replacement,
737  SmallVectorImpl<char> &Out) {
738  Out.reserve(OrigName.size() + Replacement.size() - ExtractedName.size());
739  Out.insert(Out.end(), OrigName.begin(), ExtractedName.begin());
740  Out.insert(Out.end(), Replacement.begin(), Replacement.end());
741  Out.insert(Out.end(), ExtractedName.end(), OrigName.end());
742  }
743 
745  if (Error E = Remappings.read(*RemapBuffer))
746  return E;
747  for (StringRef Name : Underlying.HashTable->keys()) {
748  StringRef RealName = extractName(Name);
749  if (auto Key = Remappings.insert(RealName)) {
750  // FIXME: We could theoretically map the same equivalence class to
751  // multiple names in the profile data. If that happens, we should
752  // return NamedInstrProfRecords from all of them.
753  MappedNames.insert({Key, RealName});
754  }
755  }
756  return Error::success();
757  }
758 
761  StringRef RealName = extractName(FuncName);
762  if (auto Key = Remappings.lookup(RealName)) {
763  StringRef Remapped = MappedNames.lookup(Key);
764  if (!Remapped.empty()) {
765  if (RealName.begin() == FuncName.begin() &&
766  RealName.end() == FuncName.end())
767  FuncName = Remapped;
768  else {
769  // Try rebuilding the name from the given remapping.
770  SmallString<256> Reconstituted;
771  reconstituteName(FuncName, RealName, Remapped, Reconstituted);
772  Error E = Underlying.getRecords(Reconstituted, Data);
773  if (!E)
774  return E;
775 
776  // If we failed because the name doesn't exist, fall back to asking
777  // about the original name.
778  if (Error Unhandled = handleErrors(
779  std::move(E), [](std::unique_ptr<InstrProfError> Err) {
780  return Err->get() == instrprof_error::unknown_function
781  ? Error::success()
782  : Error(std::move(Err));
783  }))
784  return Unhandled;
785  }
786  }
787  }
788  return Underlying.getRecords(FuncName, Data);
789  }
790 
791 private:
792  /// The memory buffer containing the remapping configuration. Remappings
793  /// holds pointers into this buffer.
794  std::unique_ptr<MemoryBuffer> RemapBuffer;
795 
796  /// The mangling remapper.
797  SymbolRemappingReader Remappings;
798 
799  /// Mapping from mangled name keys to the name used for the key in the
800  /// profile data.
801  /// FIXME: Can we store a location within the on-disk hash table instead of
802  /// redoing lookup?
804 
805  /// The real profile data reader.
807 };
808 
810  using namespace support;
811 
812  if (DataBuffer.getBufferSize() < 8)
813  return false;
814  uint64_t Magic =
815  endian::read<uint64_t, little, aligned>(DataBuffer.getBufferStart());
816  // Verify that it's magical.
817  return Magic == IndexedInstrProf::Magic;
818 }
819 
820 const unsigned char *
821 IndexedInstrProfReader::readSummary(IndexedInstrProf::ProfVersion Version,
822  const unsigned char *Cur, bool UseCS) {
823  using namespace IndexedInstrProf;
824  using namespace support;
825 
827  const IndexedInstrProf::Summary *SummaryInLE =
828  reinterpret_cast<const IndexedInstrProf::Summary *>(Cur);
829  uint64_t NFields =
830  endian::byte_swap<uint64_t, little>(SummaryInLE->NumSummaryFields);
831  uint64_t NEntries =
832  endian::byte_swap<uint64_t, little>(SummaryInLE->NumCutoffEntries);
833  uint32_t SummarySize =
834  IndexedInstrProf::Summary::getSize(NFields, NEntries);
835  std::unique_ptr<IndexedInstrProf::Summary> SummaryData =
836  IndexedInstrProf::allocSummary(SummarySize);
837 
838  const uint64_t *Src = reinterpret_cast<const uint64_t *>(SummaryInLE);
839  uint64_t *Dst = reinterpret_cast<uint64_t *>(SummaryData.get());
840  for (unsigned I = 0; I < SummarySize / sizeof(uint64_t); I++)
841  Dst[I] = endian::byte_swap<uint64_t, little>(Src[I]);
842 
843  SummaryEntryVector DetailedSummary;
844  for (unsigned I = 0; I < SummaryData->NumCutoffEntries; I++) {
845  const IndexedInstrProf::Summary::Entry &Ent = SummaryData->getEntry(I);
846  DetailedSummary.emplace_back((uint32_t)Ent.Cutoff, Ent.MinBlockCount,
847  Ent.NumBlocks);
848  }
849  std::unique_ptr<llvm::ProfileSummary> &Summary =
850  UseCS ? this->CS_Summary : this->Summary;
851 
852  // initialize InstrProfSummary using the SummaryData from disk.
853  Summary = std::make_unique<ProfileSummary>(
855  DetailedSummary, SummaryData->get(Summary::TotalBlockCount),
856  SummaryData->get(Summary::MaxBlockCount),
857  SummaryData->get(Summary::MaxInternalBlockCount),
858  SummaryData->get(Summary::MaxFunctionCount),
859  SummaryData->get(Summary::TotalNumBlocks),
860  SummaryData->get(Summary::TotalNumFunctions));
861  return Cur + SummarySize;
862  } else {
863  // The older versions do not support a profile summary. This just computes
864  // an empty summary, which will not result in accurate hot/cold detection.
865  // We would need to call addRecord for all NamedInstrProfRecords to get the
866  // correct summary. However, this version is old (prior to early 2016) and
867  // has not been supporting an accurate summary for several years.
869  Summary = Builder.getSummary();
870  return Cur;
871  }
872 }
873 
875  using namespace support;
876 
877  const unsigned char *Start =
878  (const unsigned char *)DataBuffer->getBufferStart();
879  const unsigned char *Cur = Start;
880  if ((const unsigned char *)DataBuffer->getBufferEnd() - Cur < 24)
882 
883  auto *Header = reinterpret_cast<const IndexedInstrProf::Header *>(Cur);
884  Cur += sizeof(IndexedInstrProf::Header);
885 
886  // Check the magic number.
887  uint64_t Magic = endian::byte_swap<uint64_t, little>(Header->Magic);
890 
891  // Read the version.
892  uint64_t FormatVersion = endian::byte_swap<uint64_t, little>(Header->Version);
893  if (GET_VERSION(FormatVersion) >
896 
897  Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur,
898  /* UseCS */ false);
899  if (FormatVersion & VARIANT_MASK_CSIR_PROF)
900  Cur = readSummary((IndexedInstrProf::ProfVersion)FormatVersion, Cur,
901  /* UseCS */ true);
902 
903  // Read the hash type and start offset.
904  IndexedInstrProf::HashT HashType = static_cast<IndexedInstrProf::HashT>(
905  endian::byte_swap<uint64_t, little>(Header->HashType));
906  if (HashType > IndexedInstrProf::HashT::Last)
908 
909  uint64_t HashOffset = endian::byte_swap<uint64_t, little>(Header->HashOffset);
910 
911  // The rest of the file is an on disk hash table.
912  auto IndexPtr =
913  std::make_unique<InstrProfReaderIndex<OnDiskHashTableImplV3>>(
914  Start + HashOffset, Cur, Start, HashType, FormatVersion);
915 
916  // Load the remapping table now if requested.
917  if (RemappingBuffer) {
918  Remapper = std::make_unique<
920  std::move(RemappingBuffer), *IndexPtr);
921  if (Error E = Remapper->populateRemappings())
922  return E;
923  } else {
924  Remapper = std::make_unique<InstrProfReaderNullRemapper>(*IndexPtr);
925  }
926  Index = std::move(IndexPtr);
927 
928  return success();
929 }
930 
932  if (Symtab.get())
933  return *Symtab.get();
934 
935  std::unique_ptr<InstrProfSymtab> NewSymtab = std::make_unique<InstrProfSymtab>();
936  if (Error E = Index->populateSymtab(*NewSymtab.get())) {
938  }
939 
940  Symtab = std::move(NewSymtab);
941  return *Symtab.get();
942 }
943 
946  uint64_t FuncHash) {
948  Error Err = Remapper->getRecords(FuncName, Data);
949  if (Err)
950  return std::move(Err);
951  // Found it. Look for counters with the right hash.
952  for (unsigned I = 0, E = Data.size(); I < E; ++I) {
953  // Check for a match and fill the vector if there is one.
954  if (Data[I].Hash == FuncHash) {
955  return std::move(Data[I]);
956  }
957  }
959 }
960 
962  uint64_t FuncHash,
963  std::vector<uint64_t> &Counts) {
964  Expected<InstrProfRecord> Record = getInstrProfRecord(FuncName, FuncHash);
965  if (Error E = Record.takeError())
966  return error(std::move(E));
967 
968  Counts = Record.get().Counts;
969  return success();
970 }
971 
974 
975  Error E = Index->getRecords(Data);
976  if (E)
977  return error(std::move(E));
978 
979  Record = Data[RecordIndex++];
980  if (RecordIndex >= Data.size()) {
981  Index->advanceToNextKey();
982  RecordIndex = 0;
983  }
984  return success();
985 }
986 
988  uint64_t NumFuncs = 0;
989  for (const auto &Func : *this) {
990  if (isIRLevelProfile()) {
991  bool FuncIsCS = NamedInstrProfRecord::hasCSFlagInHash(Func.Hash);
992  if (FuncIsCS != IsCS)
993  continue;
994  }
995  Func.accumulateCounts(Sum);
996  ++NumFuncs;
997  }
998  Sum.NumEntries = NumFuncs;
999 }
llvm::coverage::coveragemap_error::success
@ success
MemoryBuffer.h
llvm::IndexedInstrProfReader::getSymtab
InstrProfSymtab & getSymtab() override
Return the PGO symtab.
Definition: InstrProfReader.cpp:931
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:286
llvm::instrprof_error::bad_header
@ bad_header
llvm::RawInstrProfReader
Reader for the raw instrprof binary format from runtime.
Definition: InstrProfReader.h:206
getName
static StringRef getName(Value *V)
Definition: ProvenanceAnalysisEvaluator.cpp:42
llvm::InstrProfReader::success
Error success()
Clear the current error and return a successful one.
Definition: InstrProfReader.h:127
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::IndexedInstrProf::ProfVersion
ProfVersion
Definition: InstrProf.h:964
llvm::handleErrors
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
Definition: Error.h:945
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
offset_type
InstrProfLookupTrait::offset_type offset_type
Definition: InstrProfReader.cpp:588
llvm::IndexedInstrProfReader::hasFormat
static bool hasFormat(const MemoryBuffer &DataBuffer)
Return true if the given buffer is in an indexed instrprof format.
Definition: InstrProfReader.cpp:809
llvm::InstrProfLookupTrait::hash_value_type
uint64_t hash_value_type
Definition: InstrProfReader.h:342
ProfileSummary.h
StringRef.h
llvm::IndexedInstrProf::Summary::Entry::NumBlocks
uint64_t NumBlocks
Number of blocks >= the minumum execution count.
Definition: InstrProf.h:1015
llvm::InstrProfReader::readNextRecord
virtual Error readNextRecord(NamedInstrProfRecord &Record)=0
Read a single record.
llvm::IndexedInstrProf::ComputeHash
uint64_t ComputeHash(StringRef K)
Definition: InstrProf.h:995
llvm::InstrProfReaderIndex::InstrProfReaderIndex
InstrProfReaderIndex(const unsigned char *Buckets, const unsigned char *const Payload, const unsigned char *const Base, IndexedInstrProf::HashT HashType, uint64_t Version)
Definition: InstrProfReader.cpp:680
llvm::RawInstrProfReader64
RawInstrProfReader< uint64_t > RawInstrProfReader64
Definition: InstrProfReader.h:315
llvm::InstrProfSymtab::create
Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:331
Error.h
SwapByteOrder.h
llvm::IndexedInstrProf::Summary::Entry
Definition: InstrProf.h:1011
llvm::InstrProfLookupTrait::data_type
ArrayRef< NamedInstrProfRecord > data_type
Definition: InstrProfReader.h:338
llvm::BitmaskEnumDetail::Underlying
std::underlying_type_t< E > Underlying(E Val)
Check that Val is in range for E, and return Val cast to E's underlying type.
Definition: BitmaskEnum.h:90
DenseMap.h
llvm::StringRef::rsplit
LLVM_NODISCARD std::pair< StringRef, StringRef > rsplit(StringRef Separator) const
Split into two substrings around the last occurrence of a separator string.
Definition: StringRef.h:782
llvm::InstrProfLookupTrait::ComputeHash
hash_value_type ComputeHash(StringRef K)
Definition: InstrProfReader.cpp:583
error
#define error(X)
Definition: SymbolRecordMapping.cpp:14
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
STLExtras.h
ProfileCommon.h
llvm::consumeError
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1045
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:50
llvm::InstrProfRecord
Profiling information for a single function.
Definition: InstrProf.h:691
llvm::StringRef::substr
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:611
llvm::TextInstrProfReader::readHeader
Error readHeader() override
Read the header.
Definition: InstrProfReader.cpp:154
llvm::IndexedInstrProf::Version4
@ Version4
Definition: InstrProf.h:980
llvm::AMDGPU::HSAMD::ValueKind
ValueKind
Value kinds.
Definition: AMDGPUMetadata.h:73
llvm::coverage::Version1
@ Version1
Definition: CoverageMapping.h:994
llvm::all_of
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:1551
llvm::coverage::CurrentVersion
@ CurrentVersion
Definition: CoverageMapping.h:1010
llvm::SymbolRemappingReader
Reader for symbol remapping files.
Definition: SymbolRemappingReader.h:97
ptrdiff_t
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MemoryBuffer::getBufferSize
size_t getBufferSize() const
Definition: MemoryBuffer.h:67
llvm::errorCodeToError
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:87
InfoType
InfoType
FunctionInfo information type that is used to encode the optional data that is associated with a Func...
Definition: FunctionInfo.cpp:21
setupMemoryBuffer
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Path)
Definition: InstrProfReader.cpp:42
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:481
llvm::ErrorOr::getError
std::error_code getError() const
Definition: ErrorOr.h:153
llvm::InstrProfReaderItaniumRemapper::InstrProfReaderItaniumRemapper
InstrProfReaderItaniumRemapper(std::unique_ptr< MemoryBuffer > RemapBuffer, InstrProfReaderIndex< HashTableImpl > &Underlying)
Definition: InstrProfReader.cpp:712
CHECK_LINE_END
#define CHECK_LINE_END(Line)
InstrProf.h
llvm::instrprof_error::truncated
@ truncated
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::IndexedInstrProfReader::getFunctionCounts
Error getFunctionCounts(StringRef FuncName, uint64_t FuncHash, std::vector< uint64_t > &Counts)
Fill Counts with the profile data for the given function name.
Definition: InstrProfReader.cpp:961
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:991
llvm::TextInstrProfReader::readNextRecord
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
Definition: InstrProfReader.cpp:253
c
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int c
Definition: README.txt:418
llvm::IndexedInstrProf::Header
Definition: InstrProf.h:999
llvm::instrprof_error::bad_magic
@ bad_magic
llvm::instrprof_error::unsupported_version
@ unsupported_version
llvm::StringRef::getAsInteger
std::enable_if_t< std::numeric_limits< T >::is_signed, bool > getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:510
llvm::InstrProfReader::Symtab
std::unique_ptr< InstrProfSymtab > Symtab
Definition: InstrProfReader.h:114
RoundUp
static size_t RoundUp(size_t size, size_t align)
Definition: InstrProfReader.cpp:530
llvm::IndexedInstrProfReader::readHeader
Error readHeader() override
Read the file header.
Definition: InstrProfReader.cpp:874
llvm::instrprof_error::too_large
@ too_large
llvm::InstrProfError::take
static instrprof_error take(Error E)
Consume an Error and return the raw enum value contained within it.
Definition: InstrProf.h:327
llvm::SmallString< 256 >
llvm::Twine::str
std::string str() const
Return the twine contents as a std::string.
Definition: Twine.cpp:17
llvm::InstrProfReader::error
Error error(instrprof_error Err)
Set the current error and return same.
Definition: InstrProfReader.h:117
llvm::sys::getSwappedBytes
unsigned char getSwappedBytes(unsigned char C)
Definition: SwapByteOrder.h:103
llvm::instrprof_error::unsupported_hash_type
@ unsupported_hash_type
llvm::IndexedInstrProfReader::getInstrProfRecord
Expected< InstrProfRecord > getInstrProfRecord(StringRef FuncName, uint64_t FuncHash)
Return the NamedInstrProfRecord associated with FuncName and FuncHash.
Definition: InstrProfReader.cpp:945
llvm::InstrProfReaderItaniumRemapper::extractName
static StringRef extractName(StringRef Name)
Extract the original function name from a PGO function name.
Definition: InstrProfReader.cpp:719
InstrProfReader.h
llvm::CountSumOrPercent::NumEntries
uint64_t NumEntries
Definition: InstrProf.h:598
llvm::InstrProfReaderItaniumRemapper::getRecords
Error getRecords(StringRef FuncName, ArrayRef< NamedInstrProfRecord > &Data) override
Definition: InstrProfReader.cpp:759
SymbolRemappingReader.h
initializeReader
static Error initializeReader(InstrProfReader &Reader)
Definition: InstrProfReader.cpp:50
llvm::count
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition: STLExtras.h:1634
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
uint64_t
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::StringRef::end
iterator end() const
Definition: StringRef.h:130
llvm::IndexedInstrProfReader
Reader for the indexed binary instrprof format.
Definition: InstrProfReader.h:458
llvm::IndexedInstrProf::Summary::getSize
static uint32_t getSize(uint32_t NumSumFields, uint32_t NumCutoffEntries)
Definition: InstrProf.h:1048
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::DenseMap
Definition: DenseMap.h:714
ErrorOr.h
llvm::InstrProfSummaryBuilder
Definition: ProfileCommon.h:74
llvm::MemoryBuffer::getFileOrSTDIN
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFileOrSTDIN(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true)
Open the specified file as a MemoryBuffer, or open stdin if the Filename is "-".
Definition: MemoryBuffer.cpp:144
llvm::CountSumOrPercent
Definition: InstrProf.h:597
llvm::TextInstrProfReader
Reader for the simple text based instrprof format.
Definition: InstrProfReader.h:159
llvm::instrprof_error::empty_raw_profile
@ empty_raw_profile
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::line_iterator::is_at_end
bool is_at_end() const
Return true if we're an "end" iterator or have reached EOF.
Definition: LineIterator.h:63
StringExtras.h
Magic
const char Magic[]
Definition: Archive.cpp:41
ArrayRef.h
llvm::move
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1609
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
llvm::instrprof_error::unknown_function
@ unknown_function
llvm::IndexedInstrProf::HashT::Last
@ Last
llvm::instrprof_error::unrecognized_format
@ unrecognized_format
llvm::IndexedInstrProf::allocSummary
std::unique_ptr< Summary > allocSummary(uint32_t TotalSize)
Definition: InstrProf.h:1088
llvm::Record
Definition: Record.h:1472
llvm::IndexedInstrProfReader::create
static Expected< std::unique_ptr< IndexedInstrProfReader > > create(const Twine &Path, const Twine &RemappingPath="")
Factory method to create an indexed reader.
Definition: InstrProfReader.cpp:93
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:650
llvm::size
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1532
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::InstrProfSymtab::isExternalSymbol
static bool isExternalSymbol(const StringRef &Symbol)
True if Symbol is the value used to represent external symbols.
Definition: InstrProf.h:511
llvm::min
Expected< ExpressionValue > min(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:357
llvm::InstrProfReaderIndex
Definition: InstrProfReader.h:401
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::IndexedInstrProf::Summary::Entry::Cutoff
uint64_t Cutoff
The required percentile of total execution count.
Definition: InstrProf.h:1012
llvm::IndexedInstrProf::Magic
const uint64_t Magic
Definition: InstrProf.h:962
llvm::IndexedInstrProf::HashT
HashT
Definition: InstrProf.h:949
llvm::NamedInstrProfRecord::hasCSFlagInHash
static bool hasCSFlagInHash(uint64_t FuncHash)
Definition: InstrProf.h:860
llvm::Expected::get
reference get()
Returns a reference to the stored T value.
Definition: Error.h:569
uint32_t
llvm::instrprof_error::eof
@ eof
llvm::IndexedInstrProf::Summary::NumCutoffEntries
uint64_t NumCutoffEntries
Definition: InstrProf.h:1041
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::RawInstrProfReader::readHeader
Error readHeader() override
Read the header. Required before reading first record.
Definition: InstrProfReader.cpp:312
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::ProfileSummary::PSK_CSInstr
@ PSK_CSInstr
Definition: ProfileSummary.h:47
llvm::RawInstrProfReader::hasFormat
static bool hasFormat(const MemoryBuffer &DataBuffer)
Definition: InstrProfReader.cpp:302
llvm::instrprof_error::hash_mismatch
@ hash_mismatch
llvm::SummaryEntryVector
std::vector< ProfileSummaryEntry > SummaryEntryVector
Definition: ProfileSummary.h:43
llvm::InstrProfReaderItaniumRemapper
A remapper that applies remappings based on a symbol remapping file.
Definition: InstrProfReader.h:398
VP_READ_ADVANCE
#define VP_READ_ADVANCE(Val)
llvm::InstrProfLookupTrait::ReadData
data_type ReadData(StringRef K, const unsigned char *D, offset_type N)
Definition: InstrProfReader.cpp:604
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::MemoryBuffer::getBufferStart
const char * getBufferStart() const
Definition: MemoryBuffer.h:65
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
std
Definition: BitVector.h:838
llvm::InstrProfSymtab
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:414
llvm::InstrProfReader::accumulateCounts
void accumulateCounts(CountSumOrPercent &Sum, bool IsCS)
Compute the sum of counts and return in Sum.
Definition: InstrProfReader.cpp:987
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::InstrProfReaderItaniumRemapper::reconstituteName
static void reconstituteName(StringRef OrigName, StringRef ExtractedName, StringRef Replacement, SmallVectorImpl< char > &Out)
Given a mangled name extracted from a PGO function name, and a new form for that mangled name,...
Definition: InstrProfReader.cpp:735
llvm::IndexedInstrProf::Summary
Definition: InstrProf.h:1010
READ_NUM
#define READ_NUM(Str, Dst)
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::InstrProfReaderRemapper
Name matcher supporting fuzzy matching of symbol names to names in profiles.
Definition: InstrProfReader.h:449
llvm::InstrProfReader::readHeader
virtual Error readHeader()=0
Read the header. Required before reading first record.
llvm::RawInstrProfReader::readNextRecord
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
Definition: InstrProfReader.cpp:503
llvm::InstrProfReaderIndexBase
Definition: InstrProfReader.h:374
llvm::RawInstrProf::ProfileData
Definition: InstrProf.h:1125
llvm::IndexedInstrProfReader::readNextRecord
Error readNextRecord(NamedInstrProfRecord &Record) override
Read a single record.
Definition: InstrProfReader.cpp:972
llvm::makeArrayRef
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:476
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:599
llvm::RawInstrProfReader::printBinaryIds
Error printBinaryIds(raw_ostream &OS) override
Print binary ids on stream OS.
Definition: InstrProfReader.cpp:535
align
mov r0 ldr L5 sub r0 lr needed for prologue ldmia ip add bx lr r2 The last stmia stores r2 into the address passed in there is one additional stmia that stores and r2 to some stack location The store is dead The llvm gcc generated code looks like align
Definition: README.txt:236
llvm::InstrProfSymtab::mapAddress
void mapAddress(uint64_t Addr, uint64_t MD5Val)
Map a function address to its name's MD5 hash.
Definition: InstrProf.h:489
llvm::ErrorOr::get
reference get()
Definition: ErrorOr.h:150
llvm::TextInstrProfReader::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if the given buffer is in text instrprof format.
Definition: InstrProfReader.cpp:141
llvm::ProfileSummary::PSK_Instr
@ PSK_Instr
Definition: ProfileSummary.h:47
N
#define N
llvm::ErrorOr
Represents either an error or a value T.
Definition: ErrorOr.h:56
llvm::coverage::Version2
@ Version2
Definition: CoverageMapping.h:998
llvm::max
Align max(MaybeAlign Lhs, Align Rhs)
Definition: Alignment.h:340
support
Reimplement select in terms of SEL *We would really like to support but we need to prove that the add doesn t need to overflow between the two bit chunks *Implement pre post increment support(e.g. PR935) *Implement smarter const ant generation for binops with large immediates. A few ARMv6T2 ops should be pattern matched
Definition: README.txt:10
llvm::NamedInstrProfRecord
Definition: InstrProf.h:848
llvm::SmallVectorImpl< char >
llvm::instrprof_error::malformed
@ malformed
llvm::RawInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1109
llvm::RawInstrProf::Header
Definition: InstrProf.h:1134
llvm::InstrProfLookupTrait::offset_type
uint64_t offset_type
Definition: InstrProfReader.h:343
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::InstrProfReaderItaniumRemapper::populateRemappings
Error populateRemappings() override
Definition: InstrProfReader.cpp:744
llvm::SmallVectorImpl::reserve
void reserve(size_type N)
Definition: SmallVector.h:624
Endian.h
llvm::StringRef::begin
iterator begin() const
Definition: StringRef.h:128
llvm::InstrProfReader::create
static Expected< std::unique_ptr< InstrProfReader > > create(const Twine &Path)
Factory method to create an appropriately typed reader for the given instrprof file.
Definition: InstrProfReader.cpp:55
llvm::IndexedInstrProf::Summary::NumSummaryFields
uint64_t NumSummaryFields
Definition: InstrProf.h:1039
llvm::IndexedInstrProf::Summary::Entry::MinBlockCount
uint64_t MinBlockCount
The minimum execution count for this percentile.
Definition: InstrProf.h:1014
llvm::ProfileSummaryBuilder::DefaultCutoffs
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
Definition: ProfileCommon.h:65
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::InstrProfReader
Base class and interface for reading profiling data of any known instrprof format.
Definition: InstrProfReader.h:72
llvm::RawInstrProfReader32
RawInstrProfReader< uint32_t > RawInstrProfReader32
Definition: InstrProfReader.h:314
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::InstrProfIterator::InstrProfIterator
InstrProfIterator()=default
llvm::InstrProfLookupTrait::readValueProfilingData
bool readValueProfilingData(const unsigned char *&D, const unsigned char *const End)
Definition: InstrProfReader.cpp:590
llvm::InstrProfReaderIndex::getRecords
Error getRecords(ArrayRef< NamedInstrProfRecord > &Data) override
Definition: InstrProfReader.cpp:666
llvm::SmallVectorImpl::insert
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:773