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