llvm-6502/include/llvm/ProfileData/CoverageMapping.h
Justin Bogner baca001683 llvm-cov: Simplify CounterMappingRegion, pushing logic to its user
A single function in SourceCoverageDataManager was the only user of
some of the comparisons in CounterMappingRegion, and at this point we
know that only one file is relevant. This lets us use slightly simpler
logic directly in the client.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@217745 91177308-0d34-0410-b5e6-96231b3b80d8
2014-09-15 03:41:01 +00:00

236 lines
7.9 KiB
C++

//=-- CoverageMapping.h - Code coverage mapping support ---------*- C++ -*-=//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Code coverage mapping data is generated by clang and read by
// llvm-cov to show code coverage statistics for a file.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_PROFILEDATA_COVERAGEMAPPING_H_
#define LLVM_PROFILEDATA_COVERAGEMAPPING_H_
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/raw_ostream.h"
#include <system_error>
namespace llvm {
namespace coverage {
struct CounterExpressions;
enum CoverageMappingVersion { CoverageMappingVersion1 };
/// \brief A Counter is an abstract value that describes how to compute the
/// execution count for a region of code using the collected profile count data.
struct Counter {
enum CounterKind { Zero, CounterValueReference, Expression };
static const unsigned EncodingTagBits = 2;
static const unsigned EncodingTagMask = 0x3;
static const unsigned EncodingCounterTagAndExpansionRegionTagBits =
EncodingTagBits + 1;
private:
CounterKind Kind;
unsigned ID;
Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
public:
Counter() : Kind(Zero), ID(0) {}
CounterKind getKind() const { return Kind; }
bool isZero() const { return Kind == Zero; }
bool isExpression() const { return Kind == Expression; }
unsigned getCounterID() const { return ID; }
unsigned getExpressionID() const { return ID; }
bool operator==(const Counter &Other) const {
return Kind == Other.Kind && ID == Other.ID;
}
/// \brief Return the counter that represents the number zero.
static Counter getZero() { return Counter(); }
/// \brief Return the counter that corresponds to a specific profile counter.
static Counter getCounter(unsigned CounterId) {
return Counter(CounterValueReference, CounterId);
}
/// \brief Return the counter that corresponds to a specific
/// addition counter expression.
static Counter getExpression(unsigned ExpressionId) {
return Counter(Expression, ExpressionId);
}
};
/// \brief A Counter expression is a value that represents an arithmetic
/// operation with two counters.
struct CounterExpression {
enum ExprKind { Subtract, Add };
ExprKind Kind;
Counter LHS, RHS;
CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
: Kind(Kind), LHS(LHS), RHS(RHS) {}
bool operator==(const CounterExpression &Other) const {
return Kind == Other.Kind && LHS == Other.LHS && RHS == Other.RHS;
}
};
/// \brief A Counter expression builder is used to construct the
/// counter expressions. It avoids unecessary duplication
/// and simplifies algebraic expressions.
class CounterExpressionBuilder {
/// \brief A list of all the counter expressions
llvm::SmallVector<CounterExpression, 16> Expressions;
/// \brief An array of terms used in expression simplification.
llvm::SmallVector<int, 16> Terms;
/// \brief Return the counter which corresponds to the given expression.
///
/// If the given expression is already stored in the builder, a counter
/// that references that expression is returned. Otherwise, the given
/// expression is added to the builder's collection of expressions.
Counter get(const CounterExpression &E);
/// \brief Convert the expression tree represented by a counter
/// into a polynomial in the form of K1Counter1 + .. + KNCounterN
/// where K1 .. KN are integer constants that are stored in the Terms array.
void extractTerms(Counter C, int Sign = 1);
/// \brief Simplifies the given expression tree
/// by getting rid of algebraically redundant operations.
Counter simplify(Counter ExpressionTree);
public:
CounterExpressionBuilder(unsigned NumCounterValues);
ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
/// \brief Return a counter that represents the expression
/// that adds LHS and RHS.
Counter add(Counter LHS, Counter RHS);
/// \brief Return a counter that represents the expression
/// that subtracts RHS from LHS.
Counter subtract(Counter LHS, Counter RHS);
};
/// \brief A Counter mapping region associates a source range with
/// a specific counter.
struct CounterMappingRegion {
enum RegionKind {
/// \brief A CodeRegion associates some code with a counter
CodeRegion,
/// \brief An ExpansionRegion represents a file expansion region that
/// associates a source range with the expansion of a virtual source file,
/// such as for a macro instantiation or #include file.
ExpansionRegion,
/// \brief A SkippedRegion represents a source range with code that
/// was skipped by a preprocessor or similar means.
SkippedRegion
};
static const unsigned EncodingHasCodeBeforeBits = 1;
Counter Count;
unsigned FileID, ExpandedFileID;
unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
RegionKind Kind;
/// \brief A flag that is set to true when there is already code before
/// this region on the same line.
/// This is useful to accurately compute the execution counts for a line.
bool HasCodeBefore;
CounterMappingRegion(Counter Count, unsigned FileID, unsigned LineStart,
unsigned ColumnStart, unsigned LineEnd,
unsigned ColumnEnd, bool HasCodeBefore = false,
RegionKind Kind = CodeRegion)
: Count(Count), FileID(FileID), ExpandedFileID(0), LineStart(LineStart),
ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd),
Kind(Kind), HasCodeBefore(HasCodeBefore) {}
inline std::pair<unsigned, unsigned> startLoc() const {
return std::pair<unsigned, unsigned>(LineStart, ColumnStart);
}
inline std::pair<unsigned, unsigned> endLoc() const {
return std::pair<unsigned, unsigned>(LineEnd, ColumnEnd);
}
bool operator<(const CounterMappingRegion &Other) const {
if (FileID != Other.FileID)
return FileID < Other.FileID;
return startLoc() < Other.startLoc();
}
bool contains(const CounterMappingRegion &Other) const {
if (FileID != Other.FileID)
return false;
if (startLoc() > Other.startLoc())
return false;
if (endLoc() < Other.endLoc())
return false;
return true;
}
};
/// \brief Associates a source range with an execution count.
struct CountedRegion : public CounterMappingRegion {
uint64_t ExecutionCount;
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
: CounterMappingRegion(R), ExecutionCount(ExecutionCount) {}
};
/// \brief A Counter mapping context is used to connect the counters,
/// expressions and the obtained counter values.
class CounterMappingContext {
ArrayRef<CounterExpression> Expressions;
ArrayRef<uint64_t> CounterValues;
public:
CounterMappingContext(ArrayRef<CounterExpression> Expressions,
ArrayRef<uint64_t> CounterValues = ArrayRef<uint64_t>())
: Expressions(Expressions), CounterValues(CounterValues) {}
void dump(const Counter &C, llvm::raw_ostream &OS) const;
void dump(const Counter &C) const { dump(C, llvm::outs()); }
/// \brief Return the number of times that a region of code associated with
/// this counter was executed.
ErrorOr<int64_t> evaluate(const Counter &C) const;
};
/// \brief Code coverage information for a single function.
struct FunctionCoverageMapping {
/// \brief Raw function name.
std::string Name;
/// \brief Associated files.
std::vector<std::string> Filenames;
/// \brief Regions in the function along with their counts.
std::vector<CountedRegion> CountedRegions;
FunctionCoverageMapping(StringRef Name, ArrayRef<StringRef> Filenames)
: Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
};
} // end namespace coverage
} // end namespace llvm
#endif // LLVM_PROFILEDATA_COVERAGEMAPPING_H_