LLVM API Documentation
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_