LLVM API Documentation

CoverageMapping.h
Go to the documentation of this file.
00001 //=-- CoverageMapping.h - Code coverage mapping support ---------*- C++ -*-=//
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 // Code coverage mapping data is generated by clang and read by
00011 // llvm-cov to show code coverage statistics for a file.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_PROFILEDATA_COVERAGEMAPPING_H_
00016 #define LLVM_PROFILEDATA_COVERAGEMAPPING_H_
00017 
00018 #include "llvm/ADT/ArrayRef.h"
00019 #include "llvm/Support/ErrorOr.h"
00020 #include "llvm/Support/raw_ostream.h"
00021 #include <system_error>
00022 
00023 namespace llvm {
00024 namespace coverage {
00025 
00026 struct CounterExpressions;
00027 
00028 enum CoverageMappingVersion { CoverageMappingVersion1 };
00029 
00030 /// \brief A Counter is an abstract value that describes how to compute the
00031 /// execution count for a region of code using the collected profile count data.
00032 struct Counter {
00033   enum CounterKind { Zero, CounterValueReference, Expression };
00034   static const unsigned EncodingTagBits = 2;
00035   static const unsigned EncodingTagMask = 0x3;
00036   static const unsigned EncodingCounterTagAndExpansionRegionTagBits =
00037       EncodingTagBits + 1;
00038 
00039 private:
00040   CounterKind Kind;
00041   unsigned ID;
00042 
00043   Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
00044 
00045 public:
00046   Counter() : Kind(Zero), ID(0) {}
00047 
00048   CounterKind getKind() const { return Kind; }
00049 
00050   bool isZero() const { return Kind == Zero; }
00051 
00052   bool isExpression() const { return Kind == Expression; }
00053 
00054   unsigned getCounterID() const { return ID; }
00055 
00056   unsigned getExpressionID() const { return ID; }
00057 
00058   bool operator==(const Counter &Other) const {
00059     return Kind == Other.Kind && ID == Other.ID;
00060   }
00061 
00062   /// \brief Return the counter that represents the number zero.
00063   static Counter getZero() { return Counter(); }
00064 
00065   /// \brief Return the counter that corresponds to a specific profile counter.
00066   static Counter getCounter(unsigned CounterId) {
00067     return Counter(CounterValueReference, CounterId);
00068   }
00069 
00070   /// \brief Return the counter that corresponds to a specific
00071   /// addition counter expression.
00072   static Counter getExpression(unsigned ExpressionId) {
00073     return Counter(Expression, ExpressionId);
00074   }
00075 };
00076 
00077 /// \brief A Counter expression is a value that represents an arithmetic
00078 /// operation with two counters.
00079 struct CounterExpression {
00080   enum ExprKind { Subtract, Add };
00081   ExprKind Kind;
00082   Counter LHS, RHS;
00083 
00084   CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
00085       : Kind(Kind), LHS(LHS), RHS(RHS) {}
00086 
00087   bool operator==(const CounterExpression &Other) const {
00088     return Kind == Other.Kind && LHS == Other.LHS && RHS == Other.RHS;
00089   }
00090 };
00091 
00092 /// \brief A Counter expression builder is used to construct the
00093 /// counter expressions. It avoids unecessary duplication
00094 /// and simplifies algebraic expressions.
00095 class CounterExpressionBuilder {
00096   /// \brief A list of all the counter expressions
00097   llvm::SmallVector<CounterExpression, 16> Expressions;
00098   /// \brief An array of terms used in expression simplification.
00099   llvm::SmallVector<int, 16> Terms;
00100 
00101   /// \brief Return the counter which corresponds to the given expression.
00102   ///
00103   /// If the given expression is already stored in the builder, a counter
00104   /// that references that expression is returned. Otherwise, the given
00105   /// expression is added to the builder's collection of expressions.
00106   Counter get(const CounterExpression &E);
00107 
00108   /// \brief Convert the expression tree represented by a counter
00109   /// into a polynomial in the form of K1Counter1 + .. + KNCounterN
00110   /// where K1 .. KN are integer constants that are stored in the Terms array.
00111   void extractTerms(Counter C, int Sign = 1);
00112 
00113   /// \brief Simplifies the given expression tree
00114   /// by getting rid of algebraically redundant operations.
00115   Counter simplify(Counter ExpressionTree);
00116 
00117 public:
00118   CounterExpressionBuilder(unsigned NumCounterValues);
00119 
00120   ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
00121 
00122   /// \brief Return a counter that represents the expression
00123   /// that adds LHS and RHS.
00124   Counter add(Counter LHS, Counter RHS);
00125 
00126   /// \brief Return a counter that represents the expression
00127   /// that subtracts RHS from LHS.
00128   Counter subtract(Counter LHS, Counter RHS);
00129 };
00130 
00131 /// \brief A Counter mapping region associates a source range with
00132 /// a specific counter.
00133 struct CounterMappingRegion {
00134   enum RegionKind {
00135     /// \brief A CodeRegion associates some code with a counter
00136     CodeRegion,
00137 
00138     /// \brief An ExpansionRegion represents a file expansion region that
00139     /// associates a source range with the expansion of a virtual source file,
00140     /// such as for a macro instantiation or #include file.
00141     ExpansionRegion,
00142 
00143     /// \brief A SkippedRegion represents a source range with code that
00144     /// was skipped by a preprocessor or similar means.
00145     SkippedRegion
00146   };
00147 
00148   static const unsigned EncodingHasCodeBeforeBits = 1;
00149 
00150   Counter Count;
00151   unsigned FileID, ExpandedFileID;
00152   unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
00153   RegionKind Kind;
00154   /// \brief A flag that is set to true when there is already code before
00155   /// this region on the same line.
00156   /// This is useful to accurately compute the execution counts for a line.
00157   bool HasCodeBefore;
00158 
00159   CounterMappingRegion(Counter Count, unsigned FileID, unsigned LineStart,
00160                        unsigned ColumnStart, unsigned LineEnd,
00161                        unsigned ColumnEnd, bool HasCodeBefore = false,
00162                        RegionKind Kind = CodeRegion)
00163       : Count(Count), FileID(FileID), ExpandedFileID(0), LineStart(LineStart),
00164         ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd),
00165         Kind(Kind), HasCodeBefore(HasCodeBefore) {}
00166 
00167   inline std::pair<unsigned, unsigned> startLoc() const {
00168     return std::pair<unsigned, unsigned>(LineStart, ColumnStart);
00169   }
00170 
00171   inline std::pair<unsigned, unsigned> endLoc() const {
00172     return std::pair<unsigned, unsigned>(LineEnd, ColumnEnd);
00173   }
00174 
00175   bool operator<(const CounterMappingRegion &Other) const {
00176     if (FileID != Other.FileID)
00177       return FileID < Other.FileID;
00178     return startLoc() < Other.startLoc();
00179   }
00180 
00181   bool contains(const CounterMappingRegion &Other) const {
00182     if (FileID != Other.FileID)
00183       return false;
00184     if (startLoc() > Other.startLoc())
00185       return false;
00186     if (endLoc() < Other.endLoc())
00187       return false;
00188     return true;
00189   }
00190 };
00191 
00192 /// \brief Associates a source range with an execution count.
00193 struct CountedRegion : public CounterMappingRegion {
00194   uint64_t ExecutionCount;
00195 
00196   CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
00197       : CounterMappingRegion(R), ExecutionCount(ExecutionCount) {}
00198 };
00199 
00200 /// \brief A Counter mapping context is used to connect the counters,
00201 /// expressions and the obtained counter values.
00202 class CounterMappingContext {
00203   ArrayRef<CounterExpression> Expressions;
00204   ArrayRef<uint64_t> CounterValues;
00205 
00206 public:
00207   CounterMappingContext(ArrayRef<CounterExpression> Expressions,
00208                         ArrayRef<uint64_t> CounterValues = ArrayRef<uint64_t>())
00209       : Expressions(Expressions), CounterValues(CounterValues) {}
00210 
00211   void dump(const Counter &C, llvm::raw_ostream &OS) const;
00212   void dump(const Counter &C) const { dump(C, llvm::outs()); }
00213 
00214   /// \brief Return the number of times that a region of code associated with
00215   /// this counter was executed.
00216   ErrorOr<int64_t> evaluate(const Counter &C) const;
00217 };
00218 
00219 /// \brief Code coverage information for a single function.
00220 struct FunctionCoverageMapping {
00221   /// \brief Raw function name.
00222   std::string Name;
00223   /// \brief Associated files.
00224   std::vector<std::string> Filenames;
00225   /// \brief Regions in the function along with their counts.
00226   std::vector<CountedRegion> CountedRegions;
00227 
00228   FunctionCoverageMapping(StringRef Name, ArrayRef<StringRef> Filenames)
00229       : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
00230 };
00231 
00232 } // end namespace coverage
00233 } // end namespace llvm
00234 
00235 #endif // LLVM_PROFILEDATA_COVERAGEMAPPING_H_