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 21 #include "llvm/ProfileData/SampleProfWriter.h" 22 #include "llvm/Support/Debug.h" 23 #include "llvm/Support/ErrorOr.h" 24 #include "llvm/Support/LEB128.h" 25 #include "llvm/Support/LineIterator.h" 26 #include "llvm/Support/MemoryBuffer.h" 27 #include "llvm/Support/Regex.h" 28 29 using namespace llvm::sampleprof; 30 using namespace llvm; 31 32 /// \brief Write samples to a text file. 33 bool SampleProfileWriterText::write(StringRef FName, const FunctionSamples &S) { 34 if (S.empty()) 35 return true; 36 37 OS << FName << ":" << S.getTotalSamples() << ":" << S.getHeadSamples() 38 << "\n"; 39 40 for (const auto &I : S.getBodySamples()) { 41 LineLocation Loc = I.first; 42 const SampleRecord &Sample = I.second; 43 if (Loc.Discriminator == 0) 44 OS << Loc.LineOffset << ": "; 45 else 46 OS << Loc.LineOffset << "." << Loc.Discriminator << ": "; 47 48 OS << Sample.getSamples(); 49 50 for (const auto &J : Sample.getCallTargets()) 51 OS << " " << J.first() << ":" << J.second; 52 OS << "\n"; 53 } 54 55 return true; 56 } 57 58 SampleProfileWriterBinary::SampleProfileWriterBinary(StringRef F, 59 std::error_code &EC) 60 : SampleProfileWriter(F, EC, sys::fs::F_None) { 61 if (EC) 62 return; 63 64 // Write the file header. 65 encodeULEB128(SPMagic(), OS); 66 encodeULEB128(SPVersion(), OS); 67 } 68 69 /// \brief Write samples to a binary file. 70 /// 71 /// \returns true if the samples were written successfully, false otherwise. 72 bool SampleProfileWriterBinary::write(StringRef FName, 73 const FunctionSamples &S) { 74 if (S.empty()) 75 return true; 76 77 OS << FName; 78 encodeULEB128(0, OS); 79 encodeULEB128(S.getTotalSamples(), OS); 80 encodeULEB128(S.getHeadSamples(), OS); 81 encodeULEB128(S.getBodySamples().size(), OS); 82 for (const auto &I : S.getBodySamples()) { 83 LineLocation Loc = I.first; 84 const SampleRecord &Sample = I.second; 85 encodeULEB128(Loc.LineOffset, OS); 86 encodeULEB128(Loc.Discriminator, OS); 87 encodeULEB128(Sample.getSamples(), OS); 88 encodeULEB128(Sample.getCallTargets().size(), OS); 89 for (const auto &J : Sample.getCallTargets()) { 90 std::string Callee = J.first(); 91 unsigned CalleeSamples = J.second; 92 OS << Callee; 93 encodeULEB128(0, OS); 94 encodeULEB128(CalleeSamples, OS); 95 } 96 } 97 98 return true; 99 } 100 101 /// \brief Create a sample profile writer based on the specified format. 102 /// 103 /// \param Filename The file to create. 104 /// 105 /// \param Writer The writer to instantiate according to the specified format. 106 /// 107 /// \param Format Encoding format for the profile file. 108 /// 109 /// \returns an error code indicating the status of the created writer. 110 ErrorOr<std::unique_ptr<SampleProfileWriter>> 111 SampleProfileWriter::create(StringRef Filename, SampleProfileFormat Format) { 112 std::error_code EC; 113 std::unique_ptr<SampleProfileWriter> Writer; 114 115 if (Format == SPF_Binary) 116 Writer.reset(new SampleProfileWriterBinary(Filename, EC)); 117 else if (Format == SPF_Text) 118 Writer.reset(new SampleProfileWriterText(Filename, EC)); 119 else 120 EC = sampleprof_error::unrecognized_format; 121 122 if (EC) 123 return EC; 124 125 return std::move(Writer); 126 } 127