LLVM  12.0.0git
SampleProfWriter.cpp
Go to the documentation of this file.
1 //===- SampleProfWriter.cpp - Write 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 writes LLVM sample profiles. It
10 // supports two file formats: text and binary. The textual representation
11 // is useful for debugging and testing purposes. The binary representation
12 // is more compact, resulting in smaller file sizes. However, they can
13 // both be used interchangeably.
14 //
15 // See lib/ProfileData/SampleProfReader.cpp for documentation on each of the
16 // supported formats.
17 //
18 //===----------------------------------------------------------------------===//
19 
21 #include "llvm/ADT/StringRef.h"
25 #include "llvm/Support/Endian.h"
27 #include "llvm/Support/ErrorOr.h"
29 #include "llvm/Support/LEB128.h"
30 #include "llvm/Support/MD5.h"
32 #include <algorithm>
33 #include <cstdint>
34 #include <memory>
35 #include <set>
36 #include <system_error>
37 #include <utility>
38 #include <vector>
39 
40 using namespace llvm;
41 using namespace sampleprof;
42 
44  const StringMap<FunctionSamples> &ProfileMap) {
45  // Sort the ProfileMap by total samples.
46  typedef std::pair<StringRef, const FunctionSamples *> NameFunctionSamples;
47  std::vector<NameFunctionSamples> V;
48  for (const auto &I : ProfileMap)
49  V.push_back(std::make_pair(I.getKey(), &I.second));
50 
52  V, [](const NameFunctionSamples &A, const NameFunctionSamples &B) {
53  if (A.second->getTotalSamples() == B.second->getTotalSamples())
54  return A.first > B.first;
55  return A.second->getTotalSamples() > B.second->getTotalSamples();
56  });
57 
58  for (const auto &I : V) {
59  if (std::error_code EC = writeSample(*I.second))
60  return EC;
61  }
63 }
64 
65 std::error_code
67  if (std::error_code EC = writeHeader(ProfileMap))
68  return EC;
69 
70  if (std::error_code EC = writeFuncProfiles(ProfileMap))
71  return EC;
72 
74 }
75 
77 SampleProfileWriterExtBinaryBase::getEntryInLayout(SecType Type) {
78  auto SecIt = std::find_if(
79  SectionHdrLayout.begin(), SectionHdrLayout.end(),
80  [=](const auto &Entry) -> bool { return Entry.Type == Type; });
81  return *SecIt;
82 }
83 
84 /// Return the current position and prepare to use it as the start
85 /// position of a section.
87  uint64_t SectionStart = OutputStream->tell();
88  auto &Entry = getEntryInLayout(Type);
89  // Use LocalBuf as a temporary output for writting data.
91  LocalBufStream.swap(OutputStream);
92  return SectionStart;
93 }
94 
95 std::error_code SampleProfileWriterExtBinaryBase::compressAndOutput() {
98  std::string &UncompressedStrings =
99  static_cast<raw_string_ostream *>(LocalBufStream.get())->str();
100  if (UncompressedStrings.size() == 0)
102  auto &OS = *OutputStream;
103  SmallString<128> CompressedStrings;
104  llvm::Error E = zlib::compress(UncompressedStrings, CompressedStrings,
106  if (E)
108  encodeULEB128(UncompressedStrings.size(), OS);
109  encodeULEB128(CompressedStrings.size(), OS);
110  OS << CompressedStrings.str();
111  UncompressedStrings.clear();
113 }
114 
115 /// Add a new section into section header table.
116 std::error_code
118  uint64_t SectionStart) {
119  auto Entry = getEntryInLayout(Type);
121  LocalBufStream.swap(OutputStream);
122  if (std::error_code EC = compressAndOutput())
123  return EC;
124  }
125  SecHdrTable.push_back({Type, Entry.Flags, SectionStart - FileStart,
126  OutputStream->tell() - SectionStart});
128 }
129 
131  const StringMap<FunctionSamples> &ProfileMap) {
132  if (std::error_code EC = writeHeader(ProfileMap))
133  return EC;
134 
135  std::string LocalBuf;
136  LocalBufStream = std::make_unique<raw_string_ostream>(LocalBuf);
137  if (std::error_code EC = writeSections(ProfileMap))
138  return EC;
139 
140  if (std::error_code EC = writeSecHdrTable())
141  return EC;
142 
144 }
145 
146 std::error_code
148  uint64_t Offset = OutputStream->tell();
149  StringRef Name = S.getName();
150  FuncOffsetTable[Name] = Offset - SecLBRProfileStart;
152  return writeBody(S);
153 }
154 
155 std::error_code SampleProfileWriterExtBinary::writeFuncOffsetTable() {
156  auto &OS = *OutputStream;
157 
158  // Write out the table size.
159  encodeULEB128(FuncOffsetTable.size(), OS);
160 
161  // Write out FuncOffsetTable.
162  for (auto entry : FuncOffsetTable) {
163  writeNameIdx(entry.first);
164  encodeULEB128(entry.second, OS);
165  }
167 }
168 
169 std::error_code SampleProfileWriterExtBinary::writeNameTable() {
170  if (!UseMD5)
172 
173  auto &OS = *OutputStream;
174  std::set<StringRef> V;
175  stablizeNameTable(V);
176 
177  // Write out the name table.
178  encodeULEB128(NameTable.size(), OS);
179  for (auto N : V) {
180  encodeULEB128(MD5Hash(N), OS);
181  }
183 }
184 
185 std::error_code SampleProfileWriterExtBinary::writeSections(
186  const StringMap<FunctionSamples> &ProfileMap) {
187  uint64_t SectionStart = markSectionStart(SecProfSummary);
188  computeSummary(ProfileMap);
189  if (auto EC = writeSummary())
190  return EC;
191  if (std::error_code EC = addNewSection(SecProfSummary, SectionStart))
192  return EC;
193 
194  // Generate the name table for all the functions referenced in the profile.
195  SectionStart = markSectionStart(SecNameTable);
196  for (const auto &I : ProfileMap) {
197  addName(I.first());
198  addNames(I.second);
199  }
200  writeNameTable();
201  if (std::error_code EC = addNewSection(SecNameTable, SectionStart))
202  return EC;
203 
204  SectionStart = markSectionStart(SecLBRProfile);
205  SecLBRProfileStart = OutputStream->tell();
206  if (std::error_code EC = writeFuncProfiles(ProfileMap))
207  return EC;
208  if (std::error_code EC = addNewSection(SecLBRProfile, SectionStart))
209  return EC;
210 
211  if (ProfSymList && ProfSymList->toCompress())
212  setToCompressSection(SecProfileSymbolList);
213 
214  SectionStart = markSectionStart(SecProfileSymbolList);
215  if (ProfSymList && ProfSymList->size() > 0)
216  if (std::error_code EC = ProfSymList->write(*OutputStream))
217  return EC;
218  if (std::error_code EC = addNewSection(SecProfileSymbolList, SectionStart))
219  return EC;
220 
221  SectionStart = markSectionStart(SecFuncOffsetTable);
222  if (std::error_code EC = writeFuncOffsetTable())
223  return EC;
224  if (std::error_code EC = addNewSection(SecFuncOffsetTable, SectionStart))
225  return EC;
226 
228 }
229 
231  const StringMap<FunctionSamples> &ProfileMap) {
232  if (std::error_code EC = SampleProfileWriter::write(ProfileMap))
233  return EC;
234  if (std::error_code EC = writeFuncOffsetTable())
235  return EC;
237 }
238 
239 /// Write samples to a text file.
240 ///
241 /// Note: it may be tempting to implement this in terms of
242 /// FunctionSamples::print(). Please don't. The dump functionality is intended
243 /// for debugging and has no specified form.
244 ///
245 /// The format used here is more structured and deliberate because
246 /// it needs to be parsed by the SampleProfileReaderText class.
248  auto &OS = *OutputStream;
249  OS << S.getName() << ":" << S.getTotalSamples();
250  if (Indent == 0)
251  OS << ":" << S.getHeadSamples();
252  OS << "\n";
253 
255  for (const auto &I : SortedSamples.get()) {
256  LineLocation Loc = I->first;
257  const SampleRecord &Sample = I->second;
258  OS.indent(Indent + 1);
259  if (Loc.Discriminator == 0)
260  OS << Loc.LineOffset << ": ";
261  else
262  OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
263 
264  OS << Sample.getSamples();
265 
266  for (const auto &J : Sample.getSortedCallTargets())
267  OS << " " << J.first << ":" << J.second;
268  OS << "\n";
269  }
270 
272  S.getCallsiteSamples());
273  Indent += 1;
274  for (const auto &I : SortedCallsiteSamples.get())
275  for (const auto &FS : I->second) {
276  LineLocation Loc = I->first;
277  const FunctionSamples &CalleeSamples = FS.second;
278  OS.indent(Indent);
279  if (Loc.Discriminator == 0)
280  OS << Loc.LineOffset << ": ";
281  else
282  OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
283  if (std::error_code EC = writeSample(CalleeSamples))
284  return EC;
285  }
286  Indent -= 1;
287 
289 }
290 
292  const auto &ret = NameTable.find(FName);
293  if (ret == NameTable.end())
295  encodeULEB128(ret->second, *OutputStream);
297 }
298 
300  NameTable.insert(std::make_pair(FName, 0));
301 }
302 
304  // Add all the names in indirect call targets.
305  for (const auto &I : S.getBodySamples()) {
306  const SampleRecord &Sample = I.second;
307  for (const auto &J : Sample.getCallTargets())
308  addName(J.first());
309  }
310 
311  // Recursively add all the names for inlined callsites.
312  for (const auto &J : S.getCallsiteSamples())
313  for (const auto &FS : J.second) {
314  const FunctionSamples &CalleeSamples = FS.second;
315  addName(CalleeSamples.getName());
316  addNames(CalleeSamples);
317  }
318 }
319 
320 void SampleProfileWriterBinary::stablizeNameTable(std::set<StringRef> &V) {
321  // Sort the names to make NameTable deterministic.
322  for (const auto &I : NameTable)
323  V.insert(I.first);
324  int i = 0;
325  for (const StringRef &N : V)
326  NameTable[N] = i++;
327 }
328 
330  auto &OS = *OutputStream;
331  std::set<StringRef> V;
332  stablizeNameTable(V);
333 
334  // Write out the name table.
335  encodeULEB128(NameTable.size(), OS);
336  for (auto N : V) {
337  OS << N;
338  encodeULEB128(0, OS);
339  }
341 }
342 
344  auto &OS = *OutputStream;
345 
346  // Fill the slot remembered by TableOffset with the offset of FuncOffsetTable.
347  auto &OFS = static_cast<raw_fd_ostream &>(OS);
348  uint64_t FuncOffsetTableStart = OS.tell();
349  if (OFS.seek(TableOffset) == (uint64_t)-1)
352  Writer.write(FuncOffsetTableStart);
353  if (OFS.seek(FuncOffsetTableStart) == (uint64_t)-1)
355 
356  // Write out the table size.
357  encodeULEB128(FuncOffsetTable.size(), OS);
358 
359  // Write out FuncOffsetTable.
360  for (auto entry : FuncOffsetTable) {
361  writeNameIdx(entry.first);
362  encodeULEB128(entry.second, OS);
363  }
365 }
366 
368  auto &OS = *OutputStream;
369  std::set<StringRef> V;
370  stablizeNameTable(V);
371 
372  // Write out the name table.
373  encodeULEB128(NameTable.size(), OS);
374  for (auto N : V) {
375  encodeULEB128(MD5Hash(N), OS);
376  }
378 }
379 
380 std::error_code
382  auto &OS = *OutputStream;
383  // Write file magic identifier.
384  encodeULEB128(SPMagic(Format), OS);
385  encodeULEB128(SPVersion(), OS);
387 }
388 
390  const StringMap<FunctionSamples> &ProfileMap) {
391  writeMagicIdent(Format);
392 
393  computeSummary(ProfileMap);
394  if (auto EC = writeSummary())
395  return EC;
396 
397  // Generate the name table for all the functions referenced in the profile.
398  for (const auto &I : ProfileMap) {
399  addName(I.first());
400  addNames(I.second);
401  }
402 
403  writeNameTable();
405 }
406 
408  for (auto &Entry : SectionHdrLayout)
410 }
411 
413  addSectionFlag(Type, SecCommonFlags::SecFlagCompress);
414 }
415 
416 void SampleProfileWriterExtBinaryBase::allocSecHdrTable() {
418 
419  Writer.write(static_cast<uint64_t>(SectionHdrLayout.size()));
420  SecHdrTableOffset = OutputStream->tell();
421  for (uint32_t i = 0; i < SectionHdrLayout.size(); i++) {
422  Writer.write(static_cast<uint64_t>(-1));
423  Writer.write(static_cast<uint64_t>(-1));
424  Writer.write(static_cast<uint64_t>(-1));
425  Writer.write(static_cast<uint64_t>(-1));
426  }
427 }
428 
429 std::error_code SampleProfileWriterExtBinaryBase::writeSecHdrTable() {
430  auto &OFS = static_cast<raw_fd_ostream &>(*OutputStream);
431  uint64_t Saved = OutputStream->tell();
432 
433  // Set OutputStream to the location saved in SecHdrTableOffset.
434  if (OFS.seek(SecHdrTableOffset) == (uint64_t)-1)
437 
439  for (uint32_t i = 0; i < SecHdrTable.size(); i++) {
440  IndexMap.insert({static_cast<uint32_t>(SecHdrTable[i].Type), i});
441  }
442 
443  // Write the section header table in the order specified in
444  // SectionHdrLayout. That is the sections order Reader will see.
445  // Note that the sections order in which Reader expects to read
446  // may be different from the order in which Writer is able to
447  // write, so we need to adjust the order in SecHdrTable to be
448  // consistent with SectionHdrLayout when we write SecHdrTable
449  // to the memory.
450  for (uint32_t i = 0; i < SectionHdrLayout.size(); i++) {
451  uint32_t idx = IndexMap[static_cast<uint32_t>(SectionHdrLayout[i].Type)];
452  Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Type));
453  Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Flags));
454  Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Offset));
455  Writer.write(static_cast<uint64_t>(SecHdrTable[idx].Size));
456  }
457 
458  // Reset OutputStream.
459  if (OFS.seek(Saved) == (uint64_t)-1)
461 
463 }
464 
465 std::error_code SampleProfileWriterExtBinaryBase::writeHeader(
466  const StringMap<FunctionSamples> &ProfileMap) {
467  auto &OS = *OutputStream;
468  FileStart = OS.tell();
469  writeMagicIdent(Format);
470 
471  allocSecHdrTable();
473 }
474 
476  const StringMap<FunctionSamples> &ProfileMap) {
478  if (auto EC = SampleProfileWriterBinary::writeHeader(ProfileMap))
479  return EC;
480 
481  // Reserve a slot for the offset of function offset table. The slot will
482  // be populated with the offset of FuncOffsetTable later.
483  TableOffset = OutputStream->tell();
484  Writer.write(static_cast<uint64_t>(-2));
486 }
487 
489  auto &OS = *OutputStream;
490  encodeULEB128(Summary->getTotalCount(), OS);
491  encodeULEB128(Summary->getMaxCount(), OS);
492  encodeULEB128(Summary->getMaxFunctionCount(), OS);
493  encodeULEB128(Summary->getNumCounts(), OS);
494  encodeULEB128(Summary->getNumFunctions(), OS);
495  std::vector<ProfileSummaryEntry> &Entries = Summary->getDetailedSummary();
496  encodeULEB128(Entries.size(), OS);
497  for (auto Entry : Entries) {
498  encodeULEB128(Entry.Cutoff, OS);
499  encodeULEB128(Entry.MinCount, OS);
500  encodeULEB128(Entry.NumCounts, OS);
501  }
503 }
505  auto &OS = *OutputStream;
506 
507  if (std::error_code EC = writeNameIdx(S.getName()))
508  return EC;
509 
511 
512  // Emit all the body samples.
513  encodeULEB128(S.getBodySamples().size(), OS);
514  for (const auto &I : S.getBodySamples()) {
515  LineLocation Loc = I.first;
516  const SampleRecord &Sample = I.second;
517  encodeULEB128(Loc.LineOffset, OS);
518  encodeULEB128(Loc.Discriminator, OS);
519  encodeULEB128(Sample.getSamples(), OS);
520  encodeULEB128(Sample.getCallTargets().size(), OS);
521  for (const auto &J : Sample.getSortedCallTargets()) {
522  StringRef Callee = J.first;
523  uint64_t CalleeSamples = J.second;
524  if (std::error_code EC = writeNameIdx(Callee))
525  return EC;
526  encodeULEB128(CalleeSamples, OS);
527  }
528  }
529 
530  // Recursively emit all the callsite samples.
531  uint64_t NumCallsites = 0;
532  for (const auto &J : S.getCallsiteSamples())
533  NumCallsites += J.second.size();
534  encodeULEB128(NumCallsites, OS);
535  for (const auto &J : S.getCallsiteSamples())
536  for (const auto &FS : J.second) {
537  LineLocation Loc = J.first;
538  const FunctionSamples &CalleeSamples = FS.second;
539  encodeULEB128(Loc.LineOffset, OS);
540  encodeULEB128(Loc.Discriminator, OS);
541  if (std::error_code EC = writeBody(CalleeSamples))
542  return EC;
543  }
544 
546 }
547 
548 /// Write samples of a top-level function to a binary file.
549 ///
550 /// \returns true if the samples were written successfully, false otherwise.
551 std::error_code
554  return writeBody(S);
555 }
556 
557 std::error_code
559  uint64_t Offset = OutputStream->tell();
560  StringRef Name = S.getName();
561  FuncOffsetTable[Name] = Offset;
563  return writeBody(S);
564 }
565 
566 /// Create a sample profile file writer based on the specified format.
567 ///
568 /// \param Filename The file to create.
569 ///
570 /// \param Format Encoding format for the profile file.
571 ///
572 /// \returns an error code indicating the status of the created writer.
575  std::error_code EC;
576  std::unique_ptr<raw_ostream> OS;
577  if (Format == SPF_Binary || Format == SPF_Ext_Binary ||
578  Format == SPF_Compact_Binary)
579  OS.reset(new raw_fd_ostream(Filename, EC, sys::fs::OF_None));
580  else
581  OS.reset(new raw_fd_ostream(Filename, EC, sys::fs::OF_Text));
582  if (EC)
583  return EC;
584 
585  return create(OS, Format);
586 }
587 
588 /// Create a sample profile stream writer based on the specified format.
589 ///
590 /// \param OS The output stream to store the profile data to.
591 ///
592 /// \param Format Encoding format for the profile file.
593 ///
594 /// \returns an error code indicating the status of the created writer.
596 SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
598  std::error_code EC;
599  std::unique_ptr<SampleProfileWriter> Writer;
600 
601  if (Format == SPF_Binary)
602  Writer.reset(new SampleProfileWriterRawBinary(OS));
603  else if (Format == SPF_Ext_Binary)
604  Writer.reset(new SampleProfileWriterExtBinary(OS));
605  else if (Format == SPF_Compact_Binary)
606  Writer.reset(new SampleProfileWriterCompactBinary(OS));
607  else if (Format == SPF_Text)
608  Writer.reset(new SampleProfileWriterText(OS));
609  else if (Format == SPF_GCC)
611  else
613 
614  if (EC)
615  return EC;
616 
617  Writer->Format = Format;
618  return std::move(Writer);
619 }
620 
622  const StringMap<FunctionSamples> &ProfileMap) {
624  for (const auto &I : ProfileMap) {
625  const FunctionSamples &Profile = I.second;
626  Builder.addRecord(Profile);
627  }
628  Summary = Builder.getSummary();
629 }
Represents either an error or a value T.
Definition: ErrorOr.h:56
This class represents lattice values for constants.
Definition: AllocatorList.h:23
Fixup Statepoint Caller Saved
virtual std::error_code write(const StringMap< FunctionSamples > &ProfileMap) override
Write all the sample profiles in the given map of samples.
amdgpu Simplify well known AMD library false FunctionCallee Value const Twine & Name
void addRecord(const sampleprof::FunctionSamples &FS, bool isCallsiteSample=false)
uint64_t MD5Hash(StringRef Str)
Helper to compute and return lower 64 bits of the given string&#39;s MD5 hash.
Definition: MD5.h:109
std::unique_ptr< raw_ostream > OutputStream
Output stream where to emit the profile to.
static const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
Definition: ProfileCommon.h:64
virtual std::error_code write(const StringMap< FunctionSamples > &ProfileMap) override
Write all the sample profiles in the given map of samples.
virtual std::error_code writeHeader(const StringMap< FunctionSamples > &ProfileMap) override
Write a file header for the profile file.
Representation of the samples collected for a function.
Definition: SampleProf.h:357
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:207
std::error_code writeNameIdx(StringRef FName)
virtual std::error_code writeFuncProfiles(const StringMap< FunctionSamples > &ProfileMap)
unsigned size() const
Definition: StringMap.h:91
Error compress(StringRef InputBuffer, SmallVectorImpl< char > &CompressedBuffer, int Level=DefaultCompression)
Definition: Compression.cpp:49
virtual std::error_code writeNameTable() override
std::error_code writeSample(const FunctionSamples &S) override
Write samples to a text file.
StringRef str() const
Explicit conversion to StringRef.
Definition: SmallString.h:266
Representation of a single sample record.
Definition: SampleProf.h:263
virtual std::error_code writeHeader(const StringMap< FunctionSamples > &ProfileMap) override
Write a file header for the profile file.
static constexpr int BestSizeCompression
Definition: Compression.h:28
static uint64_t SPVersion()
Definition: SampleProf.h:114
The file should be opened in text mode on platforms that make this distinction.
Definition: FileSystem.h:767
Sort a LocationT->SampleT map by LocationT.
Definition: SampleProf.h:696
uint64_t getHeadSamples() const
Return the total number of branch samples that have the function as the branch target.
Definition: SampleProf.h:471
virtual std::error_code write(const StringMap< FunctionSamples > &ProfileMap)
Write all the sample profiles in the given map of samples.
std::unique_ptr< ProfileSummary > Summary
Profile summary.
bool isAvailable()
Definition: Compression.cpp:47
uint64_t getSamples() const
Definition: SampleProf.h:309
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
std::error_code addNewSection(SecType Sec, uint64_t SectionStart)
Add a new section into section header table.
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
Definition: SampleProf.h:494
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
assume Assume Builder
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
Definition: SampleProf.h:220
void stablizeNameTable(std::set< StringRef > &V)
virtual std::error_code writeSample(const FunctionSamples &S) override
Write samples of a top-level function to a binary file.
virtual std::error_code writeSample(const FunctionSamples &S)=0
Write sample profiles in S.
void write(ArrayRef< value_type > Val)
Definition: EndianStream.h:55
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
Definition: LEB128.h:80
static ErrorOr< std::unique_ptr< SampleProfileWriter > > create(StringRef Filename, SampleProfileFormat Format)
Profile writer factory.
SampleProfileFormat Format
Profile format.
StringMap - This is an unconventional map that is specialized for handling keys that are "strings"...
Definition: StringMap.h:106
std::error_code writeBody(const FunctionSamples &S)
amdgpu Simplify well known AMD library false FunctionCallee Callee
std::unique_ptr< ProfileSummary > getSummary()
virtual std::error_code writeSample(const FunctionSamples &S) override
Write samples of a top-level function to a binary file.
Adapter to write values to a stream in a particular byte order.
Definition: EndianStream.h:51
uint64_t markSectionStart(SecType Type)
Return the current position and prepare to use it as the start position of a section.
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:408
Represents the relative location of an instruction.
Definition: SampleProf.h:236
#define I(x, y, z)
Definition: MD5.cpp:59
#define N
StringRef getName() const
Return the function name.
Definition: SampleProf.h:567
static void addSecFlag(SecHdrTableEntry &Entry, SecFlagType Flag)
Definition: SampleProf.h:204
uint32_t Size
Definition: Profile.cpp:46
const CallTargetMap & getCallTargets() const
Definition: SampleProf.h:310
size_t size() const
Definition: SmallVector.h:66
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
Definition: SampleProf.h:97
Provides ErrorOr<T> smart pointer.
virtual std::error_code writeHeader(const StringMap< FunctionSamples > &ProfileMap)=0
Write a file header for the profile file.
void stable_sort(R &&Range)
Definition: STLExtras.h:1619
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:521
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
Definition: SampleProf.h:464
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
const CallsiteSampleMap & getCallsiteSamples() const
Return all the callsite samples collected in the body of the function.
Definition: SampleProf.h:497
uint64_t tell() const
tell - Return the current offset with the file.
Definition: raw_ostream.h:118
print Instructions which execute on loop entry
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
const SortedCallTargetSet getSortedCallTargets() const
Definition: SampleProf.h:311
void computeSummary(const StringMap< FunctionSamples > &ProfileMap)
Compute summary for this profile.
virtual std::error_code writeMagicIdent(SampleProfileFormat Format)
virtual std::error_code writeSample(const FunctionSamples &S) override
Write samples of a top-level function to a binary file.
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1518
Sample-based profile writer (text format).