LLVM API Documentation

SampleProfReader.h
Go to the documentation of this file.
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