LLVM API Documentation
00001 //===- SampleProfReader.h - Read LLVM sample profile data -----------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file contains definitions needed for reading sample profiles. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 #ifndef LLVM_PROFILEDATA_SAMPLEPROFREADER_H 00014 #define LLVM_PROFILEDATA_SAMPLEPROFREADER_H 00015 00016 #include "llvm/ADT/DenseMap.h" 00017 #include "llvm/IR/DiagnosticInfo.h" 00018 #include "llvm/IR/Function.h" 00019 #include "llvm/IR/LLVMContext.h" 00020 #include "llvm/IR/Module.h" 00021 #include "llvm/ADT/StringMap.h" 00022 #include "llvm/ADT/StringRef.h" 00023 #include "llvm/ADT/Twine.h" 00024 #include "llvm/Support/ErrorHandling.h" 00025 #include "llvm/Support/raw_ostream.h" 00026 00027 using namespace llvm; 00028 00029 namespace sampleprof { 00030 00031 /// \brief Represents the relative location of an instruction. 00032 /// 00033 /// Instruction locations are specified by the line offset from the 00034 /// beginning of the function (marked by the line where the function 00035 /// header is) and the discriminator value within that line. 00036 /// 00037 /// The discriminator value is useful to distinguish instructions 00038 /// that are on the same line but belong to different basic blocks 00039 /// (e.g., the two post-increment instructions in "if (p) x++; else y++;"). 00040 struct LineLocation { 00041 LineLocation(int L, unsigned D) : LineOffset(L), Discriminator(D) {} 00042 int LineOffset; 00043 unsigned Discriminator; 00044 }; 00045 } // End namespace sampleprof 00046 00047 namespace llvm { 00048 template <> struct DenseMapInfo<sampleprof::LineLocation> { 00049 typedef DenseMapInfo<int> OffsetInfo; 00050 typedef DenseMapInfo<unsigned> DiscriminatorInfo; 00051 static inline sampleprof::LineLocation getEmptyKey() { 00052 return sampleprof::LineLocation(OffsetInfo::getEmptyKey(), 00053 DiscriminatorInfo::getEmptyKey()); 00054 } 00055 static inline sampleprof::LineLocation getTombstoneKey() { 00056 return sampleprof::LineLocation(OffsetInfo::getTombstoneKey(), 00057 DiscriminatorInfo::getTombstoneKey()); 00058 } 00059 static inline unsigned getHashValue(sampleprof::LineLocation Val) { 00060 return DenseMapInfo<std::pair<int, unsigned>>::getHashValue( 00061 std::pair<int, unsigned>(Val.LineOffset, Val.Discriminator)); 00062 } 00063 static inline bool isEqual(sampleprof::LineLocation LHS, 00064 sampleprof::LineLocation RHS) { 00065 return LHS.LineOffset == RHS.LineOffset && 00066 LHS.Discriminator == RHS.Discriminator; 00067 } 00068 }; 00069 } 00070 00071 namespace sampleprof { 00072 00073 typedef DenseMap<LineLocation, unsigned> BodySampleMap; 00074 00075 /// \brief Representation of the samples collected for a function. 00076 /// 00077 /// This data structure contains all the collected samples for the body 00078 /// of a function. Each sample corresponds to a LineLocation instance 00079 /// within the body of the function. 00080 class FunctionSamples { 00081 public: 00082 FunctionSamples() 00083 : TotalSamples(0), TotalHeadSamples(0) {} 00084 void print(raw_ostream & OS); 00085 void addTotalSamples(unsigned Num) { TotalSamples += Num; } 00086 void addHeadSamples(unsigned Num) { TotalHeadSamples += Num; } 00087 void addBodySamples(int LineOffset, unsigned Discriminator, unsigned Num) { 00088 assert(LineOffset >= 0); 00089 BodySamples[LineLocation(LineOffset, Discriminator)] += Num; 00090 } 00091 00092 /// \brief Return the number of samples collected at the given location. 00093 /// Each location is specified by \p LineOffset and \p Discriminator. 00094 unsigned samplesAt(int LineOffset, unsigned Discriminator) { 00095 return BodySamples.lookup(LineLocation(LineOffset, Discriminator)); 00096 } 00097 00098 bool empty() { return BodySamples.empty(); } 00099 00100 private: 00101 /// \brief Total number of samples collected inside this function. 00102 /// 00103 /// Samples are cumulative, they include all the samples collected 00104 /// inside this function and all its inlined callees. 00105 unsigned TotalSamples; 00106 00107 /// \brief Total number of samples collected at the head of the function. 00108 unsigned TotalHeadSamples; 00109 00110 /// \brief Map instruction locations to collected samples. 00111 /// 00112 /// Each entry in this map contains the number of samples 00113 /// collected at the corresponding line offset. All line locations 00114 /// are an offset from the start of the function. 00115 BodySampleMap BodySamples; 00116 }; 00117 00118 /// \brief Sample-based profile reader. 00119 /// 00120 /// Each profile contains sample counts for all the functions 00121 /// executed. Inside each function, statements are annotated with the 00122 /// collected samples on all the instructions associated with that 00123 /// statement. 00124 /// 00125 /// For this to produce meaningful data, the program needs to be 00126 /// compiled with some debug information (at minimum, line numbers: 00127 /// -gline-tables-only). Otherwise, it will be impossible to match IR 00128 /// instructions to the line numbers collected by the profiler. 00129 /// 00130 /// From the profile file, we are interested in collecting the 00131 /// following information: 00132 /// 00133 /// * A list of functions included in the profile (mangled names). 00134 /// 00135 /// * For each function F: 00136 /// 1. The total number of samples collected in F. 00137 /// 00138 /// 2. The samples collected at each line in F. To provide some 00139 /// protection against source code shuffling, line numbers should 00140 /// be relative to the start of the function. 00141 /// 00142 /// The reader supports two file formats: text and bitcode. The text format 00143 /// is useful for debugging and testing, while the bitcode format is more 00144 /// compact. They can both be used interchangeably. 00145 class SampleProfileReader { 00146 public: 00147 SampleProfileReader(const Module &M, StringRef F) 00148 : Profiles(0), Filename(F), M(M) {} 00149 00150 /// \brief Print all the profiles to dbgs(). 00151 void dump(); 00152 00153 /// \brief Load sample profiles from the associated file. 00154 bool load(); 00155 00156 /// \brief Print the profile for \p FName on stream \p OS. 00157 void printFunctionProfile(raw_ostream &OS, StringRef FName); 00158 00159 /// \brief Print the profile for \p FName on dbgs(). 00160 void dumpFunctionProfile(StringRef FName); 00161 00162 /// \brief Return the samples collected for function \p F. 00163 FunctionSamples *getSamplesFor(const Function &F) { 00164 return &Profiles[F.getName()]; 00165 } 00166 00167 /// \brief Report a parse error message. 00168 void reportParseError(int64_t LineNumber, Twine Msg) const { 00169 DiagnosticInfoSampleProfile Diag(Filename.data(), LineNumber, Msg); 00170 M.getContext().diagnose(Diag); 00171 } 00172 00173 protected: 00174 bool loadText(); 00175 bool loadBitcode() { llvm_unreachable("not implemented"); } 00176 00177 /// \brief Map every function to its associated profile. 00178 /// 00179 /// The profile of every function executed at runtime is collected 00180 /// in the structure FunctionSamples. This maps function objects 00181 /// to their corresponding profiles. 00182 StringMap<FunctionSamples> Profiles; 00183 00184 /// \brief Path name to the file holding the profile data. 00185 StringRef Filename; 00186 00187 /// \brief Module being compiled. Used to access the current 00188 /// LLVM context for diagnostics. 00189 const Module &M; 00190 }; 00191 00192 } // End namespace sampleprof 00193 00194 #endif // LLVM_PROFILEDATA_SAMPLEPROFREADER_H