1 //===- SampleProfReader.h - Read 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 reading sample profiles. 11 // 12 //===----------------------------------------------------------------------===// 13 #ifndef LLVM_PROFILEDATA_SAMPLEPROFREADER_H 14 #define LLVM_PROFILEDATA_SAMPLEPROFREADER_H 15 16 #include "llvm/ADT/DenseMap.h" 17 #include "llvm/ADT/StringMap.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/Twine.h" 20 #include "llvm/IR/DiagnosticInfo.h" 21 #include "llvm/IR/Function.h" 22 #include "llvm/IR/LLVMContext.h" 23 #include "llvm/ProfileData/SampleProf.h" 24 #include "llvm/Support/Debug.h" 25 #include "llvm/Support/ErrorHandling.h" 26 #include "llvm/Support/ErrorOr.h" 27 #include "llvm/Support/MemoryBuffer.h" 28 #include "llvm/Support/raw_ostream.h" 29 30 namespace llvm { 31 32 namespace sampleprof { 33 34 /// \brief Sample-based profile reader. 35 /// 36 /// Each profile contains sample counts for all the functions 37 /// executed. Inside each function, statements are annotated with the 38 /// collected samples on all the instructions associated with that 39 /// statement. 40 /// 41 /// For this to produce meaningful data, the program needs to be 42 /// compiled with some debug information (at minimum, line numbers: 43 /// -gline-tables-only). Otherwise, it will be impossible to match IR 44 /// instructions to the line numbers collected by the profiler. 45 /// 46 /// From the profile file, we are interested in collecting the 47 /// following information: 48 /// 49 /// * A list of functions included in the profile (mangled names). 50 /// 51 /// * For each function F: 52 /// 1. The total number of samples collected in F. 53 /// 54 /// 2. The samples collected at each line in F. To provide some 55 /// protection against source code shuffling, line numbers should 56 /// be relative to the start of the function. 57 /// 58 /// The reader supports two file formats: text and binary. The text format 59 /// is useful for debugging and testing, while the binary format is more 60 /// compact. They can both be used interchangeably. 61 class SampleProfileReader { 62 public: SampleProfileReader(std::unique_ptr<MemoryBuffer> B,LLVMContext & C)63 SampleProfileReader(std::unique_ptr<MemoryBuffer> B, LLVMContext &C) 64 : Profiles(0), Ctx(C), Buffer(std::move(B)) {} 65 ~SampleProfileReader()66 virtual ~SampleProfileReader() {} 67 68 /// \brief Read and validate the file header. 69 virtual std::error_code readHeader() = 0; 70 71 /// \brief Read sample profiles from the associated file. 72 virtual std::error_code read() = 0; 73 74 /// \brief Print the profile for \p FName on stream \p OS. 75 void dumpFunctionProfile(StringRef FName, raw_ostream &OS = dbgs()); 76 77 /// \brief Print all the profiles on stream \p OS. 78 void dump(raw_ostream &OS = dbgs()); 79 80 /// \brief Return the samples collected for function \p F. getSamplesFor(const Function & F)81 FunctionSamples *getSamplesFor(const Function &F) { 82 return &Profiles[F.getName()]; 83 } 84 85 /// \brief Return all the profiles. getProfiles()86 StringMap<FunctionSamples> &getProfiles() { return Profiles; } 87 88 /// \brief Report a parse error message. reportParseError(int64_t LineNumber,Twine Msg)89 void reportParseError(int64_t LineNumber, Twine Msg) const { 90 Ctx.diagnose(DiagnosticInfoSampleProfile(Buffer->getBufferIdentifier(), 91 LineNumber, Msg)); 92 } 93 94 /// \brief Create a sample profile reader appropriate to the file format. 95 static ErrorOr<std::unique_ptr<SampleProfileReader>> 96 create(StringRef Filename, LLVMContext &C); 97 98 protected: 99 /// \brief Map every function to its associated profile. 100 /// 101 /// The profile of every function executed at runtime is collected 102 /// in the structure FunctionSamples. This maps function objects 103 /// to their corresponding profiles. 104 StringMap<FunctionSamples> Profiles; 105 106 /// \brief LLVM context used to emit diagnostics. 107 LLVMContext &Ctx; 108 109 /// \brief Memory buffer holding the profile file. 110 std::unique_ptr<MemoryBuffer> Buffer; 111 }; 112 113 class SampleProfileReaderText : public SampleProfileReader { 114 public: SampleProfileReaderText(std::unique_ptr<MemoryBuffer> B,LLVMContext & C)115 SampleProfileReaderText(std::unique_ptr<MemoryBuffer> B, LLVMContext &C) 116 : SampleProfileReader(std::move(B), C) {} 117 118 /// \brief Read and validate the file header. readHeader()119 std::error_code readHeader() override { return sampleprof_error::success; } 120 121 /// \brief Read sample profiles from the associated file. 122 std::error_code read() override; 123 }; 124 125 class SampleProfileReaderBinary : public SampleProfileReader { 126 public: SampleProfileReaderBinary(std::unique_ptr<MemoryBuffer> B,LLVMContext & C)127 SampleProfileReaderBinary(std::unique_ptr<MemoryBuffer> B, LLVMContext &C) 128 : SampleProfileReader(std::move(B), C), Data(nullptr), End(nullptr) {} 129 130 /// \brief Read and validate the file header. 131 std::error_code readHeader() override; 132 133 /// \brief Read sample profiles from the associated file. 134 std::error_code read() override; 135 136 /// \brief Return true if \p Buffer is in the format supported by this class. 137 static bool hasFormat(const MemoryBuffer &Buffer); 138 139 protected: 140 /// \brief Read a numeric value of type T from the profile. 141 /// 142 /// If an error occurs during decoding, a diagnostic message is emitted and 143 /// EC is set. 144 /// 145 /// \returns the read value. 146 template <typename T> ErrorOr<T> readNumber(); 147 148 /// \brief Read a string from the profile. 149 /// 150 /// If an error occurs during decoding, a diagnostic message is emitted and 151 /// EC is set. 152 /// 153 /// \returns the read value. 154 ErrorOr<StringRef> readString(); 155 156 /// \brief Return true if we've reached the end of file. at_eof()157 bool at_eof() const { return Data >= End; } 158 159 /// \brief Points to the current location in the buffer. 160 const uint8_t *Data; 161 162 /// \brief Points to the end of the buffer. 163 const uint8_t *End; 164 }; 165 166 } // End namespace sampleprof 167 168 } // End namespace llvm 169 170 #endif // LLVM_PROFILEDATA_SAMPLEPROFREADER_H 171