LLVM  14.0.0git
SampleProfReader.cpp
Go to the documentation of this file.
1 //===- SampleProfReader.cpp - Read LLVM sample profile data ---------------===//
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 implements the class that reads LLVM sample profiles. It
10 // supports three file formats: text, binary and gcov.
11 //
12 // The textual representation is useful for debugging and testing purposes. The
13 // binary representation is more compact, resulting in smaller file sizes.
14 //
15 // The gcov encoding is the one generated by GCC's AutoFDO profile creation
16 // tool (https://github.com/google/autofdo)
17 //
18 // All three encodings can be used interchangeably as an input sample profile.
19 //
20 //===----------------------------------------------------------------------===//
21 
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/STLExtras.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/IR/ProfileSummary.h"
31 #include "llvm/Support/ErrorOr.h"
32 #include "llvm/Support/LEB128.h"
34 #include "llvm/Support/MD5.h"
37 #include <algorithm>
38 #include <cstddef>
39 #include <cstdint>
40 #include <limits>
41 #include <memory>
42 #include <set>
43 #include <system_error>
44 #include <vector>
45 
46 using namespace llvm;
47 using namespace sampleprof;
48 
49 #define DEBUG_TYPE "samplepgo-reader"
50 
51 // This internal option specifies if the profile uses FS discriminators.
52 // It only applies to text, binary and compact binary format profiles.
53 // For ext-binary format profiles, the flag is set in the summary.
55  "profile-isfs", cl::Hidden, cl::init(false),
56  cl::desc("Profile uses flow sensitive discriminators"));
57 
58 /// Dump the function profile for \p FName.
59 ///
60 /// \param FContext Name + context of the function to print.
61 /// \param OS Stream to emit the output to.
63  raw_ostream &OS) {
64  OS << "Function: " << FContext.toString() << ": " << Profiles[FContext];
65 }
66 
67 /// Dump all the function profiles found on stream \p OS.
69  std::vector<NameFunctionSamples> V;
71  for (const auto &I : V)
72  dumpFunctionProfile(I.first, OS);
73 }
74 
75 /// Parse \p Input as function head.
76 ///
77 /// Parse one line of \p Input, and update function name in \p FName,
78 /// function's total sample count in \p NumSamples, function's entry
79 /// count in \p NumHeadSamples.
80 ///
81 /// \returns true if parsing is successful.
82 static bool ParseHead(const StringRef &Input, StringRef &FName,
83  uint64_t &NumSamples, uint64_t &NumHeadSamples) {
84  if (Input[0] == ' ')
85  return false;
86  size_t n2 = Input.rfind(':');
87  size_t n1 = Input.rfind(':', n2 - 1);
88  FName = Input.substr(0, n1);
89  if (Input.substr(n1 + 1, n2 - n1 - 1).getAsInteger(10, NumSamples))
90  return false;
91  if (Input.substr(n2 + 1).getAsInteger(10, NumHeadSamples))
92  return false;
93  return true;
94 }
95 
96 /// Returns true if line offset \p L is legal (only has 16 bits).
97 static bool isOffsetLegal(unsigned L) { return (L & 0xffff) == L; }
98 
99 /// Parse \p Input that contains metadata.
100 /// Possible metadata:
101 /// - CFG Checksum information:
102 /// !CFGChecksum: 12345
103 /// - CFG Checksum information:
104 /// !Attributes: 1
105 /// Stores the FunctionHash (a.k.a. CFG Checksum) into \p FunctionHash.
106 static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash,
107  uint32_t &Attributes) {
108  if (Input.startswith("!CFGChecksum:")) {
109  StringRef CFGInfo = Input.substr(strlen("!CFGChecksum:")).trim();
110  return !CFGInfo.getAsInteger(10, FunctionHash);
111  }
112 
113  if (Input.startswith("!Attributes:")) {
114  StringRef Attrib = Input.substr(strlen("!Attributes:")).trim();
115  return !Attrib.getAsInteger(10, Attributes);
116  }
117 
118  return false;
119 }
120 
121 enum class LineType {
123  BodyProfile,
124  Metadata,
125 };
126 
127 /// Parse \p Input as line sample.
128 ///
129 /// \param Input input line.
130 /// \param LineTy Type of this line.
131 /// \param Depth the depth of the inline stack.
132 /// \param NumSamples total samples of the line/inlined callsite.
133 /// \param LineOffset line offset to the start of the function.
134 /// \param Discriminator discriminator of the line.
135 /// \param TargetCountMap map from indirect call target to count.
136 /// \param FunctionHash the function's CFG hash, used by pseudo probe.
137 ///
138 /// returns true if parsing is successful.
139 static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth,
140  uint64_t &NumSamples, uint32_t &LineOffset,
141  uint32_t &Discriminator, StringRef &CalleeName,
142  DenseMap<StringRef, uint64_t> &TargetCountMap,
143  uint64_t &FunctionHash, uint32_t &Attributes) {
144  for (Depth = 0; Input[Depth] == ' '; Depth++)
145  ;
146  if (Depth == 0)
147  return false;
148 
149  if (Depth == 1 && Input[Depth] == '!') {
150  LineTy = LineType::Metadata;
151  return parseMetadata(Input.substr(Depth), FunctionHash, Attributes);
152  }
153 
154  size_t n1 = Input.find(':');
155  StringRef Loc = Input.substr(Depth, n1 - Depth);
156  size_t n2 = Loc.find('.');
157  if (n2 == StringRef::npos) {
158  if (Loc.getAsInteger(10, LineOffset) || !isOffsetLegal(LineOffset))
159  return false;
160  Discriminator = 0;
161  } else {
162  if (Loc.substr(0, n2).getAsInteger(10, LineOffset))
163  return false;
164  if (Loc.substr(n2 + 1).getAsInteger(10, Discriminator))
165  return false;
166  }
167 
168  StringRef Rest = Input.substr(n1 + 2);
169  if (isDigit(Rest[0])) {
170  LineTy = LineType::BodyProfile;
171  size_t n3 = Rest.find(' ');
172  if (n3 == StringRef::npos) {
173  if (Rest.getAsInteger(10, NumSamples))
174  return false;
175  } else {
176  if (Rest.substr(0, n3).getAsInteger(10, NumSamples))
177  return false;
178  }
179  // Find call targets and their sample counts.
180  // Note: In some cases, there are symbols in the profile which are not
181  // mangled. To accommodate such cases, use colon + integer pairs as the
182  // anchor points.
183  // An example:
184  // _M_construct<char *>:1000 string_view<std::allocator<char> >:437
185  // ":1000" and ":437" are used as anchor points so the string above will
186  // be interpreted as
187  // target: _M_construct<char *>
188  // count: 1000
189  // target: string_view<std::allocator<char> >
190  // count: 437
191  while (n3 != StringRef::npos) {
192  n3 += Rest.substr(n3).find_first_not_of(' ');
193  Rest = Rest.substr(n3);
194  n3 = Rest.find_first_of(':');
195  if (n3 == StringRef::npos || n3 == 0)
196  return false;
197 
199  uint64_t count, n4;
200  while (true) {
201  // Get the segment after the current colon.
202  StringRef AfterColon = Rest.substr(n3 + 1);
203  // Get the target symbol before the current colon.
204  Target = Rest.substr(0, n3);
205  // Check if the word after the current colon is an integer.
206  n4 = AfterColon.find_first_of(' ');
207  n4 = (n4 != StringRef::npos) ? n3 + n4 + 1 : Rest.size();
208  StringRef WordAfterColon = Rest.substr(n3 + 1, n4 - n3 - 1);
209  if (!WordAfterColon.getAsInteger(10, count))
210  break;
211 
212  // Try to find the next colon.
213  uint64_t n5 = AfterColon.find_first_of(':');
214  if (n5 == StringRef::npos)
215  return false;
216  n3 += n5 + 1;
217  }
218 
219  // An anchor point is found. Save the {target, count} pair
220  TargetCountMap[Target] = count;
221  if (n4 == Rest.size())
222  break;
223  // Change n3 to the next blank space after colon + integer pair.
224  n3 = n4;
225  }
226  } else {
227  LineTy = LineType::CallSiteProfile;
228  size_t n3 = Rest.find_last_of(':');
229  CalleeName = Rest.substr(0, n3);
230  if (Rest.substr(n3 + 1).getAsInteger(10, NumSamples))
231  return false;
232  }
233  return true;
234 }
235 
236 /// Load samples from a text file.
237 ///
238 /// See the documentation at the top of the file for an explanation of
239 /// the expected format.
240 ///
241 /// \returns true if the file was loaded successfully, false otherwise.
243  line_iterator LineIt(*Buffer, /*SkipBlanks=*/true, '#');
245 
246  InlineCallStack InlineStack;
247  uint32_t ProbeProfileCount = 0;
248 
249  // SeenMetadata tracks whether we have processed metadata for the current
250  // top-level function profile.
251  bool SeenMetadata = false;
252 
255  for (; !LineIt.is_at_eof(); ++LineIt) {
256  if ((*LineIt)[(*LineIt).find_first_not_of(' ')] == '#')
257  continue;
258  // Read the header of each function.
259  //
260  // Note that for function identifiers we are actually expecting
261  // mangled names, but we may not always get them. This happens when
262  // the compiler decides not to emit the function (e.g., it was inlined
263  // and removed). In this case, the binary will not have the linkage
264  // name for the function, so the profiler will emit the function's
265  // unmangled name, which may contain characters like ':' and '>' in its
266  // name (member functions, templates, etc).
267  //
268  // The only requirement we place on the identifier, then, is that it
269  // should not begin with a number.
270  if ((*LineIt)[0] != ' ') {
271  uint64_t NumSamples, NumHeadSamples;
272  StringRef FName;
273  if (!ParseHead(*LineIt, FName, NumSamples, NumHeadSamples)) {
274  reportError(LineIt.line_number(),
275  "Expected 'mangled_name:NUM:NUM', found " + *LineIt);
277  }
278  SeenMetadata = false;
279  SampleContext FContext(FName, CSNameTable);
280  if (FContext.hasContext())
281  ++CSProfileCount;
282  Profiles[FContext] = FunctionSamples();
283  FunctionSamples &FProfile = Profiles[FContext];
284  FProfile.setContext(FContext);
285  MergeResult(Result, FProfile.addTotalSamples(NumSamples));
286  MergeResult(Result, FProfile.addHeadSamples(NumHeadSamples));
287  InlineStack.clear();
288  InlineStack.push_back(&FProfile);
289  } else {
290  uint64_t NumSamples;
291  StringRef FName;
292  DenseMap<StringRef, uint64_t> TargetCountMap;
293  uint32_t Depth, LineOffset, Discriminator;
294  LineType LineTy;
295  uint64_t FunctionHash = 0;
296  uint32_t Attributes = 0;
297  if (!ParseLine(*LineIt, LineTy, Depth, NumSamples, LineOffset,
298  Discriminator, FName, TargetCountMap, FunctionHash,
299  Attributes)) {
300  reportError(LineIt.line_number(),
301  "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
302  *LineIt);
304  }
305  if (SeenMetadata && LineTy != LineType::Metadata) {
306  // Metadata must be put at the end of a function profile.
307  reportError(LineIt.line_number(),
308  "Found non-metadata after metadata: " + *LineIt);
310  }
311 
312  // Here we handle FS discriminators.
313  Discriminator &= getDiscriminatorMask();
314 
315  while (InlineStack.size() > Depth) {
316  InlineStack.pop_back();
317  }
318  switch (LineTy) {
320  FunctionSamples &FSamples = InlineStack.back()->functionSamplesAt(
321  LineLocation(LineOffset, Discriminator))[std::string(FName)];
322  FSamples.setName(FName);
323  MergeResult(Result, FSamples.addTotalSamples(NumSamples));
324  InlineStack.push_back(&FSamples);
325  break;
326  }
327  case LineType::BodyProfile: {
328  while (InlineStack.size() > Depth) {
329  InlineStack.pop_back();
330  }
331  FunctionSamples &FProfile = *InlineStack.back();
332  for (const auto &name_count : TargetCountMap) {
333  MergeResult(Result, FProfile.addCalledTargetSamples(
334  LineOffset, Discriminator, name_count.first,
335  name_count.second));
336  }
337  MergeResult(Result, FProfile.addBodySamples(LineOffset, Discriminator,
338  NumSamples));
339  break;
340  }
341  case LineType::Metadata: {
342  FunctionSamples &FProfile = *InlineStack.back();
343  if (FunctionHash) {
344  FProfile.setFunctionHash(FunctionHash);
345  ++ProbeProfileCount;
346  }
347  if (Attributes)
349  SeenMetadata = true;
350  break;
351  }
352  }
353  }
354  }
355 
356  assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
357  "Cannot have both context-sensitive and regular profile");
358  ProfileIsCS = (CSProfileCount > 0);
359  assert((ProbeProfileCount == 0 || ProbeProfileCount == Profiles.size()) &&
360  "Cannot have both probe-based profiles and regular profiles");
361  ProfileIsProbeBased = (ProbeProfileCount > 0);
364 
365  if (Result == sampleprof_error::success)
366  computeSummary();
367 
368  return Result;
369 }
370 
372  bool result = false;
373 
374  // Check that the first non-comment line is a valid function header.
375  line_iterator LineIt(Buffer, /*SkipBlanks=*/true, '#');
376  if (!LineIt.is_at_eof()) {
377  if ((*LineIt)[0] != ' ') {
378  uint64_t NumSamples, NumHeadSamples;
379  StringRef FName;
380  result = ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
381  }
382  }
383 
384  return result;
385 }
386 
388  unsigned NumBytesRead = 0;
389  std::error_code EC;
390  uint64_t Val = decodeULEB128(Data, &NumBytesRead);
391 
392  if (Val > std::numeric_limits<T>::max())
394  else if (Data + NumBytesRead > End)
396  else
398 
399  if (EC) {
400  reportError(0, EC.message());
401  return EC;
402  }
403 
404  Data += NumBytesRead;
405  return static_cast<T>(Val);
406 }
407 
409  std::error_code EC;
410  StringRef Str(reinterpret_cast<const char *>(Data));
411  if (Data + Str.size() + 1 > End) {
413  reportError(0, EC.message());
414  return EC;
415  }
416 
417  Data += Str.size() + 1;
418  return Str;
419 }
420 
421 template <typename T>
423  std::error_code EC;
424 
425  if (Data + sizeof(T) > End) {
427  reportError(0, EC.message());
428  return EC;
429  }
430 
431  using namespace support;
432  T Val = endian::readNext<T, little, unaligned>(Data);
433  return Val;
434 }
435 
436 template <typename T>
438  std::error_code EC;
439  auto Idx = readNumber<uint32_t>();
440  if (std::error_code EC = Idx.getError())
441  return EC;
442  if (*Idx >= Table.size())
444  return *Idx;
445 }
446 
448  auto Idx = readStringIndex(NameTable);
449  if (std::error_code EC = Idx.getError())
450  return EC;
451 
452  return NameTable[*Idx];
453 }
454 
456  auto FName(readStringFromTable());
457  if (std::error_code EC = FName.getError())
458  return EC;
459  return SampleContext(*FName);
460 }
461 
463  if (!FixedLengthMD5)
465 
466  // read NameTable index.
467  auto Idx = readStringIndex(NameTable);
468  if (std::error_code EC = Idx.getError())
469  return EC;
470 
471  // Check whether the name to be accessed has been accessed before,
472  // if not, read it from memory directly.
473  StringRef &SR = NameTable[*Idx];
474  if (SR.empty()) {
475  const uint8_t *SavedData = Data;
476  Data = MD5NameMemStart + ((*Idx) * sizeof(uint64_t));
477  auto FID = readUnencodedNumber<uint64_t>();
478  if (std::error_code EC = FID.getError())
479  return EC;
480  // Save the string converted from uint64_t in MD5StringBuf. All the
481  // references to the name are all StringRefs refering to the string
482  // in MD5StringBuf.
483  MD5StringBuf->push_back(std::to_string(*FID));
484  SR = MD5StringBuf->back();
485  Data = SavedData;
486  }
487  return SR;
488 }
489 
490 ErrorOr<StringRef> SampleProfileReaderCompactBinary::readStringFromTable() {
491  auto Idx = readStringIndex(NameTable);
492  if (std::error_code EC = Idx.getError())
493  return EC;
494 
495  return StringRef(NameTable[*Idx]);
496 }
497 
498 std::error_code
500  auto NumSamples = readNumber<uint64_t>();
501  if (std::error_code EC = NumSamples.getError())
502  return EC;
503  FProfile.addTotalSamples(*NumSamples);
504 
505  // Read the samples in the body.
506  auto NumRecords = readNumber<uint32_t>();
507  if (std::error_code EC = NumRecords.getError())
508  return EC;
509 
510  for (uint32_t I = 0; I < *NumRecords; ++I) {
511  auto LineOffset = readNumber<uint64_t>();
512  if (std::error_code EC = LineOffset.getError())
513  return EC;
514 
515  if (!isOffsetLegal(*LineOffset)) {
516  return std::error_code();
517  }
518 
519  auto Discriminator = readNumber<uint64_t>();
520  if (std::error_code EC = Discriminator.getError())
521  return EC;
522 
523  auto NumSamples = readNumber<uint64_t>();
524  if (std::error_code EC = NumSamples.getError())
525  return EC;
526 
527  auto NumCalls = readNumber<uint32_t>();
528  if (std::error_code EC = NumCalls.getError())
529  return EC;
530 
531  // Here we handle FS discriminators:
532  uint32_t DiscriminatorVal = (*Discriminator) & getDiscriminatorMask();
533 
534  for (uint32_t J = 0; J < *NumCalls; ++J) {
535  auto CalledFunction(readStringFromTable());
536  if (std::error_code EC = CalledFunction.getError())
537  return EC;
538 
539  auto CalledFunctionSamples = readNumber<uint64_t>();
540  if (std::error_code EC = CalledFunctionSamples.getError())
541  return EC;
542 
543  FProfile.addCalledTargetSamples(*LineOffset, DiscriminatorVal,
544  *CalledFunction, *CalledFunctionSamples);
545  }
546 
547  FProfile.addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
548  }
549 
550  // Read all the samples for inlined function calls.
551  auto NumCallsites = readNumber<uint32_t>();
552  if (std::error_code EC = NumCallsites.getError())
553  return EC;
554 
555  for (uint32_t J = 0; J < *NumCallsites; ++J) {
556  auto LineOffset = readNumber<uint64_t>();
557  if (std::error_code EC = LineOffset.getError())
558  return EC;
559 
560  auto Discriminator = readNumber<uint64_t>();
561  if (std::error_code EC = Discriminator.getError())
562  return EC;
563 
564  auto FName(readStringFromTable());
565  if (std::error_code EC = FName.getError())
566  return EC;
567 
568  // Here we handle FS discriminators:
569  uint32_t DiscriminatorVal = (*Discriminator) & getDiscriminatorMask();
570 
571  FunctionSamples &CalleeProfile = FProfile.functionSamplesAt(
572  LineLocation(*LineOffset, DiscriminatorVal))[std::string(*FName)];
573  CalleeProfile.setName(*FName);
574  if (std::error_code EC = readProfile(CalleeProfile))
575  return EC;
576  }
577 
579 }
580 
581 std::error_code
583  Data = Start;
584  auto NumHeadSamples = readNumber<uint64_t>();
585  if (std::error_code EC = NumHeadSamples.getError())
586  return EC;
587 
589  if (std::error_code EC = FContext.getError())
590  return EC;
591 
592  Profiles[*FContext] = FunctionSamples();
593  FunctionSamples &FProfile = Profiles[*FContext];
594  FProfile.setContext(*FContext);
595  FProfile.addHeadSamples(*NumHeadSamples);
596 
597  if (FContext->hasContext())
598  CSProfileCount++;
599 
600  if (std::error_code EC = readProfile(FProfile))
601  return EC;
603 }
604 
608  while (!at_eof()) {
609  if (std::error_code EC = readFuncProfile(Data))
610  return EC;
611  }
612 
614 }
615 
618  auto ContextIdx = readNumber<uint32_t>();
619  if (std::error_code EC = ContextIdx.getError())
620  return EC;
621  if (*ContextIdx >= CSNameTable->size())
623  return (*CSNameTable)[*ContextIdx];
624 }
625 
628  if (ProfileIsCS) {
629  auto FContext(readContextFromTable());
630  if (std::error_code EC = FContext.getError())
631  return EC;
632  return SampleContext(*FContext);
633  } else {
634  auto FName(readStringFromTable());
635  if (std::error_code EC = FName.getError())
636  return EC;
637  return SampleContext(*FName);
638  }
639 }
640 
642  const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry) {
643  Data = Start;
644  End = Start + Size;
645  switch (Entry.Type) {
646  case SecProfSummary:
647  if (std::error_code EC = readSummary())
648  return EC;
650  Summary->setPartialProfile(true);
655  break;
656  case SecNameTable: {
657  FixedLengthMD5 =
659  bool UseMD5 = hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name);
660  assert((!FixedLengthMD5 || UseMD5) &&
661  "If FixedLengthMD5 is true, UseMD5 has to be true");
664  if (std::error_code EC = readNameTableSec(UseMD5))
665  return EC;
666  break;
667  }
668  case SecCSNameTable: {
669  if (std::error_code EC = readCSNameTableSec())
670  return EC;
671  break;
672  }
673  case SecLBRProfile:
674  if (std::error_code EC = readFuncProfiles())
675  return EC;
676  break;
677  case SecFuncOffsetTable:
678  FuncOffsetsOrdered = hasSecFlag(Entry, SecFuncOffsetFlags::SecFlagOrdered);
679  if (std::error_code EC = readFuncOffsetTable())
680  return EC;
681  break;
682  case SecFuncMetadata: {
686  bool HasAttribute =
688  if (std::error_code EC = readFuncMetadata(HasAttribute))
689  return EC;
690  break;
691  }
693  if (std::error_code EC = readProfileSymbolList())
694  return EC;
695  break;
696  default:
697  if (std::error_code EC = readCustomSection(Entry))
698  return EC;
699  break;
700  }
702 }
703 
705  if (!M)
706  return false;
707  FuncsToUse.clear();
708  for (auto &F : *M)
709  FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F));
710  return true;
711 }
712 
714  // If there are more than one FuncOffsetTable, the profile read associated
715  // with previous FuncOffsetTable has to be done before next FuncOffsetTable
716  // is read.
717  FuncOffsetTable.clear();
718 
719  auto Size = readNumber<uint64_t>();
720  if (std::error_code EC = Size.getError())
721  return EC;
722 
723  FuncOffsetTable.reserve(*Size);
724 
725  if (FuncOffsetsOrdered) {
726  OrderedFuncOffsets =
727  std::make_unique<std::vector<std::pair<SampleContext, uint64_t>>>();
728  OrderedFuncOffsets->reserve(*Size);
729  }
730 
731  for (uint32_t I = 0; I < *Size; ++I) {
732  auto FContext(readSampleContextFromTable());
733  if (std::error_code EC = FContext.getError())
734  return EC;
735 
736  auto Offset = readNumber<uint64_t>();
737  if (std::error_code EC = Offset.getError())
738  return EC;
739 
740  FuncOffsetTable[*FContext] = *Offset;
741  if (FuncOffsetsOrdered)
742  OrderedFuncOffsets->emplace_back(*FContext, *Offset);
743  }
744 
746 }
747 
749  // Collect functions used by current module if the Reader has been
750  // given a module.
751  // collectFuncsFromModule uses FunctionSamples::getCanonicalFnName
752  // which will query FunctionSamples::HasUniqSuffix, so it has to be
753  // called after FunctionSamples::HasUniqSuffix is set, i.e. after
754  // NameTable section is read.
755  bool LoadFuncsToBeUsed = collectFuncsFromModule();
756 
757  // When LoadFuncsToBeUsed is false, load all the function profiles.
758  const uint8_t *Start = Data;
759  if (!LoadFuncsToBeUsed) {
760  while (Data < End) {
761  if (std::error_code EC = readFuncProfile(Data))
762  return EC;
763  }
764  assert(Data == End && "More data is read than expected");
765  } else {
766  // Load function profiles on demand.
767  if (Remapper) {
768  for (auto Name : FuncsToUse) {
769  Remapper->insert(Name);
770  }
771  }
772 
773  if (ProfileIsCS) {
774  DenseSet<uint64_t> FuncGuidsToUse;
775  if (useMD5()) {
776  for (auto Name : FuncsToUse)
777  FuncGuidsToUse.insert(Function::getGUID(Name));
778  }
779 
780  // For each function in current module, load all context profiles for
781  // the function as well as their callee contexts which can help profile
782  // guided importing for ThinLTO. This can be achieved by walking
783  // through an ordered context container, where contexts are laid out
784  // as if they were walked in preorder of a context trie. While
785  // traversing the trie, a link to the highest common ancestor node is
786  // kept so that all of its decendants will be loaded.
787  assert(OrderedFuncOffsets.get() &&
788  "func offset table should always be sorted in CS profile");
789  const SampleContext *CommonContext = nullptr;
790  for (const auto &NameOffset : *OrderedFuncOffsets) {
791  const auto &FContext = NameOffset.first;
792  auto FName = FContext.getName();
793  // For function in the current module, keep its farthest ancestor
794  // context. This can be used to load itself and its child and
795  // sibling contexts.
796  if ((useMD5() && FuncGuidsToUse.count(std::stoull(FName.data()))) ||
797  (!useMD5() && (FuncsToUse.count(FName) ||
798  (Remapper && Remapper->exist(FName))))) {
799  if (!CommonContext || !CommonContext->IsPrefixOf(FContext))
800  CommonContext = &FContext;
801  }
802 
803  if (CommonContext == &FContext ||
804  (CommonContext && CommonContext->IsPrefixOf(FContext))) {
805  // Load profile for the current context which originated from
806  // the common ancestor.
807  const uint8_t *FuncProfileAddr = Start + NameOffset.second;
808  assert(FuncProfileAddr < End && "out of LBRProfile section");
809  if (std::error_code EC = readFuncProfile(FuncProfileAddr))
810  return EC;
811  }
812  }
813  } else {
814  if (useMD5()) {
815  for (auto Name : FuncsToUse) {
816  auto GUID = std::to_string(MD5Hash(Name));
817  auto iter = FuncOffsetTable.find(StringRef(GUID));
818  if (iter == FuncOffsetTable.end())
819  continue;
820  const uint8_t *FuncProfileAddr = Start + iter->second;
821  assert(FuncProfileAddr < End && "out of LBRProfile section");
822  if (std::error_code EC = readFuncProfile(FuncProfileAddr))
823  return EC;
824  }
825  } else {
826  for (auto NameOffset : FuncOffsetTable) {
827  SampleContext FContext(NameOffset.first);
828  auto FuncName = FContext.getName();
829  if (!FuncsToUse.count(FuncName) &&
830  (!Remapper || !Remapper->exist(FuncName)))
831  continue;
832  const uint8_t *FuncProfileAddr = Start + NameOffset.second;
833  assert(FuncProfileAddr < End && "out of LBRProfile section");
834  if (std::error_code EC = readFuncProfile(FuncProfileAddr))
835  return EC;
836  }
837  }
838  }
839  Data = End;
840  }
841  assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
842  "Cannot have both context-sensitive and regular profile");
844  "Section flag should be consistent with actual profile");
846 }
847 
849  if (!ProfSymList)
850  ProfSymList = std::make_unique<ProfileSymbolList>();
851 
852  if (std::error_code EC = ProfSymList->read(Data, End - Data))
853  return EC;
854 
855  Data = End;
857 }
858 
859 std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
860  const uint8_t *SecStart, const uint64_t SecSize,
861  const uint8_t *&DecompressBuf, uint64_t &DecompressBufSize) {
862  Data = SecStart;
863  End = SecStart + SecSize;
864  auto DecompressSize = readNumber<uint64_t>();
865  if (std::error_code EC = DecompressSize.getError())
866  return EC;
867  DecompressBufSize = *DecompressSize;
868 
869  auto CompressSize = readNumber<uint64_t>();
870  if (std::error_code EC = CompressSize.getError())
871  return EC;
872 
875 
876  StringRef CompressedStrings(reinterpret_cast<const char *>(Data),
877  *CompressSize);
878  char *Buffer = Allocator.Allocate<char>(DecompressBufSize);
879  size_t UCSize = DecompressBufSize;
880  llvm::Error E =
881  zlib::uncompress(CompressedStrings, Buffer, UCSize);
882  if (E)
884  DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
886 }
887 
889  const uint8_t *BufStart =
890  reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
891 
892  for (auto &Entry : SecHdrTable) {
893  // Skip empty section.
894  if (!Entry.Size)
895  continue;
896 
897  // Skip sections without context when SkipFlatProf is true.
898  if (SkipFlatProf && hasSecFlag(Entry, SecCommonFlags::SecFlagFlat))
899  continue;
900 
901  const uint8_t *SecStart = BufStart + Entry.Offset;
902  uint64_t SecSize = Entry.Size;
903 
904  // If the section is compressed, decompress it into a buffer
905  // DecompressBuf before reading the actual data. The pointee of
906  // 'Data' will be changed to buffer hold by DecompressBuf
907  // temporarily when reading the actual data.
908  bool isCompressed = hasSecFlag(Entry, SecCommonFlags::SecFlagCompress);
909  if (isCompressed) {
910  const uint8_t *DecompressBuf;
911  uint64_t DecompressBufSize;
912  if (std::error_code EC = decompressSection(
913  SecStart, SecSize, DecompressBuf, DecompressBufSize))
914  return EC;
915  SecStart = DecompressBuf;
916  SecSize = DecompressBufSize;
917  }
918 
919  if (std::error_code EC = readOneSection(SecStart, SecSize, Entry))
920  return EC;
921  if (Data != SecStart + SecSize)
923 
924  // Change the pointee of 'Data' from DecompressBuf to original Buffer.
925  if (isCompressed) {
926  Data = BufStart + Entry.Offset;
927  End = BufStart + Buffer->getBufferSize();
928  }
929  }
930 
932 }
933 
935  // Collect functions used by current module if the Reader has been
936  // given a module.
937  bool LoadFuncsToBeUsed = collectFuncsFromModule();
940  std::vector<uint64_t> OffsetsToUse;
941  if (!LoadFuncsToBeUsed) {
942  // load all the function profiles.
943  for (auto FuncEntry : FuncOffsetTable) {
944  OffsetsToUse.push_back(FuncEntry.second);
945  }
946  } else {
947  // load function profiles on demand.
948  for (auto Name : FuncsToUse) {
949  auto GUID = std::to_string(MD5Hash(Name));
950  auto iter = FuncOffsetTable.find(StringRef(GUID));
951  if (iter == FuncOffsetTable.end())
952  continue;
953  OffsetsToUse.push_back(iter->second);
954  }
955  }
956 
957  for (auto Offset : OffsetsToUse) {
958  const uint8_t *SavedData = Data;
959  if (std::error_code EC = readFuncProfile(
960  reinterpret_cast<const uint8_t *>(Buffer->getBufferStart()) +
961  Offset))
962  return EC;
963  Data = SavedData;
964  }
966 }
967 
968 std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) {
969  if (Magic == SPMagic())
972 }
973 
974 std::error_code SampleProfileReaderExtBinary::verifySPMagic(uint64_t Magic) {
975  if (Magic == SPMagic(SPF_Ext_Binary))
978 }
979 
980 std::error_code
981 SampleProfileReaderCompactBinary::verifySPMagic(uint64_t Magic) {
985 }
986 
988  auto Size = readNumber<uint32_t>();
989  if (std::error_code EC = Size.getError())
990  return EC;
991  NameTable.reserve(*Size + NameTable.size());
992  for (uint32_t I = 0; I < *Size; ++I) {
993  auto Name(readString());
994  if (std::error_code EC = Name.getError())
995  return EC;
996  NameTable.push_back(*Name);
997  }
998 
1000 }
1001 
1003  auto Size = readNumber<uint64_t>();
1004  if (std::error_code EC = Size.getError())
1005  return EC;
1006  MD5StringBuf = std::make_unique<std::vector<std::string>>();
1007  MD5StringBuf->reserve(*Size);
1008  if (FixedLengthMD5) {
1009  // Preallocate and initialize NameTable so we can check whether a name
1010  // index has been read before by checking whether the element in the
1011  // NameTable is empty, meanwhile readStringIndex can do the boundary
1012  // check using the size of NameTable.
1013  NameTable.resize(*Size + NameTable.size());
1014 
1015  MD5NameMemStart = Data;
1016  Data = Data + (*Size) * sizeof(uint64_t);
1018  }
1019  NameTable.reserve(*Size);
1020  for (uint32_t I = 0; I < *Size; ++I) {
1021  auto FID = readNumber<uint64_t>();
1022  if (std::error_code EC = FID.getError())
1023  return EC;
1024  MD5StringBuf->push_back(std::to_string(*FID));
1025  // NameTable is a vector of StringRef. Here it is pushing back a
1026  // StringRef initialized with the last string in MD5stringBuf.
1027  NameTable.push_back(MD5StringBuf->back());
1028  }
1030 }
1031 
1033  if (IsMD5)
1034  return readMD5NameTable();
1036 }
1037 
1038 // Read in the CS name table section, which basically contains a list of context
1039 // vectors. Each element of a context vector, aka a frame, refers to the
1040 // underlying raw function names that are stored in the name table, as well as
1041 // a callsite identifier that only makes sense for non-leaf frames.
1043  auto Size = readNumber<uint32_t>();
1044  if (std::error_code EC = Size.getError())
1045  return EC;
1046 
1047  std::vector<SampleContextFrameVector> *PNameVec =
1048  new std::vector<SampleContextFrameVector>();
1049  PNameVec->reserve(*Size);
1050  for (uint32_t I = 0; I < *Size; ++I) {
1051  PNameVec->emplace_back(SampleContextFrameVector());
1052  auto ContextSize = readNumber<uint32_t>();
1053  if (std::error_code EC = ContextSize.getError())
1054  return EC;
1055  for (uint32_t J = 0; J < *ContextSize; ++J) {
1056  auto FName(readStringFromTable());
1057  if (std::error_code EC = FName.getError())
1058  return EC;
1059  auto LineOffset = readNumber<uint64_t>();
1060  if (std::error_code EC = LineOffset.getError())
1061  return EC;
1062 
1063  if (!isOffsetLegal(*LineOffset))
1064  return std::error_code();
1065 
1066  auto Discriminator = readNumber<uint64_t>();
1067  if (std::error_code EC = Discriminator.getError())
1068  return EC;
1069 
1070  PNameVec->back().emplace_back(
1071  FName.get(), LineLocation(LineOffset.get(), Discriminator.get()));
1072  }
1073  }
1074 
1075  // From this point the underlying object of CSNameTable should be immutable.
1076  CSNameTable.reset(PNameVec);
1078 }
1079 
1080 std::error_code
1082  while (Data < End) {
1083  auto FContext(readSampleContextFromTable());
1084  if (std::error_code EC = FContext.getError())
1085  return EC;
1086 
1087  bool ProfileInMap = Profiles.count(*FContext);
1088  if (ProfileIsProbeBased) {
1089  auto Checksum = readNumber<uint64_t>();
1090  if (std::error_code EC = Checksum.getError())
1091  return EC;
1092  if (ProfileInMap)
1093  Profiles[*FContext].setFunctionHash(*Checksum);
1094  }
1095 
1096  if (ProfileHasAttribute) {
1097  auto Attributes = readNumber<uint32_t>();
1098  if (std::error_code EC = Attributes.getError())
1099  return EC;
1100  if (ProfileInMap)
1101  Profiles[*FContext].getContext().setAllAttributes(*Attributes);
1102  }
1103  }
1104 
1105  assert(Data == End && "More data is read than expected");
1107 }
1108 
1109 std::error_code SampleProfileReaderCompactBinary::readNameTable() {
1110  auto Size = readNumber<uint64_t>();
1111  if (std::error_code EC = Size.getError())
1112  return EC;
1113  NameTable.reserve(*Size);
1114  for (uint32_t I = 0; I < *Size; ++I) {
1115  auto FID = readNumber<uint64_t>();
1116  if (std::error_code EC = FID.getError())
1117  return EC;
1118  NameTable.push_back(std::to_string(*FID));
1119  }
1121 }
1122 
1123 std::error_code
1125  SecHdrTableEntry Entry;
1126  auto Type = readUnencodedNumber<uint64_t>();
1127  if (std::error_code EC = Type.getError())
1128  return EC;
1129  Entry.Type = static_cast<SecType>(*Type);
1130 
1131  auto Flags = readUnencodedNumber<uint64_t>();
1132  if (std::error_code EC = Flags.getError())
1133  return EC;
1134  Entry.Flags = *Flags;
1135 
1136  auto Offset = readUnencodedNumber<uint64_t>();
1137  if (std::error_code EC = Offset.getError())
1138  return EC;
1139  Entry.Offset = *Offset;
1140 
1141  auto Size = readUnencodedNumber<uint64_t>();
1142  if (std::error_code EC = Size.getError())
1143  return EC;
1144  Entry.Size = *Size;
1145 
1146  Entry.LayoutIndex = Idx;
1147  SecHdrTable.push_back(std::move(Entry));
1149 }
1150 
1152  auto EntryNum = readUnencodedNumber<uint64_t>();
1153  if (std::error_code EC = EntryNum.getError())
1154  return EC;
1155 
1156  for (uint32_t i = 0; i < (*EntryNum); i++)
1157  if (std::error_code EC = readSecHdrTableEntry(i))
1158  return EC;
1159 
1161 }
1162 
1164  const uint8_t *BufStart =
1165  reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
1166  Data = BufStart;
1167  End = BufStart + Buffer->getBufferSize();
1168 
1169  if (std::error_code EC = readMagicIdent())
1170  return EC;
1171 
1172  if (std::error_code EC = readSecHdrTable())
1173  return EC;
1174 
1176 }
1177 
1179  uint64_t Size = 0;
1180  for (auto &Entry : SecHdrTable) {
1181  if (Entry.Type == Type)
1182  Size += Entry.Size;
1183  }
1184  return Size;
1185 }
1186 
1188  // Sections in SecHdrTable is not necessarily in the same order as
1189  // sections in the profile because section like FuncOffsetTable needs
1190  // to be written after section LBRProfile but needs to be read before
1191  // section LBRProfile, so we cannot simply use the last entry in
1192  // SecHdrTable to calculate the file size.
1193  uint64_t FileSize = 0;
1194  for (auto &Entry : SecHdrTable) {
1195  FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1196  }
1197  return FileSize;
1198 }
1199 
1200 static std::string getSecFlagsStr(const SecHdrTableEntry &Entry) {
1201  std::string Flags;
1203  Flags.append("{compressed,");
1204  else
1205  Flags.append("{");
1206 
1208  Flags.append("flat,");
1209 
1210  switch (Entry.Type) {
1211  case SecNameTable:
1213  Flags.append("fixlenmd5,");
1215  Flags.append("md5,");
1217  Flags.append("uniq,");
1218  break;
1219  case SecProfSummary:
1221  Flags.append("partial,");
1223  Flags.append("context,");
1225  Flags.append("fs-discriminator,");
1226  break;
1227  case SecFuncOffsetTable:
1229  Flags.append("ordered,");
1230  break;
1231  default:
1232  break;
1233  }
1234  char &last = Flags.back();
1235  if (last == ',')
1236  last = '}';
1237  else
1238  Flags.append("}");
1239  return Flags;
1240 }
1241 
1243  uint64_t TotalSecsSize = 0;
1244  for (auto &Entry : SecHdrTable) {
1245  OS << getSecName(Entry.Type) << " - Offset: " << Entry.Offset
1246  << ", Size: " << Entry.Size << ", Flags: " << getSecFlagsStr(Entry)
1247  << "\n";
1248  ;
1249  TotalSecsSize += Entry.Size;
1250  }
1251  uint64_t HeaderSize = SecHdrTable.front().Offset;
1252  assert(HeaderSize + TotalSecsSize == getFileSize() &&
1253  "Size of 'header + sections' doesn't match the total size of profile");
1254 
1255  OS << "Header Size: " << HeaderSize << "\n";
1256  OS << "Total Sections Size: " << TotalSecsSize << "\n";
1257  OS << "File Size: " << getFileSize() << "\n";
1258  return true;
1259 }
1260 
1262  // Read and check the magic identifier.
1263  auto Magic = readNumber<uint64_t>();
1264  if (std::error_code EC = Magic.getError())
1265  return EC;
1266  else if (std::error_code EC = verifySPMagic(*Magic))
1267  return EC;
1268 
1269  // Read the version number.
1270  auto Version = readNumber<uint64_t>();
1271  if (std::error_code EC = Version.getError())
1272  return EC;
1273  else if (*Version != SPVersion())
1275 
1277 }
1278 
1280  Data = reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
1281  End = Data + Buffer->getBufferSize();
1282 
1283  if (std::error_code EC = readMagicIdent())
1284  return EC;
1285 
1286  if (std::error_code EC = readSummary())
1287  return EC;
1288 
1289  if (std::error_code EC = readNameTable())
1290  return EC;
1292 }
1293 
1294 std::error_code SampleProfileReaderCompactBinary::readHeader() {
1296  if (std::error_code EC = readFuncOffsetTable())
1297  return EC;
1299 }
1300 
1301 std::error_code SampleProfileReaderCompactBinary::readFuncOffsetTable() {
1302  auto TableOffset = readUnencodedNumber<uint64_t>();
1303  if (std::error_code EC = TableOffset.getError())
1304  return EC;
1305 
1306  const uint8_t *SavedData = Data;
1307  const uint8_t *TableStart =
1308  reinterpret_cast<const uint8_t *>(Buffer->getBufferStart()) +
1309  *TableOffset;
1310  Data = TableStart;
1311 
1312  auto Size = readNumber<uint64_t>();
1313  if (std::error_code EC = Size.getError())
1314  return EC;
1315 
1316  FuncOffsetTable.reserve(*Size);
1317  for (uint32_t I = 0; I < *Size; ++I) {
1318  auto FName(readStringFromTable());
1319  if (std::error_code EC = FName.getError())
1320  return EC;
1321 
1322  auto Offset = readNumber<uint64_t>();
1323  if (std::error_code EC = Offset.getError())
1324  return EC;
1325 
1326  FuncOffsetTable[*FName] = *Offset;
1327  }
1328  End = TableStart;
1329  Data = SavedData;
1331 }
1332 
1334  if (!M)
1335  return false;
1336  FuncsToUse.clear();
1337  for (auto &F : *M)
1338  FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F));
1339  return true;
1340 }
1341 
1342 std::error_code SampleProfileReaderBinary::readSummaryEntry(
1343  std::vector<ProfileSummaryEntry> &Entries) {
1344  auto Cutoff = readNumber<uint64_t>();
1345  if (std::error_code EC = Cutoff.getError())
1346  return EC;
1347 
1348  auto MinBlockCount = readNumber<uint64_t>();
1349  if (std::error_code EC = MinBlockCount.getError())
1350  return EC;
1351 
1352  auto NumBlocks = readNumber<uint64_t>();
1353  if (std::error_code EC = NumBlocks.getError())
1354  return EC;
1355 
1356  Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1358 }
1359 
1361  auto TotalCount = readNumber<uint64_t>();
1362  if (std::error_code EC = TotalCount.getError())
1363  return EC;
1364 
1365  auto MaxBlockCount = readNumber<uint64_t>();
1366  if (std::error_code EC = MaxBlockCount.getError())
1367  return EC;
1368 
1369  auto MaxFunctionCount = readNumber<uint64_t>();
1370  if (std::error_code EC = MaxFunctionCount.getError())
1371  return EC;
1372 
1373  auto NumBlocks = readNumber<uint64_t>();
1374  if (std::error_code EC = NumBlocks.getError())
1375  return EC;
1376 
1377  auto NumFunctions = readNumber<uint64_t>();
1378  if (std::error_code EC = NumFunctions.getError())
1379  return EC;
1380 
1381  auto NumSummaryEntries = readNumber<uint64_t>();
1382  if (std::error_code EC = NumSummaryEntries.getError())
1383  return EC;
1384 
1385  std::vector<ProfileSummaryEntry> Entries;
1386  for (unsigned i = 0; i < *NumSummaryEntries; i++) {
1387  std::error_code EC = readSummaryEntry(Entries);
1388  if (EC != sampleprof_error::success)
1389  return EC;
1390  }
1391  Summary = std::make_unique<ProfileSummary>(
1392  ProfileSummary::PSK_Sample, Entries, *TotalCount, *MaxBlockCount, 0,
1393  *MaxFunctionCount, *NumBlocks, *NumFunctions);
1394 
1396 }
1397 
1399  const uint8_t *Data =
1400  reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
1402  return Magic == SPMagic();
1403 }
1404 
1406  const uint8_t *Data =
1407  reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
1409  return Magic == SPMagic(SPF_Ext_Binary);
1410 }
1411 
1413  const uint8_t *Data =
1414  reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
1416  return Magic == SPMagic(SPF_Compact_Binary);
1417 }
1418 
1420  uint32_t dummy;
1421  if (!GcovBuffer.readInt(dummy))
1424 }
1425 
1427  if (sizeof(T) <= sizeof(uint32_t)) {
1428  uint32_t Val;
1429  if (GcovBuffer.readInt(Val) && Val <= std::numeric_limits<T>::max())
1430  return static_cast<T>(Val);
1431  } else if (sizeof(T) <= sizeof(uint64_t)) {
1432  uint64_t Val;
1433  if (GcovBuffer.readInt64(Val) && Val <= std::numeric_limits<T>::max())
1434  return static_cast<T>(Val);
1435  }
1436 
1437  std::error_code EC = sampleprof_error::malformed;
1438  reportError(0, EC.message());
1439  return EC;
1440 }
1441 
1443  StringRef Str;
1444  if (!GcovBuffer.readString(Str))
1446  return Str;
1447 }
1448 
1450  // Read the magic identifier.
1451  if (!GcovBuffer.readGCDAFormat())
1453 
1454  // Read the version number. Note - the GCC reader does not validate this
1455  // version, but the profile creator generates v704.
1456  GCOV::GCOVVersion version;
1457  if (!GcovBuffer.readGCOVVersion(version))
1459 
1460  if (version != GCOV::V407)
1462 
1463  // Skip the empty integer.
1464  if (std::error_code EC = skipNextWord())
1465  return EC;
1466 
1468 }
1469 
1471  uint32_t Tag;
1472  if (!GcovBuffer.readInt(Tag))
1474 
1475  if (Tag != Expected)
1477 
1478  if (std::error_code EC = skipNextWord())
1479  return EC;
1480 
1482 }
1483 
1485  if (std::error_code EC = readSectionTag(GCOVTagAFDOFileNames))
1486  return EC;
1487 
1488  uint32_t Size;
1489  if (!GcovBuffer.readInt(Size))
1491 
1492  for (uint32_t I = 0; I < Size; ++I) {
1493  StringRef Str;
1494  if (!GcovBuffer.readString(Str))
1496  Names.push_back(std::string(Str));
1497  }
1498 
1500 }
1501 
1503  if (std::error_code EC = readSectionTag(GCOVTagAFDOFunction))
1504  return EC;
1505 
1506  uint32_t NumFunctions;
1507  if (!GcovBuffer.readInt(NumFunctions))
1509 
1510  InlineCallStack Stack;
1511  for (uint32_t I = 0; I < NumFunctions; ++I)
1512  if (std::error_code EC = readOneFunctionProfile(Stack, true, 0))
1513  return EC;
1514 
1515  computeSummary();
1517 }
1518 
1520  const InlineCallStack &InlineStack, bool Update, uint32_t Offset) {
1521  uint64_t HeadCount = 0;
1522  if (InlineStack.size() == 0)
1523  if (!GcovBuffer.readInt64(HeadCount))
1525 
1526  uint32_t NameIdx;
1527  if (!GcovBuffer.readInt(NameIdx))
1529 
1530  StringRef Name(Names[NameIdx]);
1531 
1532  uint32_t NumPosCounts;
1533  if (!GcovBuffer.readInt(NumPosCounts))
1535 
1536  uint32_t NumCallsites;
1537  if (!GcovBuffer.readInt(NumCallsites))
1539 
1540  FunctionSamples *FProfile = nullptr;
1541  if (InlineStack.size() == 0) {
1542  // If this is a top function that we have already processed, do not
1543  // update its profile again. This happens in the presence of
1544  // function aliases. Since these aliases share the same function
1545  // body, there will be identical replicated profiles for the
1546  // original function. In this case, we simply not bother updating
1547  // the profile of the original function.
1548  FProfile = &Profiles[Name];
1549  FProfile->addHeadSamples(HeadCount);
1550  if (FProfile->getTotalSamples() > 0)
1551  Update = false;
1552  } else {
1553  // Otherwise, we are reading an inlined instance. The top of the
1554  // inline stack contains the profile of the caller. Insert this
1555  // callee in the caller's CallsiteMap.
1556  FunctionSamples *CallerProfile = InlineStack.front();
1557  uint32_t LineOffset = Offset >> 16;
1558  uint32_t Discriminator = Offset & 0xffff;
1559  FProfile = &CallerProfile->functionSamplesAt(
1560  LineLocation(LineOffset, Discriminator))[std::string(Name)];
1561  }
1562  FProfile->setName(Name);
1563 
1564  for (uint32_t I = 0; I < NumPosCounts; ++I) {
1565  uint32_t Offset;
1566  if (!GcovBuffer.readInt(Offset))
1568 
1569  uint32_t NumTargets;
1570  if (!GcovBuffer.readInt(NumTargets))
1572 
1573  uint64_t Count;
1574  if (!GcovBuffer.readInt64(Count))
1576 
1577  // The line location is encoded in the offset as:
1578  // high 16 bits: line offset to the start of the function.
1579  // low 16 bits: discriminator.
1580  uint32_t LineOffset = Offset >> 16;
1581  uint32_t Discriminator = Offset & 0xffff;
1582 
1583  InlineCallStack NewStack;
1584  NewStack.push_back(FProfile);
1585  llvm::append_range(NewStack, InlineStack);
1586  if (Update) {
1587  // Walk up the inline stack, adding the samples on this line to
1588  // the total sample count of the callers in the chain.
1589  for (auto CallerProfile : NewStack)
1590  CallerProfile->addTotalSamples(Count);
1591 
1592  // Update the body samples for the current profile.
1593  FProfile->addBodySamples(LineOffset, Discriminator, Count);
1594  }
1595 
1596  // Process the list of functions called at an indirect call site.
1597  // These are all the targets that a function pointer (or virtual
1598  // function) resolved at runtime.
1599  for (uint32_t J = 0; J < NumTargets; J++) {
1600  uint32_t HistVal;
1601  if (!GcovBuffer.readInt(HistVal))
1603 
1604  if (HistVal != HIST_TYPE_INDIR_CALL_TOPN)
1606 
1607  uint64_t TargetIdx;
1608  if (!GcovBuffer.readInt64(TargetIdx))
1610  StringRef TargetName(Names[TargetIdx]);
1611 
1612  uint64_t TargetCount;
1613  if (!GcovBuffer.readInt64(TargetCount))
1615 
1616  if (Update)
1617  FProfile->addCalledTargetSamples(LineOffset, Discriminator,
1618  TargetName, TargetCount);
1619  }
1620  }
1621 
1622  // Process all the inlined callers into the current function. These
1623  // are all the callsites that were inlined into this function.
1624  for (uint32_t I = 0; I < NumCallsites; I++) {
1625  // The offset is encoded as:
1626  // high 16 bits: line offset to the start of the function.
1627  // low 16 bits: discriminator.
1628  uint32_t Offset;
1629  if (!GcovBuffer.readInt(Offset))
1631  InlineCallStack NewStack;
1632  NewStack.push_back(FProfile);
1633  llvm::append_range(NewStack, InlineStack);
1634  if (std::error_code EC = readOneFunctionProfile(NewStack, Update, Offset))
1635  return EC;
1636  }
1637 
1639 }
1640 
1641 /// Read a GCC AutoFDO profile.
1642 ///
1643 /// This format is generated by the Linux Perf conversion tool at
1644 /// https://github.com/google/autofdo.
1646  assert(!ProfileIsFSDisciminator && "Gcc profiles not support FSDisciminator");
1647  // Read the string table.
1648  if (std::error_code EC = readNameTable())
1649  return EC;
1650 
1651  // Read the source profile.
1652  if (std::error_code EC = readFunctionProfiles())
1653  return EC;
1654 
1656 }
1657 
1659  StringRef Magic(reinterpret_cast<const char *>(Buffer.getBufferStart()));
1660  return Magic == "adcg*704";
1661 }
1662 
1664  // If the reader uses MD5 to represent string, we can't remap it because
1665  // we don't know what the original function names were.
1666  if (Reader.useMD5()) {
1668  Reader.getBuffer()->getBufferIdentifier(),
1669  "Profile data remapping cannot be applied to profile data "
1670  "in compact format (original mangled names are not available).",
1671  DS_Warning));
1672  return;
1673  }
1674 
1675  // CSSPGO-TODO: Remapper is not yet supported.
1676  // We will need to remap the entire context string.
1677  assert(Remappings && "should be initialized while creating remapper");
1678  for (auto &Sample : Reader.getProfiles()) {
1679  DenseSet<StringRef> NamesInSample;
1680  Sample.second.findAllNames(NamesInSample);
1681  for (auto &Name : NamesInSample)
1682  if (auto Key = Remappings->insert(Name))
1683  NameMap.insert({Key, Name});
1684  }
1685 
1686  RemappingApplied = true;
1687 }
1688 
1691  if (auto Key = Remappings->lookup(Fname))
1692  return NameMap.lookup(Key);
1693  return None;
1694 }
1695 
1696 /// Prepare a memory buffer for the contents of \p Filename.
1697 ///
1698 /// \returns an error code indicating the status of the buffer.
1700 setupMemoryBuffer(const Twine &Filename) {
1701  auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
1702  if (std::error_code EC = BufferOrErr.getError())
1703  return EC;
1704  auto Buffer = std::move(BufferOrErr.get());
1705 
1706  // Sanity check the file.
1707  if (uint64_t(Buffer->getBufferSize()) > std::numeric_limits<uint32_t>::max())
1709 
1710  return std::move(Buffer);
1711 }
1712 
1713 /// Create a sample profile reader based on the format of the input file.
1714 ///
1715 /// \param Filename The file to open.
1716 ///
1717 /// \param C The LLVM context to use to emit diagnostics.
1718 ///
1719 /// \param P The FSDiscriminatorPass.
1720 ///
1721 /// \param RemapFilename The file used for profile remapping.
1722 ///
1723 /// \returns an error code indicating the status of the created reader.
1725 SampleProfileReader::create(const std::string Filename, LLVMContext &C,
1727  const std::string RemapFilename) {
1728  auto BufferOrError = setupMemoryBuffer(Filename);
1729  if (std::error_code EC = BufferOrError.getError())
1730  return EC;
1731  return create(BufferOrError.get(), C, P, RemapFilename);
1732 }
1733 
1734 /// Create a sample profile remapper from the given input, to remap the
1735 /// function names in the given profile data.
1736 ///
1737 /// \param Filename The file to open.
1738 ///
1739 /// \param Reader The profile reader the remapper is going to be applied to.
1740 ///
1741 /// \param C The LLVM context to use to emit diagnostics.
1742 ///
1743 /// \returns an error code indicating the status of the created reader.
1746  SampleProfileReader &Reader,
1747  LLVMContext &C) {
1748  auto BufferOrError = setupMemoryBuffer(Filename);
1749  if (std::error_code EC = BufferOrError.getError())
1750  return EC;
1751  return create(BufferOrError.get(), Reader, C);
1752 }
1753 
1754 /// Create a sample profile remapper from the given input, to remap the
1755 /// function names in the given profile data.
1756 ///
1757 /// \param B The memory buffer to create the reader from (assumes ownership).
1758 ///
1759 /// \param C The LLVM context to use to emit diagnostics.
1760 ///
1761 /// \param Reader The profile reader the remapper is going to be applied to.
1762 ///
1763 /// \returns an error code indicating the status of the created reader.
1765 SampleProfileReaderItaniumRemapper::create(std::unique_ptr<MemoryBuffer> &B,
1766  SampleProfileReader &Reader,
1767  LLVMContext &C) {
1768  auto Remappings = std::make_unique<SymbolRemappingReader>();
1769  if (Error E = Remappings->read(*B.get())) {
1771  std::move(E), [&](const SymbolRemappingParseError &ParseError) {
1772  C.diagnose(DiagnosticInfoSampleProfile(B->getBufferIdentifier(),
1773  ParseError.getLineNum(),
1774  ParseError.getMessage()));
1775  });
1777  }
1778 
1779  return std::make_unique<SampleProfileReaderItaniumRemapper>(
1780  std::move(B), std::move(Remappings), Reader);
1781 }
1782 
1783 /// Create a sample profile reader based on the format of the input data.
1784 ///
1785 /// \param B The memory buffer to create the reader from (assumes ownership).
1786 ///
1787 /// \param C The LLVM context to use to emit diagnostics.
1788 ///
1789 /// \param P The FSDiscriminatorPass.
1790 ///
1791 /// \param RemapFilename The file used for profile remapping.
1792 ///
1793 /// \returns an error code indicating the status of the created reader.
1795 SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C,
1797  const std::string RemapFilename) {
1798  std::unique_ptr<SampleProfileReader> Reader;
1800  Reader.reset(new SampleProfileReaderRawBinary(std::move(B), C));
1802  Reader.reset(new SampleProfileReaderExtBinary(std::move(B), C));
1804  Reader.reset(new SampleProfileReaderCompactBinary(std::move(B), C));
1806  Reader.reset(new SampleProfileReaderGCC(std::move(B), C));
1808  Reader.reset(new SampleProfileReaderText(std::move(B), C));
1809  else
1811 
1812  if (!RemapFilename.empty()) {
1813  auto ReaderOrErr =
1814  SampleProfileReaderItaniumRemapper::create(RemapFilename, *Reader, C);
1815  if (std::error_code EC = ReaderOrErr.getError()) {
1816  std::string Msg = "Could not create remapper: " + EC.message();
1817  C.diagnose(DiagnosticInfoSampleProfile(RemapFilename, Msg));
1818  return EC;
1819  }
1820  Reader->Remapper = std::move(ReaderOrErr.get());
1821  }
1822 
1823  FunctionSamples::Format = Reader->getFormat();
1824  if (std::error_code EC = Reader->readHeader()) {
1825  return EC;
1826  }
1827 
1828  Reader->setDiscriminatorMaskedBitFrom(P);
1829 
1830  return std::move(Reader);
1831 }
1832 
1833 // For text and GCC file formats, we compute the summary after reading the
1834 // profile. Binary format has the profile summary in its header.
1837  Summary = Builder.computeSummaryForProfiles(Profiles);
1838 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:73
llvm::sampleprof::SampleProfileReader::ProfileIsFS
bool ProfileIsFS
Whether the function profiles use FS discriminators.
Definition: SampleProfReader.h:543
i
i
Definition: README.txt:29
MemoryBuffer.h
llvm::sampleprof::SampleProfileReader::dump
void dump(raw_ostream &OS=dbgs())
Print all the profiles on stream OS.
Definition: SampleProfReader.cpp:68
llvm::sampleprof_error::uncompress_failed
@ uncompress_failed
llvm::sampleprof::SampleProfileReaderText
Definition: SampleProfReader.h:558
llvm::StringRef::back
LLVM_NODISCARD char back() const
back - Get the last character in the string.
Definition: StringRef.h:168
llvm::sampleprof::SampleProfileReaderBinary::readNameTable
virtual std::error_code readNameTable()
Read the whole name table.
Definition: SampleProfReader.cpp:987
Compression.h
llvm::sampleprof::SampleProfileReader::CSProfileCount
uint32_t CSProfileCount
Number of context-sensitive profiles.
Definition: SampleProfReader.h:540
llvm::StringRef::startswith
LLVM_NODISCARD bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition: StringRef.h:286
llvm::sampleprof::SampleProfileReaderText::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition: SampleProfReader.cpp:242
llvm::sampleprof::SampleProfileReaderItaniumRemapper::create
static ErrorOr< std::unique_ptr< SampleProfileReaderItaniumRemapper > > create(const std::string Filename, SampleProfileReader &Reader, LLVMContext &C)
Create a remapper from the given remapping file.
Definition: SampleProfReader.cpp:1745
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
llvm::sampleprof::SecFuncMetadataFlags::SecFlagHasAttribute
@ SecFlagHasAttribute
llvm::sampleprof::SampleProfileReader::M
const Module * M
The current module being compiled if SampleProfileReader is used by compiler.
Definition: SampleProfReader.h:551
llvm::sampleprof::SecProfSummaryFlags::SecFlagFSDiscriminator
@ SecFlagFSDiscriminator
SecFlagFSDiscriminator means this profile uses flow-sensitive discriminators.
llvm::sampleprof::SampleProfileReader::Remapper
std::unique_ptr< SampleProfileReaderItaniumRemapper > Remapper
Definition: SampleProfReader.h:531
llvm::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::sampleprof::FunctionSamples::ProfileIsProbeBased
static bool ProfileIsProbeBased
Definition: SampleProf.h:1010
llvm::sampleprof::FunctionSamples::ProfileIsCS
static bool ProfileIsCS
Definition: SampleProf.h:1012
llvm::line_iterator
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:33
llvm::sampleprof::SampleProfileReaderGCC::readFunctionProfiles
std::error_code readFunctionProfiles()
Definition: SampleProfReader.cpp:1502
T
llvm::StringRef::rfind
LLVM_NODISCARD size_t rfind(char C, size_t From=npos) const
Search for the last character C in the string.
Definition: StringRef.h:375
llvm::sampleprof::SampleProfileReaderGCC::readSectionTag
std::error_code readSectionTag(uint32_t Expected)
Read the section tag and check that it's the same as Expected.
Definition: SampleProfReader.cpp:1470
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::sampleprof::SecHdrTableEntry
Definition: SampleProf.h:159
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:137
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readCSNameTableSec
std::error_code readCSNameTableSec()
Definition: SampleProfReader.cpp:1042
llvm::sampleprof::SecNameTableFlags::SecFlagFixedLengthMD5
@ SecFlagFixedLengthMD5
llvm::StringRef::npos
static constexpr size_t npos
Definition: StringRef.h:60
llvm::sampleprof::SampleProfileReaderBinary::readProfile
std::error_code readProfile(FunctionSamples &FProfile)
Read the contents of the given profile instance.
Definition: SampleProfReader.cpp:499
llvm::StringRef::find
LLVM_NODISCARD size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition: StringRef.h:315
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1168
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readContextFromTable
ErrorOr< SampleContextFrames > readContextFromTable()
Definition: SampleProfReader.cpp:617
llvm::zlib::uncompress
Error uncompress(StringRef InputBuffer, char *UncompressedBuffer, size_t &UncompressedSize)
Definition: Compression.cpp:63
llvm::sampleprof::SecProfSummaryFlags::SecFlagFullContext
@ SecFlagFullContext
SecFlagContext means this is context-sensitive profile for CSSPGO.
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readStringFromTable
virtual ErrorOr< StringRef > readStringFromTable() override
Read a string indirectly via the name table.
Definition: SampleProfReader.cpp:462
llvm::GCOV::GCOVVersion
GCOVVersion
Definition: GCOV.h:45
llvm::sampleprof::SampleProfileReaderGCC::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition: SampleProfReader.cpp:1658
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readNameTableSec
std::error_code readNameTableSec(bool IsMD5)
Definition: SampleProfReader.cpp:1032
llvm::SymbolRemappingParseError::getMessage
StringRef getMessage() const
Definition: SymbolRemappingReader.h:83
llvm::sampleprof::SampleContext::toString
std::string toString() const
Definition: SampleProf.h:579
llvm::sampleprof_error::unsupported_version
@ unsupported_version
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::sampleprof::hasSecFlag
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
Definition: SampleProf.h:264
llvm::sampleprof::SampleProfileReaderItaniumRemapper::applyRemapping
void applyRemapping(LLVMContext &Ctx)
Apply remappings to the profile read by Reader.
Definition: SampleProfReader.cpp:1663
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
DenseMap.h
llvm::sampleprof::SampleProfileReaderGCC::readNameTable
std::error_code readNameTable()
Definition: SampleProfReader.cpp:1484
llvm::sampleprof::SecFuncOffsetTable
@ SecFuncOffsetTable
Definition: SampleProf.h:126
llvm::AMDGPU::Exp::Target
Target
Definition: SIDefines.h:742
llvm::Optional
Definition: APInt.h:33
llvm::sampleprof::SecCommonFlags::SecFlagCompress
@ SecFlagCompress
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readMD5NameTable
std::error_code readMD5NameTable()
Definition: SampleProfReader.cpp:1002
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readSecHdrTableEntry
std::error_code readSecHdrTableEntry(uint32_t Idx)
Definition: SampleProfReader.cpp:1124
llvm::sampleprof::SecNameTableFlags::SecFlagMD5Name
@ SecFlagMD5Name
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readSampleContextFromTable
virtual ErrorOr< SampleContext > readSampleContextFromTable() override
Definition: SampleProfReader.cpp:627
llvm::sampleprof::SampleProfileReader::collectFuncsFromModule
virtual bool collectFuncsFromModule()
Collect functions with definitions in Module M.
Definition: SampleProfReader.h:392
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:42
STLExtras.h
llvm::detail::DenseSetImpl::insert
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
llvm::detail::DenseSetImpl::count
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:97
ProfileCommon.h
isOffsetLegal
static bool isOffsetLegal(unsigned L)
Returns true if line offset L is legal (only has 16 bits).
Definition: SampleProfReader.cpp:97
llvm::sampleprof::SampleProfileReader::Summary
std::unique_ptr< ProfileSummary > Summary
Profile summary information.
Definition: SampleProfReader.h:520
llvm::sampleprof::SampleProfileReaderGCC::readOneFunctionProfile
std::error_code readOneFunctionProfile(const InlineCallStack &InlineStack, bool Update, uint32_t Offset)
Definition: SampleProfReader.cpp:1519
llvm::SampleProfileSummaryBuilder
Definition: ProfileCommon.h:88
llvm::MemoryBuffer
This interface provides simple read-only access to a block of memory, and provides simple methods for...
Definition: MemoryBuffer.h:50
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::sampleprof::SampleProfileReaderGCC::readNumber
ErrorOr< T > readNumber()
Definition: SampleProfReader.cpp:1426
llvm::sampleprof::SampleProfileReaderBinary::readStringFromTable
virtual ErrorOr< StringRef > readStringFromTable()
Read a string indirectly via the name table.
Definition: SampleProfReader.cpp:447
result
It looks like we only need to define PPCfmarto for these because according to these instructions perform RTO on fma s result
Definition: README_P9.txt:256
llvm::sampleprof::FSDiscriminatorPass
FSDiscriminatorPass
Definition: Discriminator.h:57
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::sampleprof::FunctionSamples::HasUniqSuffix
static bool HasUniqSuffix
Whether the profile contains any ".__uniq." suffix in a name.
Definition: SampleProf.h:1024
CommandLine.h
llvm::decodeULEB128
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
Definition: LEB128.h:128
llvm::sampleprof::SampleProfileReader::getDiscriminatorMask
uint32_t getDiscriminatorMask() const
Get the bitmask the discriminators: For FS profiles, return the bit mask for this pass.
Definition: SampleProfReader.h:365
llvm::sampleprof::SecFuncMetadataFlags::SecFlagIsProbeBased
@ SecFlagIsProbeBased
llvm::StringRef::find_last_of
LLVM_NODISCARD size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
Definition: StringRef.h:436
llvm::sampleprof::SampleProfileReaderBinary::NameTable
std::vector< StringRef > NameTable
Function name table.
Definition: SampleProfReader.h:643
llvm::SymbolRemappingParseError::getLineNum
int64_t getLineNum() const
Definition: SymbolRemappingReader.h:82
MD5.h
llvm::sampleprof::SampleProfileReaderCompactBinary::readImpl
std::error_code readImpl() override
Read samples only for functions to use.
Definition: SampleProfReader.cpp:934
llvm::sampleprof::FunctionSamples::getTotalSamples
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
Definition: SampleProf.h:789
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::DS_Warning
@ DS_Warning
Definition: DiagnosticInfo.h:47
llvm::sampleprof::SampleProfileReaderRawBinary::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition: SampleProfReader.cpp:1398
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::sampleprof::SampleProfileReaderBinary::readFuncProfile
std::error_code readFuncProfile(const uint8_t *Start)
Read the next function profile instance.
Definition: SampleProfReader.cpp:582
llvm::GCOV::V407
@ V407
Definition: GCOV.h:45
llvm::sampleprof::SecProfSummaryFlags::SecFlagPartial
@ SecFlagPartial
SecFlagPartial means the profile is for common/shared code.
llvm::AMDGPU::PALMD::Key
Key
PAL metadata keys.
Definition: AMDGPUMetadata.h:481
llvm::ErrorOr::getError
std::error_code getError() const
Definition: ErrorOr.h:153
SampleProf.h
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::sampleprof::SampleProfileReaderItaniumRemapper::lookUpNameInProfile
Optional< StringRef > lookUpNameInProfile(StringRef FunctionName)
Return the equivalent name in the profile for FunctionName if it exists.
Definition: SampleProfReader.cpp:1690
llvm::sampleprof::FunctionSamples::Format
static SampleProfileFormat Format
Definition: SampleProf.h:1018
llvm::sampleprof::SampleProfileReaderBinary::readString
ErrorOr< StringRef > readString()
Read a string from the profile.
Definition: SampleProfReader.cpp:408
llvm::sampleprof::SPMagic
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
Definition: SampleProf.h:99
LineIterator.h
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
getSecFlagsStr
static std::string getSecFlagsStr(const SecHdrTableEntry &Entry)
Definition: SampleProfReader.cpp:1200
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:991
llvm::sampleprof::SampleProfileReaderText::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition: SampleProfReader.cpp:371
llvm::ProfileSummary::PSK_Sample
@ PSK_Sample
Definition: ProfileSummary.h:47
llvm::Metadata
Root of the metadata hierarchy.
Definition: Metadata.h:62
llvm::BTF::HeaderSize
@ HeaderSize
Definition: BTF.h:58
llvm::sampleprof::SampleContext
Definition: SampleProf.h:469
llvm::None
const NoneType None
Definition: None.h:23
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
parseMetadata
static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input that contains metadata.
Definition: SampleProfReader.cpp:106
llvm::sampleprof::sortFuncProfiles
void sortFuncProfiles(const SampleProfileMap &ProfileMap, std::vector< NameFunctionSamples > &SortedProfiles)
Definition: SampleProf.cpp:201
llvm::sampleprof::FunctionSamples::ProfileIsFS
static bool ProfileIsFS
If this profile uses flow sensitive discriminators.
Definition: SampleProf.h:1027
llvm::StringRef::trim
LLVM_NODISCARD StringRef trim(char Char) const
Return string with consecutive Char characters starting from the left and right removed.
Definition: StringRef.h:870
llvm::DenseSet< uint64_t >
llvm::cl::opt< bool >
llvm::sampleprof::SPF_Compact_Binary
@ SPF_Compact_Binary
Definition: SampleProf.h:93
llvm::sampleprof::SecProfSummary
@ SecProfSummary
Definition: SampleProf.h:123
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
llvm::sampleprof::FunctionSamples::addHeadSamples
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)
Definition: SampleProf.h:701
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readSecHdrTable
std::error_code readSecHdrTable()
Definition: SampleProfReader.cpp:1151
uint64_t
setupMemoryBuffer
static ErrorOr< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename)
Prepare a memory buffer for the contents of Filename.
Definition: SampleProfReader.cpp:1700
llvm::sampleprof::SampleProfileReaderExtBinaryBase::getSectionSize
uint64_t getSectionSize(SecType Type)
Get the total size of all Type sections.
Definition: SampleProfReader.cpp:1178
llvm::sampleprof::SampleProfileReaderGCC
Definition: SampleProfReader.h:853
llvm::sampleprof::FunctionSamples
Representation of the samples collected for a function.
Definition: SampleProf.h:684
LEB128.h
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::LLVMContext
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:68
llvm::sampleprof::SPF_Ext_Binary
@ SPF_Ext_Binary
Definition: SampleProf.h:95
llvm::DenseMap
Definition: DenseMap.h:714
llvm::sampleprof::FunctionSamples::functionSamplesAt
FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc)
Return the function samples at the given callsite location.
Definition: SampleProf.h:763
ErrorOr.h
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::sampleprof::SecLBRProfile
@ SecLBRProfile
Definition: SampleProf.h:131
I
#define I(x, y, z)
Definition: MD5.cpp:59
SampleProfReader.h
Attributes
AMDGPU Kernel Attributes
Definition: AMDGPULowerKernelAttributes.cpp:254
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:441
llvm::sampleprof::FunctionSamples::setContext
void setContext(const SampleContext &FContext)
Definition: SampleProf.h:1016
Magic
const char Magic[]
Definition: Archive.cpp:41
llvm::sampleprof::FunctionSamples::addCalledTargetSamples
sampleprof_error addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator, StringRef FName, uint64_t Num, uint64_t Weight=1)
Definition: SampleProf.h:715
llvm::sampleprof::SampleProfileReaderBinary::readSampleContextFromTable
virtual ErrorOr< SampleContext > readSampleContextFromTable()
Definition: SampleProfReader.cpp:455
llvm::sampleprof::SampleContext::setAllAttributes
void setAllAttributes(uint32_t A)
Definition: SampleProf.h:557
llvm::sampleprof_error::malformed
@ malformed
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::sampleprof::SampleContext::getName
StringRef getName() const
Definition: SampleProf.h:563
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncMetadata
std::error_code readFuncMetadata(bool ProfileHasAttribute)
Definition: SampleProfReader.cpp:1081
llvm::sampleprof::SampleProfileReaderGCC::readString
ErrorOr< StringRef > readString()
Definition: SampleProfReader.cpp:1442
llvm::StringRef::find_first_not_of
LLVM_NODISCARD size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
Definition: StringRef.cpp:241
llvm::sampleprof::SampleProfileReader::create
static ErrorOr< std::unique_ptr< SampleProfileReader > > create(const std::string Filename, LLVMContext &C, FSDiscriminatorPass P=FSDiscriminatorPass::Base, const std::string RemapFilename="")
Create a sample profile reader appropriate to the file format.
Definition: SampleProfReader.cpp:1725
llvm::zlib::isAvailable
bool isAvailable()
Definition: Compression.cpp:47
llvm::sampleprof::LineLocation
Represents the relative location of an instruction.
Definition: SampleProf.h:280
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:650
llvm::DiagnosticInfoSampleProfile
Diagnostic information for the sample profiler.
Definition: DiagnosticInfo.h:286
llvm::sampleprof::SampleProfileReaderExtBinary
Definition: SampleProfReader.h:784
llvm::sampleprof::SampleProfileReaderBinary::readMagicIdent
std::error_code readMagicIdent()
Read the contents of Magic number and Version number.
Definition: SampleProfReader.cpp:1261
llvm::sampleprof::SampleProfileReaderBinary::End
const uint8_t * End
Points to the end of the buffer.
Definition: SampleProfReader.h:640
llvm::sampleprof::SampleProfileReaderCompactBinary
Definition: SampleProfReader.h:803
llvm::MergeResult
sampleprof_error MergeResult(sampleprof_error &Accumulator, sampleprof_error Result)
Definition: SampleProf.h:68
isDigit
static bool isDigit(const char C)
Definition: RustDemangle.cpp:206
LineType::CallSiteProfile
@ CallSiteProfile
llvm::sampleprof::SampleContext::IsPrefixOf
bool IsPrefixOf(const SampleContext &That) const
Definition: SampleProf.h:641
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readImpl
std::error_code readImpl() override
Read sample profiles in extensible format from the associated file.
Definition: SampleProfReader.cpp:888
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::sampleprof_error::unrecognized_format
@ unrecognized_format
uint32_t
llvm::sampleprof::FunctionSamples::addBodySamples
sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator, uint64_t Num, uint64_t Weight=1)
Definition: SampleProf.h:709
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:1748
llvm::sampleprof::SampleProfileReader::reportError
void reportError(int64_t LineNumber, const Twine &Msg) const
Report a parse error message.
Definition: SampleProfReader.h:444
llvm::sampleprof::SampleProfileReader::computeSummary
void computeSummary()
Compute summary for this profile.
Definition: SampleProfReader.cpp:1835
llvm::sampleprof::SecFuncOffsetFlags::SecFlagOrdered
@ SecFlagOrdered
llvm::sampleprof::SampleContextFrameVector
SmallVector< SampleContextFrame, 10 > SampleContextFrameVector
Definition: SampleProf.h:450
llvm::sampleprof::getSecName
static std::string getSecName(SecType Type)
Definition: SampleProf.h:134
llvm::sampleprof::SampleProfileReaderRawBinary
Definition: SampleProfReader.h:654
ParseHead
static bool ParseHead(const StringRef &Input, StringRef &FName, uint64_t &NumSamples, uint64_t &NumHeadSamples)
Parse Input as function head.
Definition: SampleProfReader.cpp:82
llvm::LLVMContext::diagnose
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Definition: LLVMContext.cpp:228
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:83
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::sampleprof::SampleProfileReader::Profiles
SampleProfileMap Profiles
Map every function to its associated profile.
Definition: SampleProfReader.h:507
llvm::sampleprof::SampleProfileReaderGCC::skipNextWord
std::error_code skipNextWord()
Definition: SampleProfReader.cpp:1419
llvm::sampleprof::SPVersion
static uint64_t SPVersion()
Definition: SampleProf.h:116
llvm::sampleprof::SampleProfileReaderBinary::readSummary
std::error_code readSummary()
Read profile summary.
Definition: SampleProfReader.cpp:1360
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::sampleprof::SampleProfileReaderGCC::readHeader
std::error_code readHeader() override
Read and validate the file header.
Definition: SampleProfReader.cpp:1449
llvm::GlobalValue::getGUID
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:517
llvm::sampleprof::SecProfileSymbolList
@ SecProfileSymbolList
Definition: SampleProf.h:125
llvm::sampleprof::FunctionSamples::addTotalSamples
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight=1)
Definition: SampleProf.h:691
llvm::sampleprof::SecType
SecType
Definition: SampleProf.h:121
LineType
LineType
Definition: SampleProfReader.cpp:121
llvm::sampleprof::SampleProfileReader
Sample-based profile reader.
Definition: SampleProfReader.h:345
llvm::sampleprof::SampleProfileReaderExtBinaryBase::getFileSize
uint64_t getFileSize()
Get the total size of header and all sections.
Definition: SampleProfReader.cpp:1187
llvm::sampleprof_error
sampleprof_error
Definition: SampleProf.h:45
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:585
llvm::sampleprof_error::zlib_unavailable
@ zlib_unavailable
llvm::sampleprof::SampleContext::hasContext
bool hasContext() const
Definition: SampleProf.h:561
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readHeader
virtual std::error_code readHeader() override
Read and validate the file header.
Definition: SampleProfReader.cpp:1163
llvm::sampleprof_error::too_large
@ too_large
llvm::line_iterator::is_at_eof
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
Definition: LineIterator.h:60
llvm::sampleprof::HIST_TYPE_INDIR_CALL_TOPN
@ HIST_TYPE_INDIR_CALL_TOPN
Definition: SampleProfReader.h:850
llvm::sampleprof::FunctionSamples::getContext
SampleContext & getContext() const
Definition: SampleProf.h:1014
llvm::sampleprof_error::success
@ success
llvm::sampleprof::SecNameTableFlags::SecFlagUniqSuffix
@ SecFlagUniqSuffix
llvm::sampleprof::SampleProfileReaderBinary::readUnencodedNumber
ErrorOr< T > readUnencodedNumber()
Read a numeric value of type T from the profile.
Definition: SampleProfReader.cpp:422
llvm::line_iterator::line_number
int64_t line_number() const
Return the current line number. May return any number at EOF.
Definition: LineIterator.h:66
llvm::sampleprof::FunctionSamples::getCanonicalFnName
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
Definition: SampleProf.h:926
llvm::sampleprof::SampleProfileReaderBinary::readNumber
ErrorOr< T > readNumber()
Read a numeric value of type T from the profile.
Definition: SampleProfReader.cpp:387
llvm::sampleprof::SampleProfileReaderBinary::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition: SampleProfReader.cpp:605
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncProfiles
std::error_code readFuncProfiles()
Definition: SampleProfReader.cpp:748
llvm::sampleprof::SampleProfileReader::Ctx
LLVMContext & Ctx
LLVM context used to emit diagnostics.
Definition: SampleProfReader.h:510
Allocator
Basic Register Allocator
Definition: RegAllocBasic.cpp:146
llvm::sampleprof::SecCommonFlags::SecFlagFlat
@ SecFlagFlat
llvm::sampleprof::SampleProfileReaderCompactBinary::collectFuncsFromModule
bool collectFuncsFromModule() override
Collect functions with definitions in Module M.
Definition: SampleProfReader.cpp:1333
llvm::sampleprof::SecCSNameTable
@ SecCSNameTable
Definition: SampleProf.h:128
LineType::Metadata
@ Metadata
llvm::ErrorOr
Represents either an error or a value T.
Definition: ErrorOr.h:56
llvm::sampleprof::SampleProfileReader::useMD5
virtual bool useMD5()
Return whether names in the profile are all MD5 numbers.
Definition: SampleProfReader.h:489
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:63
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::sampleprof::SampleProfileReaderExtBinaryBase::readOneSection
virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry)
Definition: SampleProfReader.cpp:641
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncOffsetTable
std::error_code readFuncOffsetTable()
Definition: SampleProfReader.cpp:713
llvm::SymbolRemappingParseError
Definition: SymbolRemappingReader.h:69
llvm::sampleprof::SampleProfileReader::dumpFunctionProfile
void dumpFunctionProfile(SampleContext FContext, raw_ostream &OS=dbgs())
Print the profile for FContext on stream OS.
Definition: SampleProfReader.cpp:62
llvm::sampleprof::SecNameTable
@ SecNameTable
Definition: SampleProf.h:124
ParseLine
static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, uint64_t &NumSamples, uint32_t &LineOffset, uint32_t &Discriminator, StringRef &CalleeName, DenseMap< StringRef, uint64_t > &TargetCountMap, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input as line sample.
Definition: SampleProfReader.cpp:139
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readProfileSymbolList
std::error_code readProfileSymbolList()
Definition: SampleProfReader.cpp:848
llvm::sampleprof::SampleProfileReaderCompactBinary::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition: SampleProfReader.cpp:1412
llvm::sampleprof::SecFuncMetadata
@ SecFuncMetadata
Definition: SampleProf.h:127
llvm::StringRef::find_first_of
LLVM_NODISCARD size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
Definition: StringRef.h:410
llvm::sampleprof_error::truncated_name_table
@ truncated_name_table
llvm::sampleprof::SampleProfileReader::ProfileIsCS
bool ProfileIsCS
Whether function profiles are context-sensitive.
Definition: SampleProfReader.h:537
LineType::BodyProfile
@ BodyProfile
llvm::sampleprof::SampleProfileReaderExtBinaryBase::dumpSectionInfo
virtual bool dumpSectionInfo(raw_ostream &OS=dbgs()) override
Definition: SampleProfReader.cpp:1242
llvm::cl::desc
Definition: CommandLine.h:412
raw_ostream.h
ProfileIsFSDisciminator
static cl::opt< bool > ProfileIsFSDisciminator("profile-isfs", cl::Hidden, cl::init(false), cl::desc("Profile uses flow sensitive discriminators"))
llvm::sampleprof::SampleProfileReaderExtBinary::hasFormat
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition: SampleProfReader.cpp:1405
llvm::StringRef::size
LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::sampleprof::SampleProfileReaderGCC::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition: SampleProfReader.cpp:1645
llvm::sampleprof::SampleProfileReaderBinary::readStringIndex
ErrorOr< uint32_t > readStringIndex(T &Table)
Read the string index and check whether it overflows the table.
Definition: SampleProfReader.cpp:437
llvm::ProfileSummaryBuilder::DefaultCutoffs
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
Definition: ProfileCommon.h:65
llvm::handleAllErrors
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
Definition: Error.h:968
llvm::sampleprof_error::truncated
@ truncated
llvm::sampleprof::SampleProfileReaderBinary::Data
const uint8_t * Data
Points to the current location in the buffer.
Definition: SampleProfReader.h:637
llvm::sampleprof::SampleProfileReaderBinary::readHeader
virtual std::error_code readHeader() override
Read and validate the file header.
Definition: SampleProfReader.cpp:1279
llvm::sampleprof::SampleProfileReader::Buffer
std::unique_ptr< MemoryBuffer > Buffer
Memory buffer holding the profile file.
Definition: SampleProfReader.h:513
llvm::sampleprof_error::bad_magic
@ bad_magic
llvm::sampleprof::FunctionSamples::setFunctionHash
void setFunctionHash(uint64_t Hash)
Definition: SampleProf.h:920
llvm::MD5Hash
uint64_t MD5Hash(StringRef Str)
Helper to compute and return lower 64 bits of the given string's MD5 hash.
Definition: MD5.h:122
llvm::sampleprof::SampleProfileReaderExtBinaryBase::collectFuncsFromModule
bool collectFuncsFromModule() override
Collect functions with definitions in Module M.
Definition: SampleProfReader.cpp:704
llvm::sampleprof::SampleProfileReader::ProfileIsProbeBased
bool ProfileIsProbeBased
Whether samples are collected based on pseudo probes.
Definition: SampleProfReader.h:534
llvm::sampleprof::SampleProfileReaderBinary::at_eof
bool at_eof() const
Return true if we've reached the end of file.
Definition: SampleProfReader.h:619
llvm::sampleprof::FunctionSamples::setName
void setName(StringRef FunctionName)
Set the name of the function.
Definition: SampleProf.h:912