1 //===- SampleProfWriter.h - 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 contains definitions needed for writing sample profiles. 11 // 12 //===----------------------------------------------------------------------===// 13 #ifndef LLVM_PROFILEDATA_SAMPLEPROFWRITER_H 14 #define LLVM_PROFILEDATA_SAMPLEPROFWRITER_H 15 16 #include "llvm/ADT/MapVector.h" 17 #include "llvm/ADT/StringRef.h" 18 #include "llvm/IR/Function.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/ProfileData/SampleProf.h" 21 #include "llvm/Support/ErrorOr.h" 22 #include "llvm/Support/FileSystem.h" 23 #include "llvm/Support/raw_ostream.h" 24 25 namespace llvm { 26 27 namespace sampleprof { 28 29 enum SampleProfileFormat { SPF_None = 0, SPF_Text, SPF_Binary, SPF_GCC }; 30 31 /// \brief Sample-based profile writer. Base class. 32 class SampleProfileWriter { 33 public: 34 SampleProfileWriter(StringRef Filename, std::error_code &EC, 35 sys::fs::OpenFlags Flags) 36 : OS(Filename, EC, Flags) {} 37 virtual ~SampleProfileWriter() {} 38 39 /// Write sample profiles in \p S for function \p FName. 40 /// 41 /// \returns status code of the file update operation. 42 virtual std::error_code write(StringRef FName, const FunctionSamples &S) = 0; 43 44 /// Write all the sample profiles in the given map of samples. 45 /// 46 /// \returns status code of the file update operation. 47 std::error_code write(const StringMap<FunctionSamples> &ProfileMap) { 48 if (std::error_code EC = writeHeader(ProfileMap)) 49 return EC; 50 51 for (const auto &I : ProfileMap) { 52 StringRef FName = I.first(); 53 const FunctionSamples &Profile = I.second; 54 if (std::error_code EC = write(FName, Profile)) 55 return EC; 56 } 57 return sampleprof_error::success; 58 } 59 60 /// Profile writer factory. 61 /// 62 /// Create a new writer based on the value of \p Format. 63 static ErrorOr<std::unique_ptr<SampleProfileWriter>> 64 create(StringRef Filename, SampleProfileFormat Format); 65 66 protected: 67 /// \brief Write a file header for the profile file. 68 virtual std::error_code 69 writeHeader(const StringMap<FunctionSamples> &ProfileMap) = 0; 70 71 /// \brief Output stream where to emit the profile to. 72 raw_fd_ostream OS; 73 }; 74 75 /// \brief Sample-based profile writer (text format). 76 class SampleProfileWriterText : public SampleProfileWriter { 77 public: 78 SampleProfileWriterText(StringRef F, std::error_code &EC) 79 : SampleProfileWriter(F, EC, sys::fs::F_Text), Indent(0) {} 80 81 std::error_code write(StringRef FName, const FunctionSamples &S) override; 82 83 protected: 84 std::error_code 85 writeHeader(const StringMap<FunctionSamples> &ProfileMap) override { 86 return sampleprof_error::success; 87 } 88 89 private: 90 /// Indent level to use when writing. 91 /// 92 /// This is used when printing inlined callees. 93 unsigned Indent; 94 }; 95 96 /// \brief Sample-based profile writer (binary format). 97 class SampleProfileWriterBinary : public SampleProfileWriter { 98 public: 99 SampleProfileWriterBinary(StringRef F, std::error_code &EC) 100 : SampleProfileWriter(F, EC, sys::fs::F_None), NameTable() {} 101 102 std::error_code write(StringRef F, const FunctionSamples &S) override; 103 104 protected: 105 std::error_code 106 writeHeader(const StringMap<FunctionSamples> &ProfileMap) override; 107 std::error_code writeNameIdx(StringRef FName); 108 std::error_code writeBody(StringRef FName, const FunctionSamples &S); 109 110 private: 111 void addName(StringRef FName); 112 void addNames(const FunctionSamples &S); 113 114 MapVector<StringRef, uint32_t> NameTable; 115 }; 116 117 } // End namespace sampleprof 118 119 } // End namespace llvm 120 121 #endif // LLVM_PROFILEDATA_SAMPLEPROFWRITER_H 122