LLVM  16.0.0git
InstrProfWriter.cpp
Go to the documentation of this file.
1 //===- InstrProfWriter.cpp - Instrumented profiling writer ----------------===//
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 writing profiling data for clang's
10 // instrumentation based PGO and coverage.
11 //
12 //===----------------------------------------------------------------------===//
13 
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/ADT/StringRef.h"
17 #include "llvm/IR/ProfileSummary.h"
21 #include "llvm/Support/Endian.h"
23 #include "llvm/Support/Error.h"
27 #include <cstdint>
28 #include <memory>
29 #include <string>
30 #include <tuple>
31 #include <utility>
32 #include <vector>
33 
34 using namespace llvm;
35 
36 // A struct to define how the data stream should be patched. For Indexed
37 // profiling, only uint64_t data type is needed.
38 struct PatchItem {
39  uint64_t Pos; // Where to patch.
40  uint64_t *D; // Pointer to an array of source data.
41  int N; // Number of elements in \c D array.
42 };
43 
44 namespace llvm {
45 
46 // A wrapper class to abstract writer stream with support of bytes
47 // back patching.
48 class ProfOStream {
49 public:
51  : IsFDOStream(true), OS(FD), LE(FD, support::little) {}
53  : IsFDOStream(false), OS(STR), LE(STR, support::little) {}
54 
55  uint64_t tell() { return OS.tell(); }
56  void write(uint64_t V) { LE.write<uint64_t>(V); }
57 
58  // \c patch can only be called when all data is written and flushed.
59  // For raw_string_ostream, the patch is done on the target string
60  // directly and it won't be reflected in the stream's internal buffer.
61  void patch(PatchItem *P, int NItems) {
62  using namespace support;
63 
64  if (IsFDOStream) {
65  raw_fd_ostream &FDOStream = static_cast<raw_fd_ostream &>(OS);
66  const uint64_t LastPos = FDOStream.tell();
67  for (int K = 0; K < NItems; K++) {
68  FDOStream.seek(P[K].Pos);
69  for (int I = 0; I < P[K].N; I++)
70  write(P[K].D[I]);
71  }
72  // Reset the stream to the last position after patching so that users
73  // don't accidentally overwrite data. This makes it consistent with
74  // the string stream below which replaces the data directly.
75  FDOStream.seek(LastPos);
76  } else {
77  raw_string_ostream &SOStream = static_cast<raw_string_ostream &>(OS);
78  std::string &Data = SOStream.str(); // with flush
79  for (int K = 0; K < NItems; K++) {
80  for (int I = 0; I < P[K].N; I++) {
81  uint64_t Bytes = endian::byte_swap<uint64_t, little>(P[K].D[I]);
82  Data.replace(P[K].Pos + I * sizeof(uint64_t), sizeof(uint64_t),
83  (const char *)&Bytes, sizeof(uint64_t));
84  }
85  }
86  }
87  }
88 
89  // If \c OS is an instance of \c raw_fd_ostream, this field will be
90  // true. Otherwise, \c OS will be an raw_string_ostream.
94 };
95 
97 public:
100 
103 
106 
107  support::endianness ValueProfDataEndianness = support::little;
110 
111  InstrProfRecordWriterTrait() = default;
112 
115  }
116 
117  static std::pair<offset_type, offset_type>
119  using namespace support;
120 
121  endian::Writer LE(Out, little);
122 
123  offset_type N = K.size();
124  LE.write<offset_type>(N);
125 
126  offset_type M = 0;
127  for (const auto &ProfileData : *V) {
128  const InstrProfRecord &ProfRecord = ProfileData.second;
129  M += sizeof(uint64_t); // The function hash
130  M += sizeof(uint64_t); // The size of the Counts vector
131  M += ProfRecord.Counts.size() * sizeof(uint64_t);
132 
133  // Value data
134  M += ValueProfData::getSize(ProfileData.second);
135  }
136  LE.write<offset_type>(M);
137 
138  return std::make_pair(N, M);
139  }
140 
142  Out.write(K.data(), N);
143  }
144 
146  using namespace support;
147 
148  endian::Writer LE(Out, little);
149  for (const auto &ProfileData : *V) {
150  const InstrProfRecord &ProfRecord = ProfileData.second;
151  if (NamedInstrProfRecord::hasCSFlagInHash(ProfileData.first))
152  CSSummaryBuilder->addRecord(ProfRecord);
153  else
154  SummaryBuilder->addRecord(ProfRecord);
155 
156  LE.write<uint64_t>(ProfileData.first); // Function hash
157  LE.write<uint64_t>(ProfRecord.Counts.size());
158  for (uint64_t I : ProfRecord.Counts)
159  LE.write<uint64_t>(I);
160 
161  // Write value data
162  std::unique_ptr<ValueProfData> VDataPtr =
163  ValueProfData::serializeFrom(ProfileData.second);
164  uint32_t S = VDataPtr->getSize();
165  VDataPtr->swapBytesFromHost(ValueProfDataEndianness);
166  Out.write((const char *)VDataPtr.get(), S);
167  }
168  }
169 };
170 
171 } // end namespace llvm
172 
174  : Sparse(Sparse), InfoObj(new InstrProfRecordWriterTrait()) {}
175 
177 
178 // Internal interface for testing purpose only.
182 }
183 
185  this->Sparse = Sparse;
186 }
187 
189  function_ref<void(Error)> Warn) {
190  auto Name = I.Name;
191  auto Hash = I.Hash;
192  addRecord(Name, Hash, std::move(I), Weight, Warn);
193 }
194 
196  OverlapStats &Overlap,
197  OverlapStats &FuncLevelOverlap,
198  const OverlapFuncFilters &FuncFilter) {
199  auto Name = Other.Name;
200  auto Hash = Other.Hash;
201  Other.accumulateCounts(FuncLevelOverlap.Test);
202  if (FunctionData.find(Name) == FunctionData.end()) {
203  Overlap.addOneUnique(FuncLevelOverlap.Test);
204  return;
205  }
206  if (FuncLevelOverlap.Test.CountSum < 1.0f) {
207  Overlap.Overlap.NumEntries += 1;
208  return;
209  }
210  auto &ProfileDataMap = FunctionData[Name];
211  bool NewFunc;
213  std::tie(Where, NewFunc) =
214  ProfileDataMap.insert(std::make_pair(Hash, InstrProfRecord()));
215  if (NewFunc) {
216  Overlap.addOneMismatch(FuncLevelOverlap.Test);
217  return;
218  }
219  InstrProfRecord &Dest = Where->second;
220 
221  uint64_t ValueCutoff = FuncFilter.ValueCutoff;
222  if (!FuncFilter.NameFilter.empty() && Name.contains(FuncFilter.NameFilter))
223  ValueCutoff = 0;
224 
225  Dest.overlap(Other, Overlap, FuncLevelOverlap, ValueCutoff);
226 }
227 
229  InstrProfRecord &&I, uint64_t Weight,
230  function_ref<void(Error)> Warn) {
231  auto &ProfileDataMap = FunctionData[Name];
232 
233  bool NewFunc;
235  std::tie(Where, NewFunc) =
236  ProfileDataMap.insert(std::make_pair(Hash, InstrProfRecord()));
237  InstrProfRecord &Dest = Where->second;
238 
239  auto MapWarn = [&](instrprof_error E) {
240  Warn(make_error<InstrProfError>(E));
241  };
242 
243  if (NewFunc) {
244  // We've never seen a function with this name and hash, add it.
245  Dest = std::move(I);
246  if (Weight > 1)
247  Dest.scale(Weight, 1, MapWarn);
248  } else {
249  // We're updating a function we've seen before.
250  Dest.merge(I, Weight, MapWarn);
251  }
252 
253  Dest.sortValueData();
254 }
255 
258  auto Result = MemProfRecordData.insert({Id, Record});
259  // If we inserted a new record then we are done.
260  if (Result.second) {
261  return;
262  }
263  memprof::IndexedMemProfRecord &Existing = Result.first->second;
264  Existing.merge(Record);
265 }
266 
268  const memprof::Frame &Frame,
269  function_ref<void(Error)> Warn) {
270  auto Result = MemProfFrameData.insert({Id, Frame});
271  // If a mapping already exists for the current frame id and it does not
272  // match the new mapping provided then reset the existing contents and bail
273  // out. We don't support the merging of memprof data whose Frame -> Id
274  // mapping across profiles is inconsistent.
275  if (!Result.second && Result.first->second != Frame) {
276  Warn(make_error<InstrProfError>(instrprof_error::malformed,
277  "frame to id mapping mismatch"));
278  return false;
279  }
280  return true;
281 }
282 
284  function_ref<void(Error)> Warn) {
285  for (auto &I : IPW.FunctionData)
286  for (auto &Func : I.getValue())
287  addRecord(I.getKey(), Func.first, std::move(Func.second), 1, Warn);
288 
289  MemProfFrameData.reserve(IPW.MemProfFrameData.size());
290  for (auto &I : IPW.MemProfFrameData) {
291  // If we weren't able to add the frame mappings then it doesn't make sense
292  // to try to merge the records from this profile.
293  if (!addMemProfFrame(I.first, I.second, Warn))
294  return;
295  }
296 
297  MemProfRecordData.reserve(IPW.MemProfRecordData.size());
298  for (auto &I : IPW.MemProfRecordData) {
299  addMemProfRecord(I.first, I.second);
300  }
301 }
302 
303 bool InstrProfWriter::shouldEncodeData(const ProfilingData &PD) {
304  if (!Sparse)
305  return true;
306  for (const auto &Func : PD) {
307  const InstrProfRecord &IPR = Func.second;
308  if (llvm::any_of(IPR.Counts, [](uint64_t Count) { return Count > 0; }))
309  return true;
310  }
311  return false;
312 }
313 
314 static void setSummary(IndexedInstrProf::Summary *TheSummary,
315  ProfileSummary &PS) {
316  using namespace IndexedInstrProf;
317 
318  const std::vector<ProfileSummaryEntry> &Res = PS.getDetailedSummary();
319  TheSummary->NumSummaryFields = Summary::NumKinds;
320  TheSummary->NumCutoffEntries = Res.size();
322  TheSummary->set(Summary::MaxBlockCount, PS.getMaxCount());
324  TheSummary->set(Summary::TotalBlockCount, PS.getTotalCount());
325  TheSummary->set(Summary::TotalNumBlocks, PS.getNumCounts());
327  for (unsigned I = 0; I < Res.size(); I++)
328  TheSummary->setEntry(I, Res[I]);
329 }
330 
331 Error InstrProfWriter::writeImpl(ProfOStream &OS) {
332  using namespace IndexedInstrProf;
333 
335 
337  InfoObj->SummaryBuilder = &ISB;
339  InfoObj->CSSummaryBuilder = &CSISB;
340 
341  // Populate the hash table generator.
342  for (const auto &I : FunctionData)
343  if (shouldEncodeData(I.getValue()))
344  Generator.insert(I.getKey(), &I.getValue());
345 
346  // Write the header.
350  if (static_cast<bool>(ProfileKind & InstrProfKind::IRInstrumentation))
351  Header.Version |= VARIANT_MASK_IR_PROF;
352  if (static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive))
353  Header.Version |= VARIANT_MASK_CSIR_PROF;
354  if (static_cast<bool>(ProfileKind &
356  Header.Version |= VARIANT_MASK_INSTR_ENTRY;
357  if (static_cast<bool>(ProfileKind & InstrProfKind::SingleByteCoverage))
358  Header.Version |= VARIANT_MASK_BYTE_COVERAGE;
359  if (static_cast<bool>(ProfileKind & InstrProfKind::FunctionEntryOnly))
360  Header.Version |= VARIANT_MASK_FUNCTION_ENTRY_ONLY;
361  if (static_cast<bool>(ProfileKind & InstrProfKind::MemProf))
362  Header.Version |= VARIANT_MASK_MEMPROF;
363 
364  Header.Unused = 0;
365  Header.HashType = static_cast<uint64_t>(IndexedInstrProf::HashType);
366  Header.HashOffset = 0;
367  Header.MemProfOffset = 0;
368  int N = sizeof(IndexedInstrProf::Header) / sizeof(uint64_t);
369 
370  // Only write out all the fields except 'HashOffset' and 'MemProfOffset'. We
371  // need to remember the offset of these fields to allow back patching later.
372  for (int I = 0; I < N - 2; I++)
373  OS.write(reinterpret_cast<uint64_t *>(&Header)[I]);
374 
375  // Save the location of Header.HashOffset field in \c OS.
376  uint64_t HashTableStartFieldOffset = OS.tell();
377  // Reserve the space for HashOffset field.
378  OS.write(0);
379 
380  // Save the location of MemProf profile data. This is stored in two parts as
381  // the schema and as a separate on-disk chained hashtable.
382  uint64_t MemProfSectionOffset = OS.tell();
383  // Reserve space for the MemProf table field to be patched later if this
384  // profile contains memory profile information.
385  OS.write(0);
386 
387  // Reserve space to write profile summary data.
389  uint32_t SummarySize = Summary::getSize(Summary::NumKinds, NumEntries);
390  // Remember the summary offset.
391  uint64_t SummaryOffset = OS.tell();
392  for (unsigned I = 0; I < SummarySize / sizeof(uint64_t); I++)
393  OS.write(0);
394  uint64_t CSSummaryOffset = 0;
395  uint64_t CSSummarySize = 0;
396  if (static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive)) {
397  CSSummaryOffset = OS.tell();
398  CSSummarySize = SummarySize / sizeof(uint64_t);
399  for (unsigned I = 0; I < CSSummarySize; I++)
400  OS.write(0);
401  }
402 
403  // Write the hash table.
404  uint64_t HashTableStart = Generator.Emit(OS.OS, *InfoObj);
405 
406  // Write the MemProf profile data if we have it. This includes a simple schema
407  // with the format described below followed by the hashtable:
408  // uint64_t RecordTableOffset = RecordTableGenerator.Emit
409  // uint64_t FramePayloadOffset = Stream offset before emitting the frame table
410  // uint64_t FrameTableOffset = FrameTableGenerator.Emit
411  // uint64_t Num schema entries
412  // uint64_t Schema entry 0
413  // uint64_t Schema entry 1
414  // ....
415  // uint64_t Schema entry N - 1
416  // OnDiskChainedHashTable MemProfRecordData
417  // OnDiskChainedHashTable MemProfFrameData
418  uint64_t MemProfSectionStart = 0;
419  if (static_cast<bool>(ProfileKind & InstrProfKind::MemProf)) {
420  MemProfSectionStart = OS.tell();
421  OS.write(0ULL); // Reserve space for the memprof record table offset.
422  OS.write(0ULL); // Reserve space for the memprof frame payload offset.
423  OS.write(0ULL); // Reserve space for the memprof frame table offset.
424 
426  OS.write(static_cast<uint64_t>(Schema.size()));
427  for (const auto Id : Schema) {
428  OS.write(static_cast<uint64_t>(Id));
429  }
430 
431  auto RecordWriter = std::make_unique<memprof::RecordWriterTrait>();
432  RecordWriter->Schema = &Schema;
434  RecordTableGenerator;
435  for (auto &I : MemProfRecordData) {
436  // Insert the key (func hash) and value (memprof record).
437  RecordTableGenerator.insert(I.first, I.second);
438  }
439 
440  uint64_t RecordTableOffset =
441  RecordTableGenerator.Emit(OS.OS, *RecordWriter);
442 
443  uint64_t FramePayloadOffset = OS.tell();
444 
445  auto FrameWriter = std::make_unique<memprof::FrameWriterTrait>();
447  FrameTableGenerator;
448  for (auto &I : MemProfFrameData) {
449  // Insert the key (frame id) and value (frame contents).
450  FrameTableGenerator.insert(I.first, I.second);
451  }
452 
453  uint64_t FrameTableOffset = FrameTableGenerator.Emit(OS.OS, *FrameWriter);
454 
455  PatchItem PatchItems[] = {
456  {MemProfSectionStart, &RecordTableOffset, 1},
457  {MemProfSectionStart + sizeof(uint64_t), &FramePayloadOffset, 1},
458  {MemProfSectionStart + 2 * sizeof(uint64_t), &FrameTableOffset, 1},
459  };
460  OS.patch(PatchItems, 3);
461  }
462 
463  // Allocate space for data to be serialized out.
464  std::unique_ptr<IndexedInstrProf::Summary> TheSummary =
465  IndexedInstrProf::allocSummary(SummarySize);
466  // Compute the Summary and copy the data to the data
467  // structure to be serialized out (to disk or buffer).
468  std::unique_ptr<ProfileSummary> PS = ISB.getSummary();
469  setSummary(TheSummary.get(), *PS);
470  InfoObj->SummaryBuilder = nullptr;
471 
472  // For Context Sensitive summary.
473  std::unique_ptr<IndexedInstrProf::Summary> TheCSSummary = nullptr;
474  if (static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive)) {
475  TheCSSummary = IndexedInstrProf::allocSummary(SummarySize);
476  std::unique_ptr<ProfileSummary> CSPS = CSISB.getSummary();
477  setSummary(TheCSSummary.get(), *CSPS);
478  }
479  InfoObj->CSSummaryBuilder = nullptr;
480 
481  // Now do the final patch:
482  PatchItem PatchItems[] = {
483  // Patch the Header.HashOffset field.
484  {HashTableStartFieldOffset, &HashTableStart, 1},
485  // Patch the Header.MemProfOffset (=0 for profiles without MemProf data).
486  {MemProfSectionOffset, &MemProfSectionStart, 1},
487  // Patch the summary data.
488  {SummaryOffset, reinterpret_cast<uint64_t *>(TheSummary.get()),
489  (int)(SummarySize / sizeof(uint64_t))},
490  {CSSummaryOffset, reinterpret_cast<uint64_t *>(TheCSSummary.get()),
491  (int)CSSummarySize}};
492 
493  OS.patch(PatchItems, sizeof(PatchItems) / sizeof(*PatchItems));
494 
495  for (const auto &I : FunctionData)
496  for (const auto &F : I.getValue())
497  if (Error E = validateRecord(F.second))
498  return E;
499 
500  return Error::success();
501 }
502 
504  // Write the hash table.
505  ProfOStream POS(OS);
506  return writeImpl(POS);
507 }
508 
509 std::unique_ptr<MemoryBuffer> InstrProfWriter::writeBuffer() {
510  std::string Data;
512  ProfOStream POS(OS);
513  // Write the hash table.
514  if (Error E = writeImpl(POS))
515  return nullptr;
516  // Return this in an aligned memory buffer.
518 }
519 
520 static const char *ValueProfKindStr[] = {
521 #define VALUE_PROF_KIND(Enumerator, Value, Descr) #Enumerator,
523 };
524 
526  for (uint32_t VK = 0; VK <= IPVK_Last; VK++) {
527  uint32_t NS = Func.getNumValueSites(VK);
528  if (!NS)
529  continue;
530  for (uint32_t S = 0; S < NS; S++) {
531  uint32_t ND = Func.getNumValueDataForSite(VK, S);
532  std::unique_ptr<InstrProfValueData[]> VD = Func.getValueForSite(VK, S);
533  bool WasZero = false;
534  for (uint32_t I = 0; I < ND; I++)
535  if ((VK != IPVK_IndirectCallTarget) && (VD[I].Value == 0)) {
536  if (WasZero)
537  return make_error<InstrProfError>(instrprof_error::invalid_prof);
538  WasZero = true;
539  }
540  }
541  }
542 
543  return Error::success();
544 }
545 
547  const InstrProfRecord &Func,
548  InstrProfSymtab &Symtab,
549  raw_fd_ostream &OS) {
550  OS << Name << "\n";
551  OS << "# Func Hash:\n" << Hash << "\n";
552  OS << "# Num Counters:\n" << Func.Counts.size() << "\n";
553  OS << "# Counter Values:\n";
554  for (uint64_t Count : Func.Counts)
555  OS << Count << "\n";
556 
557  uint32_t NumValueKinds = Func.getNumValueKinds();
558  if (!NumValueKinds) {
559  OS << "\n";
560  return;
561  }
562 
563  OS << "# Num Value Kinds:\n" << Func.getNumValueKinds() << "\n";
564  for (uint32_t VK = 0; VK < IPVK_Last + 1; VK++) {
565  uint32_t NS = Func.getNumValueSites(VK);
566  if (!NS)
567  continue;
568  OS << "# ValueKind = " << ValueProfKindStr[VK] << ":\n" << VK << "\n";
569  OS << "# NumValueSites:\n" << NS << "\n";
570  for (uint32_t S = 0; S < NS; S++) {
571  uint32_t ND = Func.getNumValueDataForSite(VK, S);
572  OS << ND << "\n";
573  std::unique_ptr<InstrProfValueData[]> VD = Func.getValueForSite(VK, S);
574  for (uint32_t I = 0; I < ND; I++) {
575  if (VK == IPVK_IndirectCallTarget)
576  OS << Symtab.getFuncNameOrExternalSymbol(VD[I].Value) << ":"
577  << VD[I].Count << "\n";
578  else
579  OS << VD[I].Value << ":" << VD[I].Count << "\n";
580  }
581  }
582  }
583 
584  OS << "\n";
585 }
586 
588  // Check CS first since it implies an IR level profile.
589  if (static_cast<bool>(ProfileKind & InstrProfKind::ContextSensitive))
590  OS << "# CSIR level Instrumentation Flag\n:csir\n";
591  else if (static_cast<bool>(ProfileKind & InstrProfKind::IRInstrumentation))
592  OS << "# IR level Instrumentation Flag\n:ir\n";
593 
594  if (static_cast<bool>(ProfileKind &
596  OS << "# Always instrument the function entry block\n:entry_first\n";
597  InstrProfSymtab Symtab;
598 
600  using RecordType = std::pair<StringRef, FuncPair>;
601  SmallVector<RecordType, 4> OrderedFuncData;
602 
603  for (const auto &I : FunctionData) {
604  if (shouldEncodeData(I.getValue())) {
605  if (Error E = Symtab.addFuncName(I.getKey()))
606  return E;
607  for (const auto &Func : I.getValue())
608  OrderedFuncData.push_back(std::make_pair(I.getKey(), Func));
609  }
610  }
611 
612  llvm::sort(OrderedFuncData, [](const RecordType &A, const RecordType &B) {
613  return std::tie(A.first, A.second.first) <
614  std::tie(B.first, B.second.first);
615  });
616 
617  for (const auto &record : OrderedFuncData) {
618  const StringRef &Name = record.first;
619  const FuncPair &Func = record.second;
620  writeRecordInText(Name, Func.first, Func.second, Symtab, OS);
621  }
622 
623  for (const auto &record : OrderedFuncData) {
624  const FuncPair &Func = record.second;
625  if (Error E = validateRecord(Func.second))
626  return E;
627  }
628 
629  return Error::success();
630 }
MemoryBuffer.h
llvm::raw_ostream::tell
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:134
llvm::InstrProfWriter::writeText
Error writeText(raw_fd_ostream &OS)
Write the profile in text format to OS.
Definition: InstrProfWriter.cpp:587
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::msgpack::Endianness
constexpr support::endianness Endianness
The endianness of all multi-byte encoded values in MessagePack.
Definition: MsgPack.h:24
llvm::memprof::IndexedMemProfRecord
Definition: MemProf.h:323
llvm::InstrProfKind::FunctionEntryInstrumentation
@ FunctionEntryInstrumentation
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::InstrProfKind::FunctionEntryOnly
@ FunctionEntryOnly
llvm::IndexedInstrProf::Header::Version
uint64_t Version
Definition: InstrProf.h:1066
llvm::InstrProfWriter::write
Error write(raw_fd_ostream &OS)
Write the profile to OS.
Definition: InstrProfWriter.cpp:503
llvm::OnDiskChainedHashTableGenerator
Generates an on disk hash table.
Definition: OnDiskHashTable.h:59
ProfileSummary.h
StringRef.h
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::raw_string_ostream
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:628
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1182
llvm::IndexedInstrProf::ComputeHash
uint64_t ComputeHash(StringRef K)
Definition: InstrProf.h:1060
llvm::FunctionLoweringInfo::StatepointRelocationRecord
Helper object to track which of three possible relocation mechanisms are used for a particular value ...
Definition: FunctionLoweringInfo.h:95
llvm::InstrProfKind::ContextSensitive
@ ContextSensitive
llvm::memprof::PortableMemInfoBlock::getSchema
static MemProfSchema getSchema()
Definition: MemProf.h:101
llvm::ProfOStream::write
void write(uint64_t V)
Definition: InstrProfWriter.cpp:56
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::SmallDenseMap
Definition: DenseMap.h:880
Error.h
true
basic Basic Alias true
Definition: BasicAliasAnalysis.cpp:1877
llvm::DenseMapIterator
Definition: DenseMap.h:57
llvm::IndexedInstrProf::Summary::NumKinds
@ NumKinds
Definition: InstrProf.h:1115
llvm::OverlapStats
Definition: InstrProf.h:650
llvm::InstrProfRecord::overlap
void overlap(InstrProfRecord &Other, OverlapStats &Overlap, OverlapStats &FuncLevelOverlap, uint64_t ValueCutoff)
Compute the overlap b/w this IntrprofRecord and Other.
Definition: InstrProf.cpp:604
llvm::InstrProfRecordWriterTrait::CSSummaryBuilder
InstrProfSummaryBuilder * CSSummaryBuilder
Definition: InstrProfWriter.cpp:109
llvm::InstrProfRecordWriterTrait::ValueProfDataEndianness
support::endianness ValueProfDataEndianness
Definition: InstrProfWriter.cpp:107
llvm::ProfOStream::tell
uint64_t tell()
Definition: InstrProfWriter.cpp:55
STLExtras.h
llvm::instrprof_error::invalid_prof
@ invalid_prof
llvm::support::endian::Writer
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:52
ProfileCommon.h
llvm::IndexedInstrProf::Header::MemProfOffset
uint64_t MemProfOffset
Definition: InstrProf.h:1070
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::detail::DenseMapPair
Definition: DenseMap.h:42
llvm::InstrProfRecord
Profiling information for a single function.
Definition: InstrProf.h:730
new
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
Definition: README.txt:125
F
#define F(x, y, z)
Definition: MD5.cpp:55
InstrProfData.inc
llvm::InstrProfRecordWriterTrait
Definition: InstrProfWriter.cpp:96
InstrProfWriter.h
llvm::OverlapFuncFilters
Definition: InstrProf.h:693
llvm::coverage::CurrentVersion
@ CurrentVersion
Definition: CoverageMapping.h:1009
PatchItem::Pos
uint64_t Pos
Definition: InstrProfWriter.cpp:39
llvm::CountSumOrPercent::CountSum
double CountSum
Definition: InstrProf.h:638
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::ProfileSummary::getNumCounts
uint32_t getNumCounts() const
Definition: ProfileSummary.h:91
llvm::support::little
@ little
Definition: Endian.h:27
llvm::InstrProfKind::IRInstrumentation
@ IRInstrumentation
llvm::InstrProfKind::SingleByteCoverage
@ SingleByteCoverage
llvm::OnDiskChainedHashTableGenerator::Emit
offset_type Emit(raw_ostream &Out)
Emit the table to Out, which must not be at offset 0.
Definition: OnDiskHashTable.h:143
OnDiskHashTable.h
llvm::InstrProfWriter::writeRecordInText
static void writeRecordInText(StringRef Name, uint64_t Hash, const InstrProfRecord &Counters, InstrProfSymtab &Symtab, raw_fd_ostream &OS)
Write Record in text format to OS.
Definition: InstrProfWriter.cpp:546
llvm::InstrProfRecordWriterTrait::EmitData
void EmitData(raw_ostream &Out, key_type_ref, data_type_ref V, offset_type)
Definition: InstrProfWriter.cpp:145
PatchItem::N
int N
Definition: InstrProfWriter.cpp:41
llvm::ProfileSummary::getNumFunctions
uint32_t getNumFunctions() const
Definition: ProfileSummary.h:89
llvm::ProfileSummary::getMaxInternalCount
uint64_t getMaxInternalCount() const
Definition: ProfileSummary.h:94
false
Definition: StackSlotColoring.cpp:141
llvm::ProfileSummary::getTotalCount
uint64_t getTotalCount() const
Definition: ProfileSummary.h:92
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::ProfOStream::OS
raw_ostream & OS
Definition: InstrProfWriter.cpp:92
PatchItem
Definition: InstrProfWriter.cpp:38
llvm::raw_ostream::write
raw_ostream & write(unsigned char C)
Definition: raw_ostream.cpp:218
InstrProf.h
llvm::IndexedInstrProf::Header::Magic
uint64_t Magic
Definition: InstrProf.h:1065
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::StringRef::data
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
Definition: StringRef.h:131
llvm::IndexedInstrProf::Header
Definition: InstrProf.h:1064
llvm::raw_fd_ostream::seek
uint64_t seek(uint64_t off)
Flushes the stream and repositions the underlying file descriptor position to the offset specified fr...
Definition: raw_ostream.cpp:800
llvm::IndexedInstrProf::Summary::TotalBlockCount
@ TotalBlockCount
The sum of all instrumented block counts.
Definition: InstrProf.h:1114
ValueProfKindStr
static const char * ValueProfKindStr[]
Definition: InstrProfWriter.cpp:520
llvm::ProfileSummary::getMaxFunctionCount
uint64_t getMaxFunctionCount() const
Definition: ProfileSummary.h:90
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1538
llvm::function_ref
An efficient, type-erasing, non-owning reference to a callable.
Definition: STLFunctionalExtras.h:36
llvm::IndexedInstrProf::Summary::MaxFunctionCount
@ MaxFunctionCount
The maximal execution count among all functions.
Definition: InstrProf.h:1108
llvm::CountSumOrPercent::NumEntries
uint64_t NumEntries
Definition: InstrProf.h:637
llvm::IndexedInstrProf::Summary::set
void set(SummaryFieldKind K, uint64_t V)
Definition: InstrProf.h:1154
llvm::InstrProfRecordWriterTrait::data_type
const InstrProfWriter::ProfilingData *const data_type
Definition: InstrProfWriter.cpp:101
llvm::ProfOStream::patch
void patch(PatchItem *P, int NItems)
Definition: InstrProfWriter.cpp:61
llvm::memprof::Frame
Definition: MemProf.h:141
llvm::InstrProfWriter
Definition: InstrProfWriter.h:36
llvm::ProfileSummary::getDetailedSummary
const SummaryEntryVector & getDetailedSummary()
Definition: ProfileSummary.h:88
uint64_t
llvm::InstrProfWriter::setValueProfDataEndianness
void setValueProfDataEndianness(support::endianness Endianness)
Definition: InstrProfWriter.cpp:179
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::InstrProfRecordWriterTrait::SummaryBuilder
InstrProfSummaryBuilder * SummaryBuilder
Definition: InstrProfWriter.cpp:108
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::InstrProfWriter::addMemProfFrame
bool addMemProfFrame(const memprof::FrameId, const memprof::Frame &F, function_ref< void(Error)> Warn)
Add a memprof frame identified by the hash of the contents of the frame in FrameId.
Definition: InstrProfWriter.cpp:267
llvm::InstrProfSummaryBuilder
Definition: ProfileCommon.h:74
llvm::InstrProfWriter::addMemProfRecord
void addMemProfRecord(const GlobalValue::GUID Id, const memprof::IndexedMemProfRecord &Record)
Add a memprof record for a function identified by its Id.
Definition: InstrProfWriter.cpp:256
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::instrprof_error
instrprof_error
Definition: InstrProf.h:308
llvm::ProfileSummary
Definition: ProfileSummary.h:45
setSummary
static void setSummary(IndexedInstrProf::Summary *TheSummary, ProfileSummary &PS)
Definition: InstrProfWriter.cpp:314
llvm::IndexedInstrProf::Header::HashType
uint64_t HashType
Definition: InstrProf.h:1068
llvm::InstrProfWriter::InstrProfWriter
InstrProfWriter(bool Sparse=false)
Definition: InstrProfWriter.cpp:173
llvm::IndexedInstrProf::allocSummary
std::unique_ptr< Summary > allocSummary(uint32_t TotalSize)
Definition: InstrProf.h:1168
llvm::Record
Definition: Record.h:1543
llvm::IndexedInstrProf::Summary::TotalNumFunctions
@ TotalNumFunctions
The total number of functions instrumented.
Definition: InstrProf.h:1102
llvm::InstrProfKind::MemProf
@ MemProf
llvm::InstrProfWriter::addRecord
void addRecord(NamedInstrProfRecord &&I, uint64_t Weight, function_ref< void(Error)> Warn)
Add function counts for the given function.
Definition: InstrProfWriter.cpp:188
llvm::ProfOStream::ProfOStream
ProfOStream(raw_fd_ostream &FD)
Definition: InstrProfWriter.cpp:50
llvm::IndexedInstrProf::Summary::setEntry
void setEntry(uint32_t I, const ProfileSummaryEntry &E)
Definition: InstrProf.h:1160
llvm::OverlapStats::addOneUnique
void addOneUnique(const CountSumOrPercent &UniqueFunc)
Definition: InstrProf.cpp:1256
llvm::X86II::PD
@ PD
Definition: X86BaseInfo.h:787
llvm::any_of
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1597
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
llvm::IndexedInstrProf::Magic
const uint64_t Magic
Definition: InstrProf.h:1025
llvm::support::endian::Writer::write
void write(ArrayRef< value_type > Val)
Definition: EndianStream.h:56
llvm::NamedInstrProfRecord::hasCSFlagInHash
static bool hasCSFlagInHash(uint64_t FuncHash)
Definition: InstrProf.h:923
uint32_t
llvm::IndexedInstrProf::Summary::NumCutoffEntries
uint64_t NumCutoffEntries
Definition: InstrProf.h:1121
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::memprof::IndexedMemProfRecord::merge
void merge(const IndexedMemProfRecord &Other)
Definition: MemProf.h:339
llvm::raw_fd_ostream
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:440
llvm::InstrProfRecord::merge
void merge(InstrProfRecord &Other, uint64_t Weight, function_ref< void(instrprof_error)> Warn)
Merge the counts in Other into this one.
Definition: InstrProf.cpp:708
llvm::StringRef::size
constexpr size_t size() const
size - Get the string size.
Definition: StringRef.h:137
MemProf.h
llvm::InstrProfWriter::writeBuffer
std::unique_ptr< MemoryBuffer > writeBuffer()
Write the profile, returning the raw data. For testing.
Definition: InstrProfWriter.cpp:509
llvm::IndexedInstrProf::Summary::MaxInternalBlockCount
@ MaxInternalBlockCount
Max internal block count of the program (excluding entry blocks).
Definition: InstrProf.h:1112
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:50
llvm::InstrProfSymtab
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:446
EndianStream.h
llvm::InstrProfWriter::~InstrProfWriter
~InstrProfWriter()
Definition: InstrProfWriter.cpp:176
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::InstrProfRecordWriterTrait::data_type_ref
const InstrProfWriter::ProfilingData *const data_type_ref
Definition: InstrProfWriter.cpp:102
llvm::IndexedInstrProf::Summary
Definition: InstrProf.h:1090
llvm::InstrProfWriter::validateRecord
Error validateRecord(const InstrProfRecord &Func)
Definition: InstrProfWriter.cpp:525
llvm::IndexedInstrProf::Summary::MaxBlockCount
@ MaxBlockCount
Max block count of the program.
Definition: InstrProf.h:1110
llvm::ProfOStream::LE
support::endian::Writer LE
Definition: InstrProfWriter.cpp:93
llvm::OverlapStats::Overlap
CountSumOrPercent Overlap
Definition: InstrProf.h:657
llvm::IndexedInstrProf::HashType
const HashT HashType
Definition: InstrProf.h:1058
llvm::InstrProfRecordWriterTrait::EmitKey
void EmitKey(raw_ostream &Out, key_type_ref K, offset_type N)
Definition: InstrProfWriter.cpp:141
llvm::IndexedInstrProf::Header::HashOffset
uint64_t HashOffset
Definition: InstrProf.h:1069
llvm::InstrProfSymtab::addFuncName
Error addFuncName(StringRef FuncName)
Update the symtab by adding FuncName to the table.
Definition: InstrProf.h:507
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::iterator
DenseMapIterator< KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > > iterator
Definition: DenseMap.h:71
llvm::InstrProfRecord::sortValueData
void sortValueData()
Sort value profile data (per site) by count.
Definition: InstrProf.h:800
llvm::OverlapFuncFilters::ValueCutoff
uint64_t ValueCutoff
Definition: InstrProf.h:694
llvm::InstrProfSymtab::getFuncNameOrExternalSymbol
StringRef getFuncNameOrExternalSymbol(uint64_t FuncMD5Hash)
Just like getFuncName, except that it will return a non-empty StringRef if the function is external t...
Definition: InstrProf.h:597
N
#define N
llvm::OverlapFuncFilters::NameFilter
const std::string NameFilter
Definition: InstrProf.h:695
llvm::ArrayRef::size
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:164
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::IndexedInstrProf::Header::Unused
uint64_t Unused
Definition: InstrProf.h:1067
llvm::support::endianness
endianness
Definition: Endian.h:27
llvm::NamedInstrProfRecord
Definition: InstrProf.h:911
llvm::instrprof_error::malformed
@ malformed
llvm::InstrProfSummaryBuilder::addRecord
void addRecord(const InstrProfRecord &)
Definition: ProfileSummaryBuilder.cpp:91
llvm::InstrProfRecordWriterTrait::EmitKeyDataLength
static std::pair< offset_type, offset_type > EmitKeyDataLength(raw_ostream &Out, key_type_ref K, data_type_ref V)
Definition: InstrProfWriter.cpp:118
PatchItem::D
uint64_t * D
Definition: InstrProfWriter.cpp:40
llvm::IndexedInstrProf::Summary::TotalNumBlocks
@ TotalNumBlocks
Total number of instrumented blocks/edges.
Definition: InstrProf.h:1104
llvm::InstrProfRecordWriterTrait::ComputeHash
static hash_value_type ComputeHash(key_type_ref K)
Definition: InstrProfWriter.cpp:113
llvm::ProfOStream
Definition: InstrProfWriter.cpp:48
llvm::InstrProfWriter::setOutputSparse
void setOutputSparse(bool Sparse)
Definition: InstrProfWriter.cpp:184
raw_ostream.h
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:241
llvm::MemoryBuffer::getMemBufferCopy
static std::unique_ptr< MemoryBuffer > getMemBufferCopy(StringRef InputData, const Twine &BufferName="")
Open the specified memory range as a MemoryBuffer, copying the contents and taking ownership of it.
Definition: MemoryBuffer.cpp:138
Endian.h
llvm::InstrProfWriter::mergeRecordsFromWriter
void mergeRecordsFromWriter(InstrProfWriter &&IPW, function_ref< void(Error)> Warn)
Merge existing function counts from the given writer.
Definition: InstrProfWriter.cpp:283
llvm::raw_string_ostream::str
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:646
llvm::IndexedInstrProf::Summary::NumSummaryFields
uint64_t NumSummaryFields
Definition: InstrProf.h:1119
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::OverlapStats::addOneMismatch
void addOneMismatch(const CountSumOrPercent &MismatchFunc)
Definition: InstrProf.cpp:1246
llvm::InstrProfRecord::Counts
std::vector< uint64_t > Counts
Definition: InstrProf.h:731
llvm::ProfOStream::IsFDOStream
bool IsFDOStream
Definition: InstrProfWriter.cpp:91
llvm::OverlapStats::Test
CountSumOrPercent Test
Definition: InstrProf.h:655
Other
Optional< std::vector< StOtherPiece > > Other
Definition: ELFYAML.cpp:1247
llvm::ProfileSummary::getMaxCount
uint64_t getMaxCount() const
Definition: ProfileSummary.h:93
llvm::ProfOStream::ProfOStream
ProfOStream(raw_string_ostream &STR)
Definition: InstrProfWriter.cpp:52
llvm::InstrProfWriter::overlapRecord
void overlapRecord(NamedInstrProfRecord &&Other, OverlapStats &Overlap, OverlapStats &FuncLevelOverlap, const OverlapFuncFilters &FuncFilter)
Definition: InstrProfWriter.cpp:195
llvm::InstrProfRecord::scale
void scale(uint64_t N, uint64_t D, function_ref< void(instrprof_error)> Warn)
Scale up profile counts (including value profile data) by a factor of (N / D).
Definition: InstrProf.cpp:759