SampleProfWriter.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. //===- SampleProfWriter.cpp - Write LLVM sample profile data --------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the class that writes LLVM sample profiles. It
  11. // supports two file formats: text and binary. The textual representation
  12. // is useful for debugging and testing purposes. The binary representation
  13. // is more compact, resulting in smaller file sizes. However, they can
  14. // both be used interchangeably.
  15. //
  16. // See lib/ProfileData/SampleProfReader.cpp for documentation on each of the
  17. // supported formats.
  18. //
  19. //===----------------------------------------------------------------------===//
  20. #include "llvm/ProfileData/SampleProfWriter.h"
  21. #include "llvm/Support/Debug.h"
  22. #include "llvm/Support/ErrorOr.h"
  23. #include "llvm/Support/LEB128.h"
  24. #include "llvm/Support/LineIterator.h"
  25. #include "llvm/Support/MemoryBuffer.h"
  26. #include "llvm/Support/Regex.h"
  27. using namespace llvm::sampleprof;
  28. using namespace llvm;
  29. /// \brief Write samples to a text file.
  30. bool SampleProfileWriterText::write(StringRef FName, const FunctionSamples &S) {
  31. if (S.empty())
  32. return true;
  33. OS << FName << ":" << S.getTotalSamples() << ":" << S.getHeadSamples()
  34. << "\n";
  35. for (const auto &I : S.getBodySamples()) {
  36. LineLocation Loc = I.first;
  37. const SampleRecord &Sample = I.second;
  38. if (Loc.Discriminator == 0)
  39. OS << Loc.LineOffset << ": ";
  40. else
  41. OS << Loc.LineOffset << "." << Loc.Discriminator << ": ";
  42. OS << Sample.getSamples();
  43. for (const auto &J : Sample.getCallTargets())
  44. OS << " " << J.first() << ":" << J.second;
  45. OS << "\n";
  46. }
  47. return true;
  48. }
  49. SampleProfileWriterBinary::SampleProfileWriterBinary(StringRef F,
  50. std::error_code &EC)
  51. : SampleProfileWriter(F, EC, sys::fs::F_None) {
  52. if (EC)
  53. return;
  54. // Write the file header.
  55. encodeULEB128(SPMagic(), OS);
  56. encodeULEB128(SPVersion(), OS);
  57. }
  58. /// \brief Write samples to a binary file.
  59. ///
  60. /// \returns true if the samples were written successfully, false otherwise.
  61. bool SampleProfileWriterBinary::write(StringRef FName,
  62. const FunctionSamples &S) {
  63. if (S.empty())
  64. return true;
  65. OS << FName;
  66. encodeULEB128(0, OS);
  67. encodeULEB128(S.getTotalSamples(), OS);
  68. encodeULEB128(S.getHeadSamples(), OS);
  69. encodeULEB128(S.getBodySamples().size(), OS);
  70. for (const auto &I : S.getBodySamples()) {
  71. LineLocation Loc = I.first;
  72. const SampleRecord &Sample = I.second;
  73. encodeULEB128(Loc.LineOffset, OS);
  74. encodeULEB128(Loc.Discriminator, OS);
  75. encodeULEB128(Sample.getSamples(), OS);
  76. encodeULEB128(Sample.getCallTargets().size(), OS);
  77. for (const auto &J : Sample.getCallTargets()) {
  78. std::string Callee = J.first();
  79. unsigned CalleeSamples = J.second;
  80. OS << Callee;
  81. encodeULEB128(0, OS);
  82. encodeULEB128(CalleeSamples, OS);
  83. }
  84. }
  85. return true;
  86. }
  87. /// \brief Create a sample profile writer based on the specified format.
  88. ///
  89. /// \param Filename The file to create.
  90. ///
  91. /// \param Writer The writer to instantiate according to the specified format.
  92. ///
  93. /// \param Format Encoding format for the profile file.
  94. ///
  95. /// \returns an error code indicating the status of the created writer.
  96. ErrorOr<std::unique_ptr<SampleProfileWriter>>
  97. SampleProfileWriter::create(StringRef Filename, SampleProfileFormat Format) {
  98. std::error_code EC;
  99. std::unique_ptr<SampleProfileWriter> Writer;
  100. if (Format == SPF_Binary)
  101. Writer.reset(new SampleProfileWriterBinary(Filename, EC));
  102. else if (Format == SPF_Text)
  103. Writer.reset(new SampleProfileWriterText(Filename, EC));
  104. else
  105. EC = sampleprof_error::unrecognized_format;
  106. if (EC)
  107. return EC;
  108. return std::move(Writer);
  109. }