Add code coverage mapping data, reader, and writer.
[oota-llvm.git] / include / llvm / ProfileData / CoverageMapping.h
1 //=-- CoverageMapping.h - Code coverage mapping support ---------*- C++ -*-=//
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 // Code coverage mapping data is generated by clang and read by
11 // llvm-cov to show code coverage statistics for a file.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_PROFILEDATA_COVERAGEMAPPING_H_
16 #define LLVM_PROFILEDATA_COVERAGEMAPPING_H_
17
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include <system_error>
21
22 namespace llvm {
23 namespace coverage {
24
25 struct CounterExpressions;
26
27 enum CoverageMappingVersion { CoverageMappingVersion1 };
28
29 /// \brief A Counter is an abstract value that describes how to compute the
30 /// execution count for a region of code using the collected profile count data.
31 struct Counter {
32   enum CounterKind { Zero, CounterValueReference, Expression };
33   static const unsigned EncodingTagBits = 2;
34   static const unsigned EncodingTagMask = 0x3;
35   static const unsigned EncodingCounterTagAndExpansionRegionTagBits =
36       EncodingTagBits + 1;
37
38 private:
39   CounterKind Kind;
40   unsigned ID;
41
42   Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
43
44 public:
45   Counter() : Kind(Zero), ID(0) {}
46
47   CounterKind getKind() const { return Kind; }
48
49   bool isZero() const { return Kind == Zero; }
50
51   bool isExpression() const { return Kind == Expression; }
52
53   unsigned getCounterID() const { return ID; }
54
55   unsigned getExpressionID() const { return ID; }
56
57   bool operator==(const Counter &Other) const {
58     return Kind == Other.Kind && ID == Other.ID;
59   }
60
61   /// \brief Return the counter that represents the number zero.
62   static Counter getZero() { return Counter(); }
63
64   /// \brief Return the counter that corresponds to a specific profile counter.
65   static Counter getCounter(unsigned CounterId) {
66     return Counter(CounterValueReference, CounterId);
67   }
68
69   /// \brief Return the counter that corresponds to a specific
70   /// addition counter expression.
71   static Counter getExpression(unsigned ExpressionId) {
72     return Counter(Expression, ExpressionId);
73   }
74 };
75
76 /// \brief A Counter expression is a value that represents an arithmetic
77 /// operation with two counters.
78 struct CounterExpression {
79   enum ExprKind { Subtract, Add };
80   ExprKind Kind;
81   Counter LHS, RHS;
82
83   CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
84       : Kind(Kind), LHS(LHS), RHS(RHS) {}
85
86   bool operator==(const CounterExpression &Other) const {
87     return Kind == Other.Kind && LHS == Other.LHS && RHS == Other.RHS;
88   }
89 };
90
91 /// \brief A Counter expression builder is used to construct the
92 /// counter expressions. It avoids unecessary duplication
93 /// and simplifies algebraic expressions.
94 class CounterExpressionBuilder {
95   /// \brief A list of all the counter expressions
96   llvm::SmallVector<CounterExpression, 16> Expressions;
97   /// \brief An array of terms used in expression simplification.
98   llvm::SmallVector<int, 16> Terms;
99
100   /// \brief Return the counter which corresponds to the given expression.
101   ///
102   /// If the given expression is already stored in the builder, a counter
103   /// that references that expression is returned. Otherwise, the given
104   /// expression is added to the builder's collection of expressions.
105   Counter get(const CounterExpression &E);
106
107   /// \brief Convert the expression tree represented by a counter
108   /// into a polynomial in the form of K1Counter1 + .. + KNCounterN
109   /// where K1 .. KN are integer constants that are stored in the Terms array.
110   void extractTerms(Counter C, int Sign = 1);
111
112   /// \brief Simplifies the given expression tree
113   /// by getting rid of algebraically redundant operations.
114   Counter simplify(Counter ExpressionTree);
115
116 public:
117   CounterExpressionBuilder(unsigned NumCounterValues);
118
119   ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
120
121   /// \brief Return a counter that represents the expression
122   /// that adds LHS and RHS.
123   Counter add(Counter LHS, Counter RHS);
124
125   /// \brief Return a counter that represents the expression
126   /// that subtracts RHS from LHS.
127   Counter subtract(Counter LHS, Counter RHS);
128 };
129
130 /// \brief A Counter mapping region associates a source range with
131 /// a specific counter.
132 struct CounterMappingRegion {
133   enum RegionKind {
134     /// \brief A CodeRegion associates some code with a counter
135     CodeRegion,
136
137     /// \brief An ExpansionRegion represents a file expansion region that
138     /// associates a source range with the expansion of a virtual source file,
139     /// such as for a macro instantiation or #include file.
140     ExpansionRegion,
141
142     /// \brief An EmptyRegion represents a source range without code,
143     /// but with a distinct counter.
144     EmptyRegion,
145
146     /// \brief A SkippedRegion represents a source range with code that
147     /// was skipped by a preprocessor or similar means.
148     SkippedRegion
149   };
150
151   Counter Count;
152   unsigned FileID, ExpandedFileID;
153   unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
154   RegionKind Kind;
155
156   CounterMappingRegion(Counter Count, unsigned FileID, unsigned LineStart,
157                        unsigned ColumnStart, unsigned LineEnd,
158                        unsigned ColumnEnd, RegionKind Kind = CodeRegion)
159       : Count(Count), FileID(FileID), ExpandedFileID(0), LineStart(LineStart),
160         ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd),
161         Kind(Kind) {}
162
163   bool operator<(const CounterMappingRegion &Other) const {
164     if (FileID != Other.FileID)
165       return FileID < Other.FileID;
166     if (LineStart == Other.LineStart)
167       return ColumnStart < Other.ColumnStart;
168     return LineStart < Other.LineStart;
169   }
170 };
171
172 /// \brief A Counter mapping context is used to connect the counters,
173 /// expressions and the obtained counter values.
174 class CounterMappingContext {
175   ArrayRef<CounterExpression> Expressions;
176   ArrayRef<uint64_t> CounterValues;
177
178 public:
179   CounterMappingContext(ArrayRef<CounterExpression> Expressions,
180                         ArrayRef<uint64_t> CounterValues = ArrayRef<uint64_t>())
181       : Expressions(Expressions), CounterValues(CounterValues) {}
182
183   void dump(const Counter &C, llvm::raw_ostream &OS) const;
184   void dump(const Counter &C) const { dump(C, llvm::outs()); }
185
186   /// \brief Return the number of times that a region of code
187   /// associated with this counter was executed.
188   int64_t evaluate(const Counter &C, std::error_code *Error) const;
189   int64_t evaluate(const Counter &C, std::error_code &Error) const {
190     Error.clear();
191     return evaluate(C, &Error);
192   }
193 };
194
195 } // end namespace coverage
196 } // end namespace llvm
197
198 #endif // LLVM_PROFILEDATA_COVERAGEMAPPING_H_