LLVM  15.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/Module.h"
27 #include "llvm/IR/ProfileSummary.h"
32 #include "llvm/Support/ErrorOr.h"
33 #include "llvm/Support/LEB128.h"
35 #include "llvm/Support/MD5.h"
38 #include <algorithm>
39 #include <cstddef>
40 #include <cstdint>
41 #include <limits>
42 #include <memory>
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 (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 TopLevelProbeProfileCount = 0;
248 
249  // DepthMetadata tracks whether we have processed metadata for the current
250  // top-level or nested function profile.
251  uint32_t DepthMetadata = 0;
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  DepthMetadata = 0;
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 (LineTy != LineType::Metadata && Depth == DepthMetadata) {
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  DepthMetadata = 0;
326  break;
327  }
328  case LineType::BodyProfile: {
329  while (InlineStack.size() > Depth) {
330  InlineStack.pop_back();
331  }
332  FunctionSamples &FProfile = *InlineStack.back();
333  for (const auto &name_count : TargetCountMap) {
334  MergeResult(Result, FProfile.addCalledTargetSamples(
335  LineOffset, Discriminator, name_count.first,
336  name_count.second));
337  }
338  MergeResult(Result, FProfile.addBodySamples(LineOffset, Discriminator,
339  NumSamples));
340  break;
341  }
342  case LineType::Metadata: {
343  FunctionSamples &FProfile = *InlineStack.back();
344  if (FunctionHash) {
345  FProfile.setFunctionHash(FunctionHash);
346  if (Depth == 1)
347  ++TopLevelProbeProfileCount;
348  }
351  ProfileIsPreInlined = true;
352  DepthMetadata = Depth;
353  break;
354  }
355  }
356  }
357  }
358 
359  assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
360  "Cannot have both context-sensitive and regular profile");
361  ProfileIsCS = (CSProfileCount > 0);
362  assert((TopLevelProbeProfileCount == 0 ||
363  TopLevelProbeProfileCount == Profiles.size()) &&
364  "Cannot have both probe-based profiles and regular profiles");
365  ProfileIsProbeBased = (TopLevelProbeProfileCount > 0);
369 
370  if (Result == sampleprof_error::success)
371  computeSummary();
372 
373  return Result;
374 }
375 
377  bool result = false;
378 
379  // Check that the first non-comment line is a valid function header.
380  line_iterator LineIt(Buffer, /*SkipBlanks=*/true, '#');
381  if (!LineIt.is_at_eof()) {
382  if ((*LineIt)[0] != ' ') {
383  uint64_t NumSamples, NumHeadSamples;
384  StringRef FName;
385  result = ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
386  }
387  }
388 
389  return result;
390 }
391 
393  unsigned NumBytesRead = 0;
394  std::error_code EC;
395  uint64_t Val = decodeULEB128(Data, &NumBytesRead);
396 
397  if (Val > std::numeric_limits<T>::max())
399  else if (Data + NumBytesRead > End)
401  else
403 
404  if (EC) {
405  reportError(0, EC.message());
406  return EC;
407  }
408 
409  Data += NumBytesRead;
410  return static_cast<T>(Val);
411 }
412 
414  std::error_code EC;
415  StringRef Str(reinterpret_cast<const char *>(Data));
416  if (Data + Str.size() + 1 > End) {
418  reportError(0, EC.message());
419  return EC;
420  }
421 
422  Data += Str.size() + 1;
423  return Str;
424 }
425 
426 template <typename T>
428  std::error_code EC;
429 
430  if (Data + sizeof(T) > End) {
432  reportError(0, EC.message());
433  return EC;
434  }
435 
436  using namespace support;
437  T Val = endian::readNext<T, little, unaligned>(Data);
438  return Val;
439 }
440 
441 template <typename T>
443  std::error_code EC;
444  auto Idx = readNumber<uint32_t>();
445  if (std::error_code EC = Idx.getError())
446  return EC;
447  if (*Idx >= Table.size())
449  return *Idx;
450 }
451 
453  auto Idx = readStringIndex(NameTable);
454  if (std::error_code EC = Idx.getError())
455  return EC;
456 
457  return NameTable[*Idx];
458 }
459 
461  auto FName(readStringFromTable());
462  if (std::error_code EC = FName.getError())
463  return EC;
464  return SampleContext(*FName);
465 }
466 
468  if (!FixedLengthMD5)
470 
471  // read NameTable index.
472  auto Idx = readStringIndex(NameTable);
473  if (std::error_code EC = Idx.getError())
474  return EC;
475 
476  // Check whether the name to be accessed has been accessed before,
477  // if not, read it from memory directly.
478  StringRef &SR = NameTable[*Idx];
479  if (SR.empty()) {
480  const uint8_t *SavedData = Data;
481  Data = MD5NameMemStart + ((*Idx) * sizeof(uint64_t));
482  auto FID = readUnencodedNumber<uint64_t>();
483  if (std::error_code EC = FID.getError())
484  return EC;
485  // Save the string converted from uint64_t in MD5StringBuf. All the
486  // references to the name are all StringRefs refering to the string
487  // in MD5StringBuf.
488  MD5StringBuf->push_back(std::to_string(*FID));
489  SR = MD5StringBuf->back();
490  Data = SavedData;
491  }
492  return SR;
493 }
494 
495 ErrorOr<StringRef> SampleProfileReaderCompactBinary::readStringFromTable() {
496  auto Idx = readStringIndex(NameTable);
497  if (std::error_code EC = Idx.getError())
498  return EC;
499 
500  return StringRef(NameTable[*Idx]);
501 }
502 
503 std::error_code
505  auto NumSamples = readNumber<uint64_t>();
506  if (std::error_code EC = NumSamples.getError())
507  return EC;
508  FProfile.addTotalSamples(*NumSamples);
509 
510  // Read the samples in the body.
511  auto NumRecords = readNumber<uint32_t>();
512  if (std::error_code EC = NumRecords.getError())
513  return EC;
514 
515  for (uint32_t I = 0; I < *NumRecords; ++I) {
516  auto LineOffset = readNumber<uint64_t>();
517  if (std::error_code EC = LineOffset.getError())
518  return EC;
519 
520  if (!isOffsetLegal(*LineOffset)) {
521  return std::error_code();
522  }
523 
524  auto Discriminator = readNumber<uint64_t>();
525  if (std::error_code EC = Discriminator.getError())
526  return EC;
527 
528  auto NumSamples = readNumber<uint64_t>();
529  if (std::error_code EC = NumSamples.getError())
530  return EC;
531 
532  auto NumCalls = readNumber<uint32_t>();
533  if (std::error_code EC = NumCalls.getError())
534  return EC;
535 
536  // Here we handle FS discriminators:
537  uint32_t DiscriminatorVal = (*Discriminator) & getDiscriminatorMask();
538 
539  for (uint32_t J = 0; J < *NumCalls; ++J) {
540  auto CalledFunction(readStringFromTable());
541  if (std::error_code EC = CalledFunction.getError())
542  return EC;
543 
544  auto CalledFunctionSamples = readNumber<uint64_t>();
545  if (std::error_code EC = CalledFunctionSamples.getError())
546  return EC;
547 
548  FProfile.addCalledTargetSamples(*LineOffset, DiscriminatorVal,
549  *CalledFunction, *CalledFunctionSamples);
550  }
551 
552  FProfile.addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
553  }
554 
555  // Read all the samples for inlined function calls.
556  auto NumCallsites = readNumber<uint32_t>();
557  if (std::error_code EC = NumCallsites.getError())
558  return EC;
559 
560  for (uint32_t J = 0; J < *NumCallsites; ++J) {
561  auto LineOffset = readNumber<uint64_t>();
562  if (std::error_code EC = LineOffset.getError())
563  return EC;
564 
565  auto Discriminator = readNumber<uint64_t>();
566  if (std::error_code EC = Discriminator.getError())
567  return EC;
568 
569  auto FName(readStringFromTable());
570  if (std::error_code EC = FName.getError())
571  return EC;
572 
573  // Here we handle FS discriminators:
574  uint32_t DiscriminatorVal = (*Discriminator) & getDiscriminatorMask();
575 
576  FunctionSamples &CalleeProfile = FProfile.functionSamplesAt(
577  LineLocation(*LineOffset, DiscriminatorVal))[std::string(*FName)];
578  CalleeProfile.setName(*FName);
579  if (std::error_code EC = readProfile(CalleeProfile))
580  return EC;
581  }
582 
584 }
585 
586 std::error_code
588  Data = Start;
589  auto NumHeadSamples = readNumber<uint64_t>();
590  if (std::error_code EC = NumHeadSamples.getError())
591  return EC;
592 
594  if (std::error_code EC = FContext.getError())
595  return EC;
596 
597  Profiles[*FContext] = FunctionSamples();
598  FunctionSamples &FProfile = Profiles[*FContext];
599  FProfile.setContext(*FContext);
600  FProfile.addHeadSamples(*NumHeadSamples);
601 
602  if (FContext->hasContext())
603  CSProfileCount++;
604 
605  if (std::error_code EC = readProfile(FProfile))
606  return EC;
608 }
609 
613  while (!at_eof()) {
614  if (std::error_code EC = readFuncProfile(Data))
615  return EC;
616  }
617 
619 }
620 
623  auto ContextIdx = readNumber<uint32_t>();
624  if (std::error_code EC = ContextIdx.getError())
625  return EC;
626  if (*ContextIdx >= CSNameTable->size())
628  return (*CSNameTable)[*ContextIdx];
629 }
630 
633  if (ProfileIsCS) {
634  auto FContext(readContextFromTable());
635  if (std::error_code EC = FContext.getError())
636  return EC;
637  return SampleContext(*FContext);
638  } else {
639  auto FName(readStringFromTable());
640  if (std::error_code EC = FName.getError())
641  return EC;
642  return SampleContext(*FName);
643  }
644 }
645 
647  const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry) {
648  Data = Start;
649  End = Start + Size;
650  switch (Entry.Type) {
651  case SecProfSummary:
652  if (std::error_code EC = readSummary())
653  return EC;
655  Summary->setPartialProfile(true);
662  break;
663  case SecNameTable: {
664  FixedLengthMD5 =
666  bool UseMD5 = hasSecFlag(Entry, SecNameTableFlags::SecFlagMD5Name);
667  assert((!FixedLengthMD5 || UseMD5) &&
668  "If FixedLengthMD5 is true, UseMD5 has to be true");
671  if (std::error_code EC = readNameTableSec(UseMD5))
672  return EC;
673  break;
674  }
675  case SecCSNameTable: {
676  if (std::error_code EC = readCSNameTableSec())
677  return EC;
678  break;
679  }
680  case SecLBRProfile:
681  if (std::error_code EC = readFuncProfiles())
682  return EC;
683  break;
684  case SecFuncOffsetTable:
685  FuncOffsetsOrdered = hasSecFlag(Entry, SecFuncOffsetFlags::SecFlagOrdered);
686  if (std::error_code EC = readFuncOffsetTable())
687  return EC;
688  break;
689  case SecFuncMetadata: {
693  bool HasAttribute =
695  if (std::error_code EC = readFuncMetadata(HasAttribute))
696  return EC;
697  break;
698  }
700  if (std::error_code EC = readProfileSymbolList())
701  return EC;
702  break;
703  default:
704  if (std::error_code EC = readCustomSection(Entry))
705  return EC;
706  break;
707  }
709 }
710 
712  if (!M)
713  return false;
714  FuncsToUse.clear();
715  for (auto &F : *M)
716  FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F));
717  return true;
718 }
719 
721  // If there are more than one FuncOffsetTable, the profile read associated
722  // with previous FuncOffsetTable has to be done before next FuncOffsetTable
723  // is read.
724  FuncOffsetTable.clear();
725 
726  auto Size = readNumber<uint64_t>();
727  if (std::error_code EC = Size.getError())
728  return EC;
729 
730  FuncOffsetTable.reserve(*Size);
731 
732  if (FuncOffsetsOrdered) {
733  OrderedFuncOffsets =
734  std::make_unique<std::vector<std::pair<SampleContext, uint64_t>>>();
735  OrderedFuncOffsets->reserve(*Size);
736  }
737 
738  for (uint32_t I = 0; I < *Size; ++I) {
739  auto FContext(readSampleContextFromTable());
740  if (std::error_code EC = FContext.getError())
741  return EC;
742 
743  auto Offset = readNumber<uint64_t>();
744  if (std::error_code EC = Offset.getError())
745  return EC;
746 
747  FuncOffsetTable[*FContext] = *Offset;
748  if (FuncOffsetsOrdered)
749  OrderedFuncOffsets->emplace_back(*FContext, *Offset);
750  }
751 
753 }
754 
756  // Collect functions used by current module if the Reader has been
757  // given a module.
758  // collectFuncsFromModule uses FunctionSamples::getCanonicalFnName
759  // which will query FunctionSamples::HasUniqSuffix, so it has to be
760  // called after FunctionSamples::HasUniqSuffix is set, i.e. after
761  // NameTable section is read.
762  bool LoadFuncsToBeUsed = collectFuncsFromModule();
763 
764  // When LoadFuncsToBeUsed is false, load all the function profiles.
765  const uint8_t *Start = Data;
766  if (!LoadFuncsToBeUsed) {
767  while (Data < End) {
768  if (std::error_code EC = readFuncProfile(Data))
769  return EC;
770  }
771  assert(Data == End && "More data is read than expected");
772  } else {
773  // Load function profiles on demand.
774  if (Remapper) {
775  for (auto Name : FuncsToUse) {
776  Remapper->insert(Name);
777  }
778  }
779 
780  if (ProfileIsCS) {
781  DenseSet<uint64_t> FuncGuidsToUse;
782  if (useMD5()) {
783  for (auto Name : FuncsToUse)
784  FuncGuidsToUse.insert(Function::getGUID(Name));
785  }
786 
787  // For each function in current module, load all context profiles for
788  // the function as well as their callee contexts which can help profile
789  // guided importing for ThinLTO. This can be achieved by walking
790  // through an ordered context container, where contexts are laid out
791  // as if they were walked in preorder of a context trie. While
792  // traversing the trie, a link to the highest common ancestor node is
793  // kept so that all of its decendants will be loaded.
794  assert(OrderedFuncOffsets.get() &&
795  "func offset table should always be sorted in CS profile");
796  const SampleContext *CommonContext = nullptr;
797  for (const auto &NameOffset : *OrderedFuncOffsets) {
798  const auto &FContext = NameOffset.first;
799  auto FName = FContext.getName();
800  // For function in the current module, keep its farthest ancestor
801  // context. This can be used to load itself and its child and
802  // sibling contexts.
803  if ((useMD5() && FuncGuidsToUse.count(std::stoull(FName.data()))) ||
804  (!useMD5() && (FuncsToUse.count(FName) ||
805  (Remapper && Remapper->exist(FName))))) {
806  if (!CommonContext || !CommonContext->IsPrefixOf(FContext))
807  CommonContext = &FContext;
808  }
809 
810  if (CommonContext == &FContext ||
811  (CommonContext && CommonContext->IsPrefixOf(FContext))) {
812  // Load profile for the current context which originated from
813  // the common ancestor.
814  const uint8_t *FuncProfileAddr = Start + NameOffset.second;
815  assert(FuncProfileAddr < End && "out of LBRProfile section");
816  if (std::error_code EC = readFuncProfile(FuncProfileAddr))
817  return EC;
818  }
819  }
820  } else {
821  if (useMD5()) {
822  for (auto Name : FuncsToUse) {
823  auto GUID = std::to_string(MD5Hash(Name));
824  auto iter = FuncOffsetTable.find(StringRef(GUID));
825  if (iter == FuncOffsetTable.end())
826  continue;
827  const uint8_t *FuncProfileAddr = Start + iter->second;
828  assert(FuncProfileAddr < End && "out of LBRProfile section");
829  if (std::error_code EC = readFuncProfile(FuncProfileAddr))
830  return EC;
831  }
832  } else {
833  for (auto NameOffset : FuncOffsetTable) {
834  SampleContext FContext(NameOffset.first);
835  auto FuncName = FContext.getName();
836  if (!FuncsToUse.count(FuncName) &&
837  (!Remapper || !Remapper->exist(FuncName)))
838  continue;
839  const uint8_t *FuncProfileAddr = Start + NameOffset.second;
840  assert(FuncProfileAddr < End && "out of LBRProfile section");
841  if (std::error_code EC = readFuncProfile(FuncProfileAddr))
842  return EC;
843  }
844  }
845  }
846  Data = End;
847  }
848  assert((CSProfileCount == 0 || CSProfileCount == Profiles.size()) &&
849  "Cannot have both context-sensitive and regular profile");
851  "Section flag should be consistent with actual profile");
853 }
854 
856  if (!ProfSymList)
857  ProfSymList = std::make_unique<ProfileSymbolList>();
858 
859  if (std::error_code EC = ProfSymList->read(Data, End - Data))
860  return EC;
861 
862  Data = End;
864 }
865 
866 std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
867  const uint8_t *SecStart, const uint64_t SecSize,
868  const uint8_t *&DecompressBuf, uint64_t &DecompressBufSize) {
869  Data = SecStart;
870  End = SecStart + SecSize;
871  auto DecompressSize = readNumber<uint64_t>();
872  if (std::error_code EC = DecompressSize.getError())
873  return EC;
874  DecompressBufSize = *DecompressSize;
875 
876  auto CompressSize = readNumber<uint64_t>();
877  if (std::error_code EC = CompressSize.getError())
878  return EC;
879 
882 
883  StringRef CompressedStrings(reinterpret_cast<const char *>(Data),
884  *CompressSize);
885  char *Buffer = Allocator.Allocate<char>(DecompressBufSize);
886  size_t UCSize = DecompressBufSize;
887  llvm::Error E =
888  zlib::uncompress(CompressedStrings, Buffer, UCSize);
889  if (E)
891  DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
893 }
894 
896  const uint8_t *BufStart =
897  reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
898 
899  for (auto &Entry : SecHdrTable) {
900  // Skip empty section.
901  if (!Entry.Size)
902  continue;
903 
904  // Skip sections without context when SkipFlatProf is true.
905  if (SkipFlatProf && hasSecFlag(Entry, SecCommonFlags::SecFlagFlat))
906  continue;
907 
908  const uint8_t *SecStart = BufStart + Entry.Offset;
909  uint64_t SecSize = Entry.Size;
910 
911  // If the section is compressed, decompress it into a buffer
912  // DecompressBuf before reading the actual data. The pointee of
913  // 'Data' will be changed to buffer hold by DecompressBuf
914  // temporarily when reading the actual data.
915  bool isCompressed = hasSecFlag(Entry, SecCommonFlags::SecFlagCompress);
916  if (isCompressed) {
917  const uint8_t *DecompressBuf;
918  uint64_t DecompressBufSize;
919  if (std::error_code EC = decompressSection(
920  SecStart, SecSize, DecompressBuf, DecompressBufSize))
921  return EC;
922  SecStart = DecompressBuf;
923  SecSize = DecompressBufSize;
924  }
925 
926  if (std::error_code EC = readOneSection(SecStart, SecSize, Entry))
927  return EC;
928  if (Data != SecStart + SecSize)
930 
931  // Change the pointee of 'Data' from DecompressBuf to original Buffer.
932  if (isCompressed) {
933  Data = BufStart + Entry.Offset;
934  End = BufStart + Buffer->getBufferSize();
935  }
936  }
937 
939 }
940 
942  // Collect functions used by current module if the Reader has been
943  // given a module.
944  bool LoadFuncsToBeUsed = collectFuncsFromModule();
947  std::vector<uint64_t> OffsetsToUse;
948  if (!LoadFuncsToBeUsed) {
949  // load all the function profiles.
950  for (auto FuncEntry : FuncOffsetTable) {
951  OffsetsToUse.push_back(FuncEntry.second);
952  }
953  } else {
954  // load function profiles on demand.
955  for (auto Name : FuncsToUse) {
956  auto GUID = std::to_string(MD5Hash(Name));
957  auto iter = FuncOffsetTable.find(StringRef(GUID));
958  if (iter == FuncOffsetTable.end())
959  continue;
960  OffsetsToUse.push_back(iter->second);
961  }
962  }
963 
964  for (auto Offset : OffsetsToUse) {
965  const uint8_t *SavedData = Data;
966  if (std::error_code EC = readFuncProfile(
967  reinterpret_cast<const uint8_t *>(Buffer->getBufferStart()) +
968  Offset))
969  return EC;
970  Data = SavedData;
971  }
973 }
974 
975 std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) {
976  if (Magic == SPMagic())
979 }
980 
981 std::error_code SampleProfileReaderExtBinary::verifySPMagic(uint64_t Magic) {
982  if (Magic == SPMagic(SPF_Ext_Binary))
985 }
986 
987 std::error_code
988 SampleProfileReaderCompactBinary::verifySPMagic(uint64_t Magic) {
992 }
993 
995  auto Size = readNumber<uint32_t>();
996  if (std::error_code EC = Size.getError())
997  return EC;
998  NameTable.reserve(*Size + NameTable.size());
999  for (uint32_t I = 0; I < *Size; ++I) {
1000  auto Name(readString());
1001  if (std::error_code EC = Name.getError())
1002  return EC;
1003  NameTable.push_back(*Name);
1004  }
1005 
1007 }
1008 
1010  auto Size = readNumber<uint64_t>();
1011  if (std::error_code EC = Size.getError())
1012  return EC;
1013  MD5StringBuf = std::make_unique<std::vector<std::string>>();
1014  MD5StringBuf->reserve(*Size);
1015  if (FixedLengthMD5) {
1016  // Preallocate and initialize NameTable so we can check whether a name
1017  // index has been read before by checking whether the element in the
1018  // NameTable is empty, meanwhile readStringIndex can do the boundary
1019  // check using the size of NameTable.
1020  NameTable.resize(*Size + NameTable.size());
1021 
1022  MD5NameMemStart = Data;
1023  Data = Data + (*Size) * sizeof(uint64_t);
1025  }
1026  NameTable.reserve(*Size);
1027  for (uint32_t I = 0; I < *Size; ++I) {
1028  auto FID = readNumber<uint64_t>();
1029  if (std::error_code EC = FID.getError())
1030  return EC;
1031  MD5StringBuf->push_back(std::to_string(*FID));
1032  // NameTable is a vector of StringRef. Here it is pushing back a
1033  // StringRef initialized with the last string in MD5stringBuf.
1034  NameTable.push_back(MD5StringBuf->back());
1035  }
1037 }
1038 
1040  if (IsMD5)
1041  return readMD5NameTable();
1043 }
1044 
1045 // Read in the CS name table section, which basically contains a list of context
1046 // vectors. Each element of a context vector, aka a frame, refers to the
1047 // underlying raw function names that are stored in the name table, as well as
1048 // a callsite identifier that only makes sense for non-leaf frames.
1050  auto Size = readNumber<uint32_t>();
1051  if (std::error_code EC = Size.getError())
1052  return EC;
1053 
1054  std::vector<SampleContextFrameVector> *PNameVec =
1055  new std::vector<SampleContextFrameVector>();
1056  PNameVec->reserve(*Size);
1057  for (uint32_t I = 0; I < *Size; ++I) {
1058  PNameVec->emplace_back(SampleContextFrameVector());
1059  auto ContextSize = readNumber<uint32_t>();
1060  if (std::error_code EC = ContextSize.getError())
1061  return EC;
1062  for (uint32_t J = 0; J < *ContextSize; ++J) {
1063  auto FName(readStringFromTable());
1064  if (std::error_code EC = FName.getError())
1065  return EC;
1066  auto LineOffset = readNumber<uint64_t>();
1067  if (std::error_code EC = LineOffset.getError())
1068  return EC;
1069 
1070  if (!isOffsetLegal(*LineOffset))
1071  return std::error_code();
1072 
1073  auto Discriminator = readNumber<uint64_t>();
1074  if (std::error_code EC = Discriminator.getError())
1075  return EC;
1076 
1077  PNameVec->back().emplace_back(
1078  FName.get(), LineLocation(LineOffset.get(), Discriminator.get()));
1079  }
1080  }
1081 
1082  // From this point the underlying object of CSNameTable should be immutable.
1083  CSNameTable.reset(PNameVec);
1085 }
1086 
1087 std::error_code
1088 
1090  FunctionSamples *FProfile) {
1091  if (Data < End) {
1092  if (ProfileIsProbeBased) {
1093  auto Checksum = readNumber<uint64_t>();
1094  if (std::error_code EC = Checksum.getError())
1095  return EC;
1096  if (FProfile)
1097  FProfile->setFunctionHash(*Checksum);
1098  }
1099 
1100  if (ProfileHasAttribute) {
1101  auto Attributes = readNumber<uint32_t>();
1102  if (std::error_code EC = Attributes.getError())
1103  return EC;
1104  if (FProfile)
1105  FProfile->getContext().setAllAttributes(*Attributes);
1106  }
1107 
1108  if (!ProfileIsCS) {
1109  // Read all the attributes for inlined function calls.
1110  auto NumCallsites = readNumber<uint32_t>();
1111  if (std::error_code EC = NumCallsites.getError())
1112  return EC;
1113 
1114  for (uint32_t J = 0; J < *NumCallsites; ++J) {
1115  auto LineOffset = readNumber<uint64_t>();
1116  if (std::error_code EC = LineOffset.getError())
1117  return EC;
1118 
1119  auto Discriminator = readNumber<uint64_t>();
1120  if (std::error_code EC = Discriminator.getError())
1121  return EC;
1122 
1123  auto FContext(readSampleContextFromTable());
1124  if (std::error_code EC = FContext.getError())
1125  return EC;
1126 
1127  FunctionSamples *CalleeProfile = nullptr;
1128  if (FProfile) {
1129  CalleeProfile = const_cast<FunctionSamples *>(
1130  &FProfile->functionSamplesAt(LineLocation(
1131  *LineOffset,
1132  *Discriminator))[std::string(FContext.get().getName())]);
1133  }
1134  if (std::error_code EC =
1135  readFuncMetadata(ProfileHasAttribute, CalleeProfile))
1136  return EC;
1137  }
1138  }
1139  }
1140 
1142 }
1143 
1144 std::error_code
1146  while (Data < End) {
1147  auto FContext(readSampleContextFromTable());
1148  if (std::error_code EC = FContext.getError())
1149  return EC;
1150  FunctionSamples *FProfile = nullptr;
1151  auto It = Profiles.find(*FContext);
1152  if (It != Profiles.end())
1153  FProfile = &It->second;
1154 
1155  if (std::error_code EC = readFuncMetadata(ProfileHasAttribute, FProfile))
1156  return EC;
1157  }
1158 
1159  assert(Data == End && "More data is read than expected");
1161 }
1162 
1163 std::error_code SampleProfileReaderCompactBinary::readNameTable() {
1164  auto Size = readNumber<uint64_t>();
1165  if (std::error_code EC = Size.getError())
1166  return EC;
1167  NameTable.reserve(*Size);
1168  for (uint32_t I = 0; I < *Size; ++I) {
1169  auto FID = readNumber<uint64_t>();
1170  if (std::error_code EC = FID.getError())
1171  return EC;
1172  NameTable.push_back(std::to_string(*FID));
1173  }
1175 }
1176 
1177 std::error_code
1179  SecHdrTableEntry Entry;
1180  auto Type = readUnencodedNumber<uint64_t>();
1181  if (std::error_code EC = Type.getError())
1182  return EC;
1183  Entry.Type = static_cast<SecType>(*Type);
1184 
1185  auto Flags = readUnencodedNumber<uint64_t>();
1186  if (std::error_code EC = Flags.getError())
1187  return EC;
1188  Entry.Flags = *Flags;
1189 
1190  auto Offset = readUnencodedNumber<uint64_t>();
1191  if (std::error_code EC = Offset.getError())
1192  return EC;
1193  Entry.Offset = *Offset;
1194 
1195  auto Size = readUnencodedNumber<uint64_t>();
1196  if (std::error_code EC = Size.getError())
1197  return EC;
1198  Entry.Size = *Size;
1199 
1200  Entry.LayoutIndex = Idx;
1201  SecHdrTable.push_back(std::move(Entry));
1203 }
1204 
1206  auto EntryNum = readUnencodedNumber<uint64_t>();
1207  if (std::error_code EC = EntryNum.getError())
1208  return EC;
1209 
1210  for (uint32_t i = 0; i < (*EntryNum); i++)
1211  if (std::error_code EC = readSecHdrTableEntry(i))
1212  return EC;
1213 
1215 }
1216 
1218  const uint8_t *BufStart =
1219  reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
1220  Data = BufStart;
1221  End = BufStart + Buffer->getBufferSize();
1222 
1223  if (std::error_code EC = readMagicIdent())
1224  return EC;
1225 
1226  if (std::error_code EC = readSecHdrTable())
1227  return EC;
1228 
1230 }
1231 
1233  uint64_t Size = 0;
1234  for (auto &Entry : SecHdrTable) {
1235  if (Entry.Type == Type)
1236  Size += Entry.Size;
1237  }
1238  return Size;
1239 }
1240 
1242  // Sections in SecHdrTable is not necessarily in the same order as
1243  // sections in the profile because section like FuncOffsetTable needs
1244  // to be written after section LBRProfile but needs to be read before
1245  // section LBRProfile, so we cannot simply use the last entry in
1246  // SecHdrTable to calculate the file size.
1247  uint64_t FileSize = 0;
1248  for (auto &Entry : SecHdrTable) {
1249  FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1250  }
1251  return FileSize;
1252 }
1253 
1254 static std::string getSecFlagsStr(const SecHdrTableEntry &Entry) {
1255  std::string Flags;
1257  Flags.append("{compressed,");
1258  else
1259  Flags.append("{");
1260 
1262  Flags.append("flat,");
1263 
1264  switch (Entry.Type) {
1265  case SecNameTable:
1267  Flags.append("fixlenmd5,");
1269  Flags.append("md5,");
1271  Flags.append("uniq,");
1272  break;
1273  case SecProfSummary:
1275  Flags.append("partial,");
1277  Flags.append("context,");
1279  Flags.append("preInlined,");
1281  Flags.append("fs-discriminator,");
1282  break;
1283  case SecFuncOffsetTable:
1285  Flags.append("ordered,");
1286  break;
1287  case SecFuncMetadata:
1289  Flags.append("probe,");
1291  Flags.append("attr,");
1292  break;
1293  default:
1294  break;
1295  }
1296  char &last = Flags.back();
1297  if (last == ',')
1298  last = '}';
1299  else
1300  Flags.append("}");
1301  return Flags;
1302 }
1303 
1305  uint64_t TotalSecsSize = 0;
1306  for (auto &Entry : SecHdrTable) {
1307  OS << getSecName(Entry.Type) << " - Offset: " << Entry.Offset
1308  << ", Size: " << Entry.Size << ", Flags: " << getSecFlagsStr(Entry)
1309  << "\n";
1310  ;
1311  TotalSecsSize += Entry.Size;
1312  }
1313  uint64_t HeaderSize = SecHdrTable.front().Offset;
1314  assert(HeaderSize + TotalSecsSize == getFileSize() &&
1315  "Size of 'header + sections' doesn't match the total size of profile");
1316 
1317  OS << "Header Size: " << HeaderSize << "\n";
1318  OS << "Total Sections Size: " << TotalSecsSize << "\n";
1319  OS << "File Size: " << getFileSize() << "\n";
1320  return true;
1321 }
1322 
1324  // Read and check the magic identifier.
1325  auto Magic = readNumber<uint64_t>();
1326  if (std::error_code EC = Magic.getError())
1327  return EC;
1328  else if (std::error_code EC = verifySPMagic(*Magic))
1329  return EC;
1330 
1331  // Read the version number.
1332  auto Version = readNumber<uint64_t>();
1333  if (std::error_code EC = Version.getError())
1334  return EC;
1335  else if (*Version != SPVersion())
1337 
1339 }
1340 
1342  Data = reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
1343  End = Data + Buffer->getBufferSize();
1344 
1345  if (std::error_code EC = readMagicIdent())
1346  return EC;
1347 
1348  if (std::error_code EC = readSummary())
1349  return EC;
1350 
1351  if (std::error_code EC = readNameTable())
1352  return EC;
1354 }
1355 
1356 std::error_code SampleProfileReaderCompactBinary::readHeader() {
1358  if (std::error_code EC = readFuncOffsetTable())
1359  return EC;
1361 }
1362 
1363 std::error_code SampleProfileReaderCompactBinary::readFuncOffsetTable() {
1364  auto TableOffset = readUnencodedNumber<uint64_t>();
1365  if (std::error_code EC = TableOffset.getError())
1366  return EC;
1367 
1368  const uint8_t *SavedData = Data;
1369  const uint8_t *TableStart =
1370  reinterpret_cast<const uint8_t *>(Buffer->getBufferStart()) +
1371  *TableOffset;
1372  Data = TableStart;
1373 
1374  auto Size = readNumber<uint64_t>();
1375  if (std::error_code EC = Size.getError())
1376  return EC;
1377 
1378  FuncOffsetTable.reserve(*Size);
1379  for (uint32_t I = 0; I < *Size; ++I) {
1380  auto FName(readStringFromTable());
1381  if (std::error_code EC = FName.getError())
1382  return EC;
1383 
1384  auto Offset = readNumber<uint64_t>();
1385  if (std::error_code EC = Offset.getError())
1386  return EC;
1387 
1388  FuncOffsetTable[*FName] = *Offset;
1389  }
1390  End = TableStart;
1391  Data = SavedData;
1393 }
1394 
1396  if (!M)
1397  return false;
1398  FuncsToUse.clear();
1399  for (auto &F : *M)
1400  FuncsToUse.insert(FunctionSamples::getCanonicalFnName(F));
1401  return true;
1402 }
1403 
1404 std::error_code SampleProfileReaderBinary::readSummaryEntry(
1405  std::vector<ProfileSummaryEntry> &Entries) {
1406  auto Cutoff = readNumber<uint64_t>();
1407  if (std::error_code EC = Cutoff.getError())
1408  return EC;
1409 
1410  auto MinBlockCount = readNumber<uint64_t>();
1411  if (std::error_code EC = MinBlockCount.getError())
1412  return EC;
1413 
1414  auto NumBlocks = readNumber<uint64_t>();
1415  if (std::error_code EC = NumBlocks.getError())
1416  return EC;
1417 
1418  Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1420 }
1421 
1423  auto TotalCount = readNumber<uint64_t>();
1424  if (std::error_code EC = TotalCount.getError())
1425  return EC;
1426 
1427  auto MaxBlockCount = readNumber<uint64_t>();
1428  if (std::error_code EC = MaxBlockCount.getError())
1429  return EC;
1430 
1431  auto MaxFunctionCount = readNumber<uint64_t>();
1432  if (std::error_code EC = MaxFunctionCount.getError())
1433  return EC;
1434 
1435  auto NumBlocks = readNumber<uint64_t>();
1436  if (std::error_code EC = NumBlocks.getError())
1437  return EC;
1438 
1439  auto NumFunctions = readNumber<uint64_t>();
1440  if (std::error_code EC = NumFunctions.getError())
1441  return EC;
1442 
1443  auto NumSummaryEntries = readNumber<uint64_t>();
1444  if (std::error_code EC = NumSummaryEntries.getError())
1445  return EC;
1446 
1447  std::vector<ProfileSummaryEntry> Entries;
1448  for (unsigned i = 0; i < *NumSummaryEntries; i++) {
1449  std::error_code EC = readSummaryEntry(Entries);
1450  if (EC != sampleprof_error::success)
1451  return EC;
1452  }
1453  Summary = std::make_unique<ProfileSummary>(
1454  ProfileSummary::PSK_Sample, Entries, *TotalCount, *MaxBlockCount, 0,
1455  *MaxFunctionCount, *NumBlocks, *NumFunctions);
1456 
1458 }
1459 
1461  const uint8_t *Data =
1462  reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
1464  return Magic == SPMagic();
1465 }
1466 
1468  const uint8_t *Data =
1469  reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
1471  return Magic == SPMagic(SPF_Ext_Binary);
1472 }
1473 
1475  const uint8_t *Data =
1476  reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
1478  return Magic == SPMagic(SPF_Compact_Binary);
1479 }
1480 
1482  uint32_t dummy;
1483  if (!GcovBuffer.readInt(dummy))
1486 }
1487 
1489  if (sizeof(T) <= sizeof(uint32_t)) {
1490  uint32_t Val;
1491  if (GcovBuffer.readInt(Val) && Val <= std::numeric_limits<T>::max())
1492  return static_cast<T>(Val);
1493  } else if (sizeof(T) <= sizeof(uint64_t)) {
1494  uint64_t Val;
1495  if (GcovBuffer.readInt64(Val) && Val <= std::numeric_limits<T>::max())
1496  return static_cast<T>(Val);
1497  }
1498 
1499  std::error_code EC = sampleprof_error::malformed;
1500  reportError(0, EC.message());
1501  return EC;
1502 }
1503 
1505  StringRef Str;
1506  if (!GcovBuffer.readString(Str))
1508  return Str;
1509 }
1510 
1512  // Read the magic identifier.
1513  if (!GcovBuffer.readGCDAFormat())
1515 
1516  // Read the version number. Note - the GCC reader does not validate this
1517  // version, but the profile creator generates v704.
1518  GCOV::GCOVVersion version;
1519  if (!GcovBuffer.readGCOVVersion(version))
1521 
1522  if (version != GCOV::V407)
1524 
1525  // Skip the empty integer.
1526  if (std::error_code EC = skipNextWord())
1527  return EC;
1528 
1530 }
1531 
1533  uint32_t Tag;
1534  if (!GcovBuffer.readInt(Tag))
1536 
1537  if (Tag != Expected)
1539 
1540  if (std::error_code EC = skipNextWord())
1541  return EC;
1542 
1544 }
1545 
1547  if (std::error_code EC = readSectionTag(GCOVTagAFDOFileNames))
1548  return EC;
1549 
1550  uint32_t Size;
1551  if (!GcovBuffer.readInt(Size))
1553 
1554  for (uint32_t I = 0; I < Size; ++I) {
1555  StringRef Str;
1556  if (!GcovBuffer.readString(Str))
1558  Names.push_back(std::string(Str));
1559  }
1560 
1562 }
1563 
1565  if (std::error_code EC = readSectionTag(GCOVTagAFDOFunction))
1566  return EC;
1567 
1568  uint32_t NumFunctions;
1569  if (!GcovBuffer.readInt(NumFunctions))
1571 
1572  InlineCallStack Stack;
1573  for (uint32_t I = 0; I < NumFunctions; ++I)
1574  if (std::error_code EC = readOneFunctionProfile(Stack, true, 0))
1575  return EC;
1576 
1577  computeSummary();
1579 }
1580 
1582  const InlineCallStack &InlineStack, bool Update, uint32_t Offset) {
1583  uint64_t HeadCount = 0;
1584  if (InlineStack.size() == 0)
1585  if (!GcovBuffer.readInt64(HeadCount))
1587 
1588  uint32_t NameIdx;
1589  if (!GcovBuffer.readInt(NameIdx))
1591 
1592  StringRef Name(Names[NameIdx]);
1593 
1594  uint32_t NumPosCounts;
1595  if (!GcovBuffer.readInt(NumPosCounts))
1597 
1598  uint32_t NumCallsites;
1599  if (!GcovBuffer.readInt(NumCallsites))
1601 
1602  FunctionSamples *FProfile = nullptr;
1603  if (InlineStack.size() == 0) {
1604  // If this is a top function that we have already processed, do not
1605  // update its profile again. This happens in the presence of
1606  // function aliases. Since these aliases share the same function
1607  // body, there will be identical replicated profiles for the
1608  // original function. In this case, we simply not bother updating
1609  // the profile of the original function.
1610  FProfile = &Profiles[Name];
1611  FProfile->addHeadSamples(HeadCount);
1612  if (FProfile->getTotalSamples() > 0)
1613  Update = false;
1614  } else {
1615  // Otherwise, we are reading an inlined instance. The top of the
1616  // inline stack contains the profile of the caller. Insert this
1617  // callee in the caller's CallsiteMap.
1618  FunctionSamples *CallerProfile = InlineStack.front();
1619  uint32_t LineOffset = Offset >> 16;
1620  uint32_t Discriminator = Offset & 0xffff;
1621  FProfile = &CallerProfile->functionSamplesAt(
1622  LineLocation(LineOffset, Discriminator))[std::string(Name)];
1623  }
1624  FProfile->setName(Name);
1625 
1626  for (uint32_t I = 0; I < NumPosCounts; ++I) {
1627  uint32_t Offset;
1628  if (!GcovBuffer.readInt(Offset))
1630 
1631  uint32_t NumTargets;
1632  if (!GcovBuffer.readInt(NumTargets))
1634 
1635  uint64_t Count;
1636  if (!GcovBuffer.readInt64(Count))
1638 
1639  // The line location is encoded in the offset as:
1640  // high 16 bits: line offset to the start of the function.
1641  // low 16 bits: discriminator.
1642  uint32_t LineOffset = Offset >> 16;
1643  uint32_t Discriminator = Offset & 0xffff;
1644 
1645  InlineCallStack NewStack;
1646  NewStack.push_back(FProfile);
1647  llvm::append_range(NewStack, InlineStack);
1648  if (Update) {
1649  // Walk up the inline stack, adding the samples on this line to
1650  // the total sample count of the callers in the chain.
1651  for (auto CallerProfile : NewStack)
1652  CallerProfile->addTotalSamples(Count);
1653 
1654  // Update the body samples for the current profile.
1655  FProfile->addBodySamples(LineOffset, Discriminator, Count);
1656  }
1657 
1658  // Process the list of functions called at an indirect call site.
1659  // These are all the targets that a function pointer (or virtual
1660  // function) resolved at runtime.
1661  for (uint32_t J = 0; J < NumTargets; J++) {
1662  uint32_t HistVal;
1663  if (!GcovBuffer.readInt(HistVal))
1665 
1666  if (HistVal != HIST_TYPE_INDIR_CALL_TOPN)
1668 
1669  uint64_t TargetIdx;
1670  if (!GcovBuffer.readInt64(TargetIdx))
1672  StringRef TargetName(Names[TargetIdx]);
1673 
1674  uint64_t TargetCount;
1675  if (!GcovBuffer.readInt64(TargetCount))
1677 
1678  if (Update)
1679  FProfile->addCalledTargetSamples(LineOffset, Discriminator,
1680  TargetName, TargetCount);
1681  }
1682  }
1683 
1684  // Process all the inlined callers into the current function. These
1685  // are all the callsites that were inlined into this function.
1686  for (uint32_t I = 0; I < NumCallsites; I++) {
1687  // The offset is encoded as:
1688  // high 16 bits: line offset to the start of the function.
1689  // low 16 bits: discriminator.
1690  uint32_t Offset;
1691  if (!GcovBuffer.readInt(Offset))
1693  InlineCallStack NewStack;
1694  NewStack.push_back(FProfile);
1695  llvm::append_range(NewStack, InlineStack);
1696  if (std::error_code EC = readOneFunctionProfile(NewStack, Update, Offset))
1697  return EC;
1698  }
1699 
1701 }
1702 
1703 /// Read a GCC AutoFDO profile.
1704 ///
1705 /// This format is generated by the Linux Perf conversion tool at
1706 /// https://github.com/google/autofdo.
1708  assert(!ProfileIsFSDisciminator && "Gcc profiles not support FSDisciminator");
1709  // Read the string table.
1710  if (std::error_code EC = readNameTable())
1711  return EC;
1712 
1713  // Read the source profile.
1714  if (std::error_code EC = readFunctionProfiles())
1715  return EC;
1716 
1718 }
1719 
1721  StringRef Magic(reinterpret_cast<const char *>(Buffer.getBufferStart()));
1722  return Magic == "adcg*704";
1723 }
1724 
1726  // If the reader uses MD5 to represent string, we can't remap it because
1727  // we don't know what the original function names were.
1728  if (Reader.useMD5()) {
1730  Reader.getBuffer()->getBufferIdentifier(),
1731  "Profile data remapping cannot be applied to profile data "
1732  "in compact format (original mangled names are not available).",
1733  DS_Warning));
1734  return;
1735  }
1736 
1737  // CSSPGO-TODO: Remapper is not yet supported.
1738  // We will need to remap the entire context string.
1739  assert(Remappings && "should be initialized while creating remapper");
1740  for (auto &Sample : Reader.getProfiles()) {
1741  DenseSet<StringRef> NamesInSample;
1742  Sample.second.findAllNames(NamesInSample);
1743  for (auto &Name : NamesInSample)
1744  if (auto Key = Remappings->insert(Name))
1745  NameMap.insert({Key, Name});
1746  }
1747 
1748  RemappingApplied = true;
1749 }
1750 
1753  if (auto Key = Remappings->lookup(Fname))
1754  return NameMap.lookup(Key);
1755  return None;
1756 }
1757 
1758 /// Prepare a memory buffer for the contents of \p Filename.
1759 ///
1760 /// \returns an error code indicating the status of the buffer.
1762 setupMemoryBuffer(const Twine &Filename) {
1763  auto BufferOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true);
1764  if (std::error_code EC = BufferOrErr.getError())
1765  return EC;
1766  auto Buffer = std::move(BufferOrErr.get());
1767 
1768  // Check the file.
1769  if (uint64_t(Buffer->getBufferSize()) > std::numeric_limits<uint32_t>::max())
1771 
1772  return std::move(Buffer);
1773 }
1774 
1775 /// Create a sample profile reader based on the format of the input file.
1776 ///
1777 /// \param Filename The file to open.
1778 ///
1779 /// \param C The LLVM context to use to emit diagnostics.
1780 ///
1781 /// \param P The FSDiscriminatorPass.
1782 ///
1783 /// \param RemapFilename The file used for profile remapping.
1784 ///
1785 /// \returns an error code indicating the status of the created reader.
1787 SampleProfileReader::create(const std::string Filename, LLVMContext &C,
1789  const std::string RemapFilename) {
1790  auto BufferOrError = setupMemoryBuffer(Filename);
1791  if (std::error_code EC = BufferOrError.getError())
1792  return EC;
1793  return create(BufferOrError.get(), C, P, RemapFilename);
1794 }
1795 
1796 /// Create a sample profile remapper from the given input, to remap the
1797 /// function names in the given profile data.
1798 ///
1799 /// \param Filename The file to open.
1800 ///
1801 /// \param Reader The profile reader the remapper is going to be applied to.
1802 ///
1803 /// \param C The LLVM context to use to emit diagnostics.
1804 ///
1805 /// \returns an error code indicating the status of the created reader.
1808  SampleProfileReader &Reader,
1809  LLVMContext &C) {
1810  auto BufferOrError = setupMemoryBuffer(Filename);
1811  if (std::error_code EC = BufferOrError.getError())
1812  return EC;
1813  return create(BufferOrError.get(), Reader, C);
1814 }
1815 
1816 /// Create a sample profile remapper from the given input, to remap the
1817 /// function names in the given profile data.
1818 ///
1819 /// \param B The memory buffer to create the reader from (assumes ownership).
1820 ///
1821 /// \param C The LLVM context to use to emit diagnostics.
1822 ///
1823 /// \param Reader The profile reader the remapper is going to be applied to.
1824 ///
1825 /// \returns an error code indicating the status of the created reader.
1827 SampleProfileReaderItaniumRemapper::create(std::unique_ptr<MemoryBuffer> &B,
1828  SampleProfileReader &Reader,
1829  LLVMContext &C) {
1830  auto Remappings = std::make_unique<SymbolRemappingReader>();
1831  if (Error E = Remappings->read(*B)) {
1833  std::move(E), [&](const SymbolRemappingParseError &ParseError) {
1834  C.diagnose(DiagnosticInfoSampleProfile(B->getBufferIdentifier(),
1835  ParseError.getLineNum(),
1836  ParseError.getMessage()));
1837  });
1839  }
1840 
1841  return std::make_unique<SampleProfileReaderItaniumRemapper>(
1842  std::move(B), std::move(Remappings), Reader);
1843 }
1844 
1845 /// Create a sample profile reader based on the format of the input data.
1846 ///
1847 /// \param B The memory buffer to create the reader from (assumes ownership).
1848 ///
1849 /// \param C The LLVM context to use to emit diagnostics.
1850 ///
1851 /// \param P The FSDiscriminatorPass.
1852 ///
1853 /// \param RemapFilename The file used for profile remapping.
1854 ///
1855 /// \returns an error code indicating the status of the created reader.
1857 SampleProfileReader::create(std::unique_ptr<MemoryBuffer> &B, LLVMContext &C,
1859  const std::string RemapFilename) {
1860  std::unique_ptr<SampleProfileReader> Reader;
1862  Reader.reset(new SampleProfileReaderRawBinary(std::move(B), C));
1864  Reader.reset(new SampleProfileReaderExtBinary(std::move(B), C));
1866  Reader.reset(new SampleProfileReaderCompactBinary(std::move(B), C));
1868  Reader.reset(new SampleProfileReaderGCC(std::move(B), C));
1870  Reader.reset(new SampleProfileReaderText(std::move(B), C));
1871  else
1873 
1874  if (!RemapFilename.empty()) {
1875  auto ReaderOrErr =
1876  SampleProfileReaderItaniumRemapper::create(RemapFilename, *Reader, C);
1877  if (std::error_code EC = ReaderOrErr.getError()) {
1878  std::string Msg = "Could not create remapper: " + EC.message();
1879  C.diagnose(DiagnosticInfoSampleProfile(RemapFilename, Msg));
1880  return EC;
1881  }
1882  Reader->Remapper = std::move(ReaderOrErr.get());
1883  }
1884 
1885  if (std::error_code EC = Reader->readHeader()) {
1886  return EC;
1887  }
1888 
1889  Reader->setDiscriminatorMaskedBitFrom(P);
1890 
1891  return std::move(Reader);
1892 }
1893 
1894 // For text and GCC file formats, we compute the summary after reading the
1895 // profile. Binary format has the profile summary in its header.
1898  Summary = Builder.computeSummaryForProfiles(Profiles);
1899 }
llvm::sampleprof::SampleProfileReader::ProfileIsFS
bool ProfileIsFS
Whether the function profiles use FS discriminators.
Definition: SampleProfReader.h:546
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:561
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:994
Compression.h
llvm::sampleprof::SampleProfileReader::CSProfileCount
uint32_t CSProfileCount
Number of context-sensitive profiles.
Definition: SampleProfReader.h:543
llvm::sampleprof::SampleProfileReaderText::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition: SampleProfReader.cpp:242
llvm::binaryformat::last
@ last
Definition: Swift.h:19
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:1807
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
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:554
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::sampleprof::FunctionSamples::ProfileIsProbeBased
static bool ProfileIsProbeBased
Definition: SampleProf.h:1112
llvm::sampleprof::FunctionSamples::ProfileIsCS
static bool ProfileIsCS
Definition: SampleProf.h:1114
llvm::line_iterator
A forward iterator which reads text lines from a buffer.
Definition: LineIterator.h:33
llvm::BTF::HeaderSize
@ HeaderSize
Definition: BTF.h:58
llvm::sampleprof::SampleProfileReaderGCC::readFunctionProfiles
std::error_code readFunctionProfiles()
Definition: SampleProfReader.cpp:1564
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:1532
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:158
llvm::Target
Target - Wrapper for Target specific information.
Definition: TargetRegistry.h:145
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readCSNameTableSec
std::error_code readCSNameTableSec()
Definition: SampleProfReader.cpp:1049
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:504
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:319
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readContextFromTable
ErrorOr< SampleContextFrames > readContextFromTable()
Definition: SampleProfReader.cpp:622
llvm::zlib::uncompress
Error uncompress(StringRef InputBuffer, char *UncompressedBuffer, size_t &UncompressedSize)
Definition: Compression.cpp:65
llvm::sampleprof::SecProfSummaryFlags::SecFlagFullContext
@ SecFlagFullContext
SecFlagContext means this is context-sensitive flat profile for CSSPGO.
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readStringFromTable
virtual ErrorOr< StringRef > readStringFromTable() override
Read a string indirectly via the name table.
Definition: SampleProfReader.cpp:467
llvm::GCOV::GCOVVersion
GCOVVersion
Definition: GCOV.h:41
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:1720
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readNameTableSec
std::error_code readNameTableSec(bool IsMD5)
Definition: SampleProfReader.cpp:1039
llvm::SymbolRemappingParseError::getMessage
StringRef getMessage() const
Definition: SymbolRemappingReader.h:84
llvm::sampleprof::SampleContext::toString
std::string toString() const
Definition: SampleProf.h:615
llvm::sampleprof_error::unsupported_version
@ unsupported_version
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:139
llvm::sampleprof::hasSecFlag
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
Definition: SampleProf.h:266
llvm::sampleprof::SampleProfileReaderItaniumRemapper::applyRemapping
void applyRemapping(LLVMContext &Ctx)
Apply remappings to the profile read by Reader.
Definition: SampleProfReader.cpp:1725
llvm::Depth
@ Depth
Definition: SIMachineScheduler.h:36
llvm::sampleprof::ContextShouldBeInlined
@ ContextShouldBeInlined
Definition: SampleProf.h:442
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
DenseMap.h
Module.h
llvm::sampleprof::SampleProfileReaderGCC::readNameTable
std::error_code readNameTable()
Definition: SampleProfReader.cpp:1546
llvm::sampleprof::SecFuncOffsetTable
@ SecFuncOffsetTable
Definition: SampleProf.h:125
llvm::Optional
Definition: APInt.h:33
llvm::sampleprof::SecCommonFlags::SecFlagCompress
@ SecFlagCompress
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readMD5NameTable
std::error_code readMD5NameTable()
Definition: SampleProfReader.cpp:1009
T
#define T
Definition: Mips16ISelLowering.cpp:341
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readSecHdrTableEntry
std::error_code readSecHdrTableEntry(uint32_t Idx)
Definition: SampleProfReader.cpp:1178
llvm::sampleprof::SecNameTableFlags::SecFlagMD5Name
@ SecFlagMD5Name
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readSampleContextFromTable
virtual ErrorOr< SampleContext > readSampleContextFromTable() override
Definition: SampleProfReader.cpp:632
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
llvm::sampleprof::SampleProfileReader::collectFuncsFromModule
virtual bool collectFuncsFromModule()
Collect functions with definitions in Module M.
Definition: SampleProfReader.h:389
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
STLExtras.h
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
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:1581
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:55
llvm::sampleprof::SampleProfileReaderGCC::readNumber
ErrorOr< T > readNumber()
Definition: SampleProfReader.cpp:1488
llvm::sampleprof::SampleProfileReaderBinary::readStringFromTable
virtual ErrorOr< StringRef > readStringFromTable()
Read a string indirectly via the name table.
Definition: SampleProfReader.cpp:452
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:615
llvm::sampleprof::FunctionSamples::HasUniqSuffix
static bool HasUniqSuffix
Whether the profile contains any ".__uniq." suffix in a name.
Definition: SampleProf.h:1126
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:362
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:440
llvm::sampleprof::SampleProfileReaderBinary::NameTable
std::vector< StringRef > NameTable
Function name table.
Definition: SampleProfReader.h:646
llvm::SymbolRemappingParseError::getLineNum
int64_t getLineNum() const
Definition: SymbolRemappingReader.h:83
MD5.h
llvm::sampleprof::SampleProfileReaderCompactBinary::readImpl
std::error_code readImpl() override
Read samples only for functions to use.
Definition: SampleProfReader.cpp:941
llvm::sampleprof::FunctionSamples::getTotalSamples
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
Definition: SampleProf.h:885
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::DS_Warning
@ DS_Warning
Definition: DiagnosticInfo.h:51
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:1460
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:587
llvm::GCOV::V407
@ V407
Definition: GCOV.h:41
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:486
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:1752
llvm::sampleprof::SampleProfileReaderBinary::readString
ErrorOr< StringRef > readString()
Read a string from the profile.
Definition: SampleProfReader.cpp:413
llvm::sampleprof::SPMagic
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
Definition: SampleProf.h:98
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:54
getSecFlagsStr
static std::string getSecFlagsStr(const SecHdrTableEntry &Entry)
Definition: SampleProfReader.cpp:1254
llvm::IndexedInstrProf::Version
const uint64_t Version
Definition: InstrProf.h:1027
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:376
llvm::ProfileSummary::PSK_Sample
@ PSK_Sample
Definition: ProfileSummary.h:47
llvm::Metadata
Root of the metadata hierarchy.
Definition: Metadata.h:62
llvm::sampleprof::SampleContext
Definition: SampleProf.h:501
llvm::None
const NoneType None
Definition: None.h:24
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:514
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:203
llvm::sampleprof::FunctionSamples::ProfileIsFS
static bool ProfileIsFS
If this profile uses flow sensitive discriminators.
Definition: SampleProf.h:1129
llvm::DenseSet< uint64_t >
llvm::cl::opt< bool >
llvm::sampleprof::SPF_Compact_Binary
@ SPF_Compact_Binary
Definition: SampleProf.h:92
llvm::sampleprof::SecProfSummary
@ SecProfSummary
Definition: SampleProf.h:122
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
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:1709
llvm::sampleprof::FunctionSamples::addHeadSamples
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)
Definition: SampleProf.h:744
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readSecHdrTable
std::error_code readSecHdrTable()
Definition: SampleProfReader.cpp:1205
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:1762
llvm::sampleprof::SampleProfileReaderExtBinaryBase::getSectionSize
uint64_t getSectionSize(SecType Type)
Get the total size of all Type sections.
Definition: SampleProfReader.cpp:1232
llvm::sampleprof::SampleProfileReaderGCC
Definition: SampleProfReader.h:858
llvm::sampleprof::FunctionSamples
Representation of the samples collected for a function.
Definition: SampleProf.h:720
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:94
llvm::DenseMap
Definition: DenseMap.h:716
llvm::sampleprof::FunctionSamples::functionSamplesAt
FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc)
Return the function samples at the given callsite location.
Definition: SampleProf.h:859
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:146
llvm::sampleprof::SecLBRProfile
@ SecLBRProfile
Definition: SampleProf.h:130
I
#define I(x, y, z)
Definition: MD5.cpp:58
SampleProfReader.h
Attributes
AMDGPU Kernel Attributes
Definition: AMDGPULowerKernelAttributes.cpp:244
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:432
llvm::sampleprof::FunctionSamples::setContext
void setContext(const SampleContext &FContext)
Definition: SampleProf.h:1120
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:758
llvm::sampleprof::SampleProfileReaderBinary::readSampleContextFromTable
virtual ErrorOr< SampleContext > readSampleContextFromTable()
Definition: SampleProfReader.cpp:460
llvm::sampleprof::SampleContext::setAllAttributes
void setAllAttributes(uint32_t A)
Definition: SampleProf.h:593
llvm::sampleprof_error::malformed
@ malformed
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::sampleprof::SampleProfileReader::ProfileIsPreInlined
bool ProfileIsPreInlined
Whether function profile contains ShouldBeInlined contexts.
Definition: SampleProfReader.h:540
llvm::sampleprof::SampleContext::getName
StringRef getName() const
Definition: SampleProf.h:599
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncMetadata
std::error_code readFuncMetadata(bool ProfileHasAttribute)
Definition: SampleProfReader.cpp:1145
llvm::sampleprof::SampleProfileReaderGCC::readString
ErrorOr< StringRef > readString()
Definition: SampleProfReader.cpp:1504
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:248
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:1787
llvm::zlib::isAvailable
bool isAvailable()
Definition: Compression.cpp:47
llvm::sampleprof::LineLocation
Represents the relative location of an instruction.
Definition: SampleProf.h:282
Builder
assume Assume Builder
Definition: AssumeBundleBuilder.cpp:651
llvm::DiagnosticInfoSampleProfile
Diagnostic information for the sample profiler.
Definition: DiagnosticInfo.h:291
llvm::sampleprof::SampleProfileReaderExtBinary
Definition: SampleProfReader.h:789
llvm::sampleprof::SampleProfileReaderBinary::readMagicIdent
std::error_code readMagicIdent()
Read the contents of Magic number and Version number.
Definition: SampleProfReader.cpp:1323
llvm::sampleprof::SampleProfileReaderBinary::End
const uint8_t * End
Points to the end of the buffer.
Definition: SampleProfReader.h:643
llvm::sampleprof::SampleProfileReaderCompactBinary
Definition: SampleProfReader.h:808
llvm::MergeResult
sampleprof_error MergeResult(sampleprof_error &Accumulator, sampleprof_error Result)
Definition: SampleProf.h:67
isDigit
static bool isDigit(const char C)
Definition: RustDemangle.cpp:176
LineType::CallSiteProfile
@ CallSiteProfile
llvm::sampleprof::SampleContext::IsPrefixOf
bool IsPrefixOf(const SampleContext &That) const
Definition: SampleProf.h:677
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readImpl
std::error_code readImpl() override
Read sample profiles in extensible format from the associated file.
Definition: SampleProfReader.cpp:895
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::msf::Magic
static const char Magic[]
Definition: MSFCommon.h:23
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:752
llvm::append_range
void append_range(Container &C, Range &&R)
Wrapper function to append a range to a container.
Definition: STLExtras.h:1823
llvm::sampleprof::SampleProfileReader::reportError
void reportError(int64_t LineNumber, const Twine &Msg) const
Report a parse error message.
Definition: SampleProfReader.h:441
llvm::sampleprof::SampleProfileReader::computeSummary
void computeSummary()
Compute summary for this profile.
Definition: SampleProfReader.cpp:1896
llvm::sampleprof::SecFuncOffsetFlags::SecFlagOrdered
@ SecFlagOrdered
llvm::sampleprof::getSecName
static std::string getSecName(SecType Type)
Definition: SampleProf.h:133
llvm::AMDGPU::SendMsg::Msg
const CustomOperand< const MCSubtargetInfo & > Msg[]
Definition: AMDGPUAsmUtils.cpp:39
llvm::sampleprof::SampleProfileReaderRawBinary
Definition: SampleProfReader.h:657
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::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::LLVMContext::diagnose
void diagnose(const DiagnosticInfo &DI)
Report a message to the currently installed diagnostic handler.
Definition: LLVMContext.cpp:243
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:50
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:1481
llvm::sampleprof::SPVersion
static uint64_t SPVersion()
Definition: SampleProf.h:115
llvm::sampleprof::SampleProfileReaderBinary::readSummary
std::error_code readSummary()
Read profile summary.
Definition: SampleProfReader.cpp:1422
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::sampleprof::SampleProfileReaderGCC::readHeader
std::error_code readHeader() override
Read and validate the file header.
Definition: SampleProfReader.cpp:1511
llvm::GlobalValue::getGUID
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:559
llvm::sampleprof::SecProfileSymbolList
@ SecProfileSymbolList
Definition: SampleProf.h:124
llvm::sampleprof::FunctionSamples::addTotalSamples
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight=1)
Definition: SampleProf.h:727
llvm::sampleprof::SecType
SecType
Definition: SampleProf.h:120
LineType
LineType
Definition: SampleProfReader.cpp:121
llvm::sampleprof::SampleProfileReader
Sample-based profile reader.
Definition: SampleProfReader.h:342
llvm::sampleprof::SampleProfileReaderExtBinaryBase::getFileSize
uint64_t getFileSize()
Get the total size of header and all sections.
Definition: SampleProfReader.cpp:1241
llvm::sampleprof_error
sampleprof_error
Definition: SampleProf.h:45
llvm::SmallVectorImpl::clear
void clear()
Definition: SmallVector.h:591
llvm::sampleprof_error::zlib_unavailable
@ zlib_unavailable
llvm::sampleprof::SampleContext::hasContext
bool hasContext() const
Definition: SampleProf.h:597
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readHeader
virtual std::error_code readHeader() override
Read and validate the file header.
Definition: SampleProfReader.cpp:1217
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:855
llvm::sampleprof::FunctionSamples::getContext
SampleContext & getContext() const
Definition: SampleProf.h:1118
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:427
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:1022
llvm::sampleprof::SampleProfileReaderBinary::readNumber
ErrorOr< T > readNumber()
Read a numeric value of type T from the profile.
Definition: SampleProfReader.cpp:392
llvm::sampleprof::SampleProfileReaderBinary::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition: SampleProfReader.cpp:610
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncProfiles
std::error_code readFuncProfiles()
Definition: SampleProfReader.cpp:755
llvm::sampleprof::SampleProfileReader::Ctx
LLVMContext & Ctx
LLVM context used to emit diagnostics.
Definition: SampleProfReader.h:510
Allocator
Basic Register Allocator
Definition: RegAllocBasic.cpp:142
llvm::sampleprof::SecCommonFlags::SecFlagFlat
@ SecFlagFlat
llvm::sampleprof::SampleProfileReaderCompactBinary::collectFuncsFromModule
bool collectFuncsFromModule() override
Collect functions with definitions in Module M.
Definition: SampleProfReader.cpp:1395
llvm::sampleprof::SecCSNameTable
@ SecCSNameTable
Definition: SampleProf.h:127
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:85
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::SecProfSummaryFlags::SecFlagIsPreInlined
@ SecFlagIsPreInlined
SecFlagIsPreInlined means this profile contains ShouldBeInlined contexts thus this is CS preinliner c...
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readOneSection
virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry)
Definition: SampleProfReader.cpp:646
llvm::sampleprof::SampleProfileReaderExtBinaryBase::readFuncOffsetTable
std::error_code readFuncOffsetTable()
Definition: SampleProfReader.cpp:720
llvm::SymbolRemappingParseError
Definition: SymbolRemappingReader.h:70
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:123
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:855
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:1474
llvm::sampleprof::SecFuncMetadata
@ SecFuncMetadata
Definition: SampleProf.h:126
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:414
llvm::sampleprof_error::truncated_name_table
@ truncated_name_table
llvm::sampleprof::SampleProfileReader::ProfileIsCS
bool ProfileIsCS
Whether function profiles are context-sensitive flat profiles.
Definition: SampleProfReader.h:537
LineType::BodyProfile
@ BodyProfile
llvm::sampleprof::SampleProfileReaderExtBinaryBase::dumpSectionInfo
virtual bool dumpSectionInfo(raw_ostream &OS=dbgs()) override
Definition: SampleProfReader.cpp:1304
llvm::cl::desc
Definition: CommandLine.h:405
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:1467
llvm::sampleprof::SampleContextFrameVector
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
Definition: SampleProf.h:482
llvm::sampleprof::SampleProfileReaderGCC::readImpl
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition: SampleProfReader.cpp:1707
llvm::sampleprof::SampleProfileReaderBinary::readStringIndex
ErrorOr< uint32_t > readStringIndex(T &Table)
Read the string index and check whether it overflows the table.
Definition: SampleProfReader.cpp:442
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:966
llvm::sampleprof_error::truncated
@ truncated
llvm::sampleprof::SampleProfileReaderBinary::Data
const uint8_t * Data
Points to the current location in the buffer.
Definition: SampleProfReader.h:640
llvm::sampleprof::SampleProfileReaderBinary::readHeader
virtual std::error_code readHeader() override
Read and validate the file header.
Definition: SampleProfReader.cpp:1341
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:1016
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:109
llvm::sampleprof::SampleProfileReaderExtBinaryBase::collectFuncsFromModule
bool collectFuncsFromModule() override
Collect functions with definitions in Module M.
Definition: SampleProfReader.cpp:711
llvm::sampleprof::SampleProfileReader::ProfileIsProbeBased
bool ProfileIsProbeBased
Whether samples are collected based on pseudo probes.
Definition: SampleProfReader.h:534
llvm::sampleprof::FunctionSamples::ProfileIsPreInlined
static bool ProfileIsPreInlined
Definition: SampleProf.h:1116
llvm::sampleprof::SampleProfileReaderBinary::at_eof
bool at_eof() const
Return true if we've reached the end of file.
Definition: SampleProfReader.h:622
llvm::sampleprof::FunctionSamples::setName
void setName(StringRef FunctionName)
Set the name of the function.
Definition: SampleProf.h:1008