Home | History | Annotate | Download | only in Coverage
      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_COVERAGE_COVERAGEMAPPING_H
     16 #define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
     17 
     18 #include "llvm/ADT/ArrayRef.h"
     19 #include "llvm/ADT/DenseMap.h"
     20 #include "llvm/ADT/Hashing.h"
     21 #include "llvm/ADT/None.h"
     22 #include "llvm/ADT/StringRef.h"
     23 #include "llvm/ADT/StringSet.h"
     24 #include "llvm/ADT/iterator.h"
     25 #include "llvm/ADT/iterator_range.h"
     26 #include "llvm/ProfileData/InstrProf.h"
     27 #include "llvm/Support/Compiler.h"
     28 #include "llvm/Support/Debug.h"
     29 #include "llvm/Support/Endian.h"
     30 #include "llvm/Support/Error.h"
     31 #include "llvm/Support/raw_ostream.h"
     32 #include <cassert>
     33 #include <cstdint>
     34 #include <iterator>
     35 #include <memory>
     36 #include <string>
     37 #include <system_error>
     38 #include <tuple>
     39 #include <utility>
     40 #include <vector>
     41 
     42 namespace llvm {
     43 
     44 class IndexedInstrProfReader;
     45 
     46 namespace coverage {
     47 
     48 class CoverageMappingReader;
     49 struct CoverageMappingRecord;
     50 
     51 enum class coveragemap_error {
     52   success = 0,
     53   eof,
     54   no_data_found,
     55   unsupported_version,
     56   truncated,
     57   malformed
     58 };
     59 
     60 const std::error_category &coveragemap_category();
     61 
     62 inline std::error_code make_error_code(coveragemap_error E) {
     63   return std::error_code(static_cast<int>(E), coveragemap_category());
     64 }
     65 
     66 class CoverageMapError : public ErrorInfo<CoverageMapError> {
     67 public:
     68   CoverageMapError(coveragemap_error Err) : Err(Err) {
     69     assert(Err != coveragemap_error::success && "Not an error");
     70   }
     71 
     72   std::string message() const override;
     73 
     74   void log(raw_ostream &OS) const override { OS << message(); }
     75 
     76   std::error_code convertToErrorCode() const override {
     77     return make_error_code(Err);
     78   }
     79 
     80   coveragemap_error get() const { return Err; }
     81 
     82   static char ID;
     83 
     84 private:
     85   coveragemap_error Err;
     86 };
     87 
     88 /// A Counter is an abstract value that describes how to compute the
     89 /// execution count for a region of code using the collected profile count data.
     90 struct Counter {
     91   enum CounterKind { Zero, CounterValueReference, Expression };
     92   static const unsigned EncodingTagBits = 2;
     93   static const unsigned EncodingTagMask = 0x3;
     94   static const unsigned EncodingCounterTagAndExpansionRegionTagBits =
     95       EncodingTagBits + 1;
     96 
     97 private:
     98   CounterKind Kind = Zero;
     99   unsigned ID = 0;
    100 
    101   Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
    102 
    103 public:
    104   Counter() = default;
    105 
    106   CounterKind getKind() const { return Kind; }
    107 
    108   bool isZero() const { return Kind == Zero; }
    109 
    110   bool isExpression() const { return Kind == Expression; }
    111 
    112   unsigned getCounterID() const { return ID; }
    113 
    114   unsigned getExpressionID() const { return ID; }
    115 
    116   friend bool operator==(const Counter &LHS, const Counter &RHS) {
    117     return LHS.Kind == RHS.Kind && LHS.ID == RHS.ID;
    118   }
    119 
    120   friend bool operator!=(const Counter &LHS, const Counter &RHS) {
    121     return !(LHS == RHS);
    122   }
    123 
    124   friend bool operator<(const Counter &LHS, const Counter &RHS) {
    125     return std::tie(LHS.Kind, LHS.ID) < std::tie(RHS.Kind, RHS.ID);
    126   }
    127 
    128   /// Return the counter that represents the number zero.
    129   static Counter getZero() { return Counter(); }
    130 
    131   /// Return the counter that corresponds to a specific profile counter.
    132   static Counter getCounter(unsigned CounterId) {
    133     return Counter(CounterValueReference, CounterId);
    134   }
    135 
    136   /// Return the counter that corresponds to a specific addition counter
    137   /// expression.
    138   static Counter getExpression(unsigned ExpressionId) {
    139     return Counter(Expression, ExpressionId);
    140   }
    141 };
    142 
    143 /// A Counter expression is a value that represents an arithmetic operation
    144 /// with two counters.
    145 struct CounterExpression {
    146   enum ExprKind { Subtract, Add };
    147   ExprKind Kind;
    148   Counter LHS, RHS;
    149 
    150   CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
    151       : Kind(Kind), LHS(LHS), RHS(RHS) {}
    152 };
    153 
    154 /// A Counter expression builder is used to construct the counter expressions.
    155 /// It avoids unnecessary duplication and simplifies algebraic expressions.
    156 class CounterExpressionBuilder {
    157   /// A list of all the counter expressions
    158   std::vector<CounterExpression> Expressions;
    159 
    160   /// A lookup table for the index of a given expression.
    161   DenseMap<CounterExpression, unsigned> ExpressionIndices;
    162 
    163   /// Return the counter which corresponds to the given expression.
    164   ///
    165   /// If the given expression is already stored in the builder, a counter
    166   /// that references that expression is returned. Otherwise, the given
    167   /// expression is added to the builder's collection of expressions.
    168   Counter get(const CounterExpression &E);
    169 
    170   /// Represents a term in a counter expression tree.
    171   struct Term {
    172     unsigned CounterID;
    173     int Factor;
    174 
    175     Term(unsigned CounterID, int Factor)
    176         : CounterID(CounterID), Factor(Factor) {}
    177   };
    178 
    179   /// Gather the terms of the expression tree for processing.
    180   ///
    181   /// This collects each addition and subtraction referenced by the counter into
    182   /// a sequence that can be sorted and combined to build a simplified counter
    183   /// expression.
    184   void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms);
    185 
    186   /// Simplifies the given expression tree
    187   /// by getting rid of algebraically redundant operations.
    188   Counter simplify(Counter ExpressionTree);
    189 
    190 public:
    191   ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
    192 
    193   /// Return a counter that represents the expression that adds LHS and RHS.
    194   Counter add(Counter LHS, Counter RHS);
    195 
    196   /// Return a counter that represents the expression that subtracts RHS from
    197   /// LHS.
    198   Counter subtract(Counter LHS, Counter RHS);
    199 };
    200 
    201 using LineColPair = std::pair<unsigned, unsigned>;
    202 
    203 /// A Counter mapping region associates a source range with a specific counter.
    204 struct CounterMappingRegion {
    205   enum RegionKind {
    206     /// A CodeRegion associates some code with a counter
    207     CodeRegion,
    208 
    209     /// An ExpansionRegion represents a file expansion region that associates
    210     /// a source range with the expansion of a virtual source file, such as
    211     /// for a macro instantiation or #include file.
    212     ExpansionRegion,
    213 
    214     /// A SkippedRegion represents a source range with code that was skipped
    215     /// by a preprocessor or similar means.
    216     SkippedRegion,
    217 
    218     /// A GapRegion is like a CodeRegion, but its count is only set as the
    219     /// line execution count when its the only region in the line.
    220     GapRegion
    221   };
    222 
    223   Counter Count;
    224   unsigned FileID, ExpandedFileID;
    225   unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
    226   RegionKind Kind;
    227 
    228   CounterMappingRegion(Counter Count, unsigned FileID, unsigned ExpandedFileID,
    229                        unsigned LineStart, unsigned ColumnStart,
    230                        unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
    231       : Count(Count), FileID(FileID), ExpandedFileID(ExpandedFileID),
    232         LineStart(LineStart), ColumnStart(ColumnStart), LineEnd(LineEnd),
    233         ColumnEnd(ColumnEnd), Kind(Kind) {}
    234 
    235   static CounterMappingRegion
    236   makeRegion(Counter Count, unsigned FileID, unsigned LineStart,
    237              unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
    238     return CounterMappingRegion(Count, FileID, 0, LineStart, ColumnStart,
    239                                 LineEnd, ColumnEnd, CodeRegion);
    240   }
    241 
    242   static CounterMappingRegion
    243   makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart,
    244                 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
    245     return CounterMappingRegion(Counter(), FileID, ExpandedFileID, LineStart,
    246                                 ColumnStart, LineEnd, ColumnEnd,
    247                                 ExpansionRegion);
    248   }
    249 
    250   static CounterMappingRegion
    251   makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart,
    252               unsigned LineEnd, unsigned ColumnEnd) {
    253     return CounterMappingRegion(Counter(), FileID, 0, LineStart, ColumnStart,
    254                                 LineEnd, ColumnEnd, SkippedRegion);
    255   }
    256 
    257   static CounterMappingRegion
    258   makeGapRegion(Counter Count, unsigned FileID, unsigned LineStart,
    259                 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
    260     return CounterMappingRegion(Count, FileID, 0, LineStart, ColumnStart,
    261                                 LineEnd, (1U << 31) | ColumnEnd, GapRegion);
    262   }
    263 
    264   inline LineColPair startLoc() const {
    265     return LineColPair(LineStart, ColumnStart);
    266   }
    267 
    268   inline LineColPair endLoc() const { return LineColPair(LineEnd, ColumnEnd); }
    269 };
    270 
    271 /// Associates a source range with an execution count.
    272 struct CountedRegion : public CounterMappingRegion {
    273   uint64_t ExecutionCount;
    274 
    275   CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
    276       : CounterMappingRegion(R), ExecutionCount(ExecutionCount) {}
    277 };
    278 
    279 /// A Counter mapping context is used to connect the counters, expressions
    280 /// and the obtained counter values.
    281 class CounterMappingContext {
    282   ArrayRef<CounterExpression> Expressions;
    283   ArrayRef<uint64_t> CounterValues;
    284 
    285 public:
    286   CounterMappingContext(ArrayRef<CounterExpression> Expressions,
    287                         ArrayRef<uint64_t> CounterValues = None)
    288       : Expressions(Expressions), CounterValues(CounterValues) {}
    289 
    290   void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
    291 
    292   void dump(const Counter &C, raw_ostream &OS) const;
    293   void dump(const Counter &C) const { dump(C, dbgs()); }
    294 
    295   /// Return the number of times that a region of code associated with this
    296   /// counter was executed.
    297   Expected<int64_t> evaluate(const Counter &C) const;
    298 };
    299 
    300 /// Code coverage information for a single function.
    301 struct FunctionRecord {
    302   /// Raw function name.
    303   std::string Name;
    304   /// Associated files.
    305   std::vector<std::string> Filenames;
    306   /// Regions in the function along with their counts.
    307   std::vector<CountedRegion> CountedRegions;
    308   /// The number of times this function was executed.
    309   uint64_t ExecutionCount;
    310 
    311   FunctionRecord(StringRef Name, ArrayRef<StringRef> Filenames)
    312       : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
    313 
    314   FunctionRecord(FunctionRecord &&FR) = default;
    315   FunctionRecord &operator=(FunctionRecord &&) = default;
    316 
    317   void pushRegion(CounterMappingRegion Region, uint64_t Count) {
    318     if (CountedRegions.empty())
    319       ExecutionCount = Count;
    320     CountedRegions.emplace_back(Region, Count);
    321   }
    322 };
    323 
    324 /// Iterator over Functions, optionally filtered to a single file.
    325 class FunctionRecordIterator
    326     : public iterator_facade_base<FunctionRecordIterator,
    327                                   std::forward_iterator_tag, FunctionRecord> {
    328   ArrayRef<FunctionRecord> Records;
    329   ArrayRef<FunctionRecord>::iterator Current;
    330   StringRef Filename;
    331 
    332   /// Skip records whose primary file is not \c Filename.
    333   void skipOtherFiles();
    334 
    335 public:
    336   FunctionRecordIterator(ArrayRef<FunctionRecord> Records_,
    337                          StringRef Filename = "")
    338       : Records(Records_), Current(Records.begin()), Filename(Filename) {
    339     skipOtherFiles();
    340   }
    341 
    342   FunctionRecordIterator() : Current(Records.begin()) {}
    343 
    344   bool operator==(const FunctionRecordIterator &RHS) const {
    345     return Current == RHS.Current && Filename == RHS.Filename;
    346   }
    347 
    348   const FunctionRecord &operator*() const { return *Current; }
    349 
    350   FunctionRecordIterator &operator++() {
    351     assert(Current != Records.end() && "incremented past end");
    352     ++Current;
    353     skipOtherFiles();
    354     return *this;
    355   }
    356 };
    357 
    358 /// Coverage information for a macro expansion or #included file.
    359 ///
    360 /// When covered code has pieces that can be expanded for more detail, such as a
    361 /// preprocessor macro use and its definition, these are represented as
    362 /// expansions whose coverage can be looked up independently.
    363 struct ExpansionRecord {
    364   /// The abstract file this expansion covers.
    365   unsigned FileID;
    366   /// The region that expands to this record.
    367   const CountedRegion &Region;
    368   /// Coverage for the expansion.
    369   const FunctionRecord &Function;
    370 
    371   ExpansionRecord(const CountedRegion &Region,
    372                   const FunctionRecord &Function)
    373       : FileID(Region.ExpandedFileID), Region(Region), Function(Function) {}
    374 };
    375 
    376 /// The execution count information starting at a point in a file.
    377 ///
    378 /// A sequence of CoverageSegments gives execution counts for a file in format
    379 /// that's simple to iterate through for processing.
    380 struct CoverageSegment {
    381   /// The line where this segment begins.
    382   unsigned Line;
    383   /// The column where this segment begins.
    384   unsigned Col;
    385   /// The execution count, or zero if no count was recorded.
    386   uint64_t Count;
    387   /// When false, the segment was uninstrumented or skipped.
    388   bool HasCount;
    389   /// Whether this enters a new region or returns to a previous count.
    390   bool IsRegionEntry;
    391   /// Whether this enters a gap region.
    392   bool IsGapRegion;
    393 
    394   CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
    395       : Line(Line), Col(Col), Count(0), HasCount(false),
    396         IsRegionEntry(IsRegionEntry), IsGapRegion(false) {}
    397 
    398   CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
    399                   bool IsRegionEntry, bool IsGapRegion = false)
    400       : Line(Line), Col(Col), Count(Count), HasCount(true),
    401         IsRegionEntry(IsRegionEntry), IsGapRegion(IsGapRegion) {}
    402 
    403   friend bool operator==(const CoverageSegment &L, const CoverageSegment &R) {
    404     return std::tie(L.Line, L.Col, L.Count, L.HasCount, L.IsRegionEntry,
    405                     L.IsGapRegion) == std::tie(R.Line, R.Col, R.Count,
    406                                                R.HasCount, R.IsRegionEntry,
    407                                                R.IsGapRegion);
    408   }
    409 };
    410 
    411 /// An instantiation group contains a \c FunctionRecord list, such that each
    412 /// record corresponds to a distinct instantiation of the same function.
    413 ///
    414 /// Note that it's possible for a function to have more than one instantiation
    415 /// (consider C++ template specializations or static inline functions).
    416 class InstantiationGroup {
    417   friend class CoverageMapping;
    418 
    419   unsigned Line;
    420   unsigned Col;
    421   std::vector<const FunctionRecord *> Instantiations;
    422 
    423   InstantiationGroup(unsigned Line, unsigned Col,
    424                      std::vector<const FunctionRecord *> Instantiations)
    425       : Line(Line), Col(Col), Instantiations(std::move(Instantiations)) {}
    426 
    427 public:
    428   InstantiationGroup(const InstantiationGroup &) = delete;
    429   InstantiationGroup(InstantiationGroup &&) = default;
    430 
    431   /// Get the number of instantiations in this group.
    432   size_t size() const { return Instantiations.size(); }
    433 
    434   /// Get the line where the common function was defined.
    435   unsigned getLine() const { return Line; }
    436 
    437   /// Get the column where the common function was defined.
    438   unsigned getColumn() const { return Col; }
    439 
    440   /// Check if the instantiations in this group have a common mangled name.
    441   bool hasName() const {
    442     for (unsigned I = 1, E = Instantiations.size(); I < E; ++I)
    443       if (Instantiations[I]->Name != Instantiations[0]->Name)
    444         return false;
    445     return true;
    446   }
    447 
    448   /// Get the common mangled name for instantiations in this group.
    449   StringRef getName() const {
    450     assert(hasName() && "Instantiations don't have a shared name");
    451     return Instantiations[0]->Name;
    452   }
    453 
    454   /// Get the total execution count of all instantiations in this group.
    455   uint64_t getTotalExecutionCount() const {
    456     uint64_t Count = 0;
    457     for (const FunctionRecord *F : Instantiations)
    458       Count += F->ExecutionCount;
    459     return Count;
    460   }
    461 
    462   /// Get the instantiations in this group.
    463   ArrayRef<const FunctionRecord *> getInstantiations() const {
    464     return Instantiations;
    465   }
    466 };
    467 
    468 /// Coverage information to be processed or displayed.
    469 ///
    470 /// This represents the coverage of an entire file, expansion, or function. It
    471 /// provides a sequence of CoverageSegments to iterate through, as well as the
    472 /// list of expansions that can be further processed.
    473 class CoverageData {
    474   friend class CoverageMapping;
    475 
    476   std::string Filename;
    477   std::vector<CoverageSegment> Segments;
    478   std::vector<ExpansionRecord> Expansions;
    479 
    480 public:
    481   CoverageData() = default;
    482 
    483   CoverageData(StringRef Filename) : Filename(Filename) {}
    484 
    485   /// Get the name of the file this data covers.
    486   StringRef getFilename() const { return Filename; }
    487 
    488   /// Get an iterator over the coverage segments for this object. The segments
    489   /// are guaranteed to be uniqued and sorted by location.
    490   std::vector<CoverageSegment>::const_iterator begin() const {
    491     return Segments.begin();
    492   }
    493 
    494   std::vector<CoverageSegment>::const_iterator end() const {
    495     return Segments.end();
    496   }
    497 
    498   bool empty() const { return Segments.empty(); }
    499 
    500   /// Expansions that can be further processed.
    501   ArrayRef<ExpansionRecord> getExpansions() const { return Expansions; }
    502 };
    503 
    504 /// The mapping of profile information to coverage data.
    505 ///
    506 /// This is the main interface to get coverage information, using a profile to
    507 /// fill out execution counts.
    508 class CoverageMapping {
    509   StringSet<> FunctionNames;
    510   std::vector<FunctionRecord> Functions;
    511   std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
    512   std::vector<std::pair<std::string, uint64_t>> FuncCounterMismatches;
    513 
    514   CoverageMapping() = default;
    515 
    516   /// Add a function record corresponding to \p Record.
    517   Error loadFunctionRecord(const CoverageMappingRecord &Record,
    518                            IndexedInstrProfReader &ProfileReader);
    519 
    520 public:
    521   CoverageMapping(const CoverageMapping &) = delete;
    522   CoverageMapping &operator=(const CoverageMapping &) = delete;
    523 
    524   /// Load the coverage mapping using the given readers.
    525   static Expected<std::unique_ptr<CoverageMapping>>
    526   load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
    527        IndexedInstrProfReader &ProfileReader);
    528 
    529   /// Load the coverage mapping from the given object files and profile. If
    530   /// \p Arches is non-empty, it must specify an architecture for each object.
    531   static Expected<std::unique_ptr<CoverageMapping>>
    532   load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
    533        ArrayRef<StringRef> Arches = None);
    534 
    535   /// The number of functions that couldn't have their profiles mapped.
    536   ///
    537   /// This is a count of functions whose profile is out of date or otherwise
    538   /// can't be associated with any coverage information.
    539   unsigned getMismatchedCount() const {
    540     return FuncHashMismatches.size() + FuncCounterMismatches.size();
    541   }
    542 
    543   /// A hash mismatch occurs when a profile record for a symbol does not have
    544   /// the same hash as a coverage mapping record for the same symbol. This
    545   /// returns a list of hash mismatches, where each mismatch is a pair of the
    546   /// symbol name and its coverage mapping hash.
    547   ArrayRef<std::pair<std::string, uint64_t>> getHashMismatches() const {
    548     return FuncHashMismatches;
    549   }
    550 
    551   /// A counter mismatch occurs when there is an error when evaluating the
    552   /// counter expressions in a coverage mapping record. This returns a list of
    553   /// counter mismatches, where each mismatch is a pair of the symbol name and
    554   /// the number of valid evaluated counter expressions.
    555   ArrayRef<std::pair<std::string, uint64_t>> getCounterMismatches() const {
    556     return FuncCounterMismatches;
    557   }
    558 
    559   /// Returns a lexicographically sorted, unique list of files that are
    560   /// covered.
    561   std::vector<StringRef> getUniqueSourceFiles() const;
    562 
    563   /// Get the coverage for a particular file.
    564   ///
    565   /// The given filename must be the name as recorded in the coverage
    566   /// information. That is, only names returned from getUniqueSourceFiles will
    567   /// yield a result.
    568   CoverageData getCoverageForFile(StringRef Filename) const;
    569 
    570   /// Get the coverage for a particular function.
    571   CoverageData getCoverageForFunction(const FunctionRecord &Function) const;
    572 
    573   /// Get the coverage for an expansion within a coverage set.
    574   CoverageData getCoverageForExpansion(const ExpansionRecord &Expansion) const;
    575 
    576   /// Gets all of the functions covered by this profile.
    577   iterator_range<FunctionRecordIterator> getCoveredFunctions() const {
    578     return make_range(FunctionRecordIterator(Functions),
    579                       FunctionRecordIterator());
    580   }
    581 
    582   /// Gets all of the functions in a particular file.
    583   iterator_range<FunctionRecordIterator>
    584   getCoveredFunctions(StringRef Filename) const {
    585     return make_range(FunctionRecordIterator(Functions, Filename),
    586                       FunctionRecordIterator());
    587   }
    588 
    589   /// Get the list of function instantiation groups in a particular file.
    590   ///
    591   /// Every instantiation group in a program is attributed to exactly one file:
    592   /// the file in which the definition for the common function begins.
    593   std::vector<InstantiationGroup>
    594   getInstantiationGroups(StringRef Filename) const;
    595 };
    596 
    597 /// Coverage statistics for a single line.
    598 class LineCoverageStats {
    599   uint64_t ExecutionCount;
    600   bool HasMultipleRegions;
    601   bool Mapped;
    602   unsigned Line;
    603   ArrayRef<const CoverageSegment *> LineSegments;
    604   const CoverageSegment *WrappedSegment;
    605 
    606   friend class LineCoverageIterator;
    607   LineCoverageStats() = default;
    608 
    609 public:
    610   LineCoverageStats(ArrayRef<const CoverageSegment *> LineSegments,
    611                     const CoverageSegment *WrappedSegment, unsigned Line);
    612 
    613   uint64_t getExecutionCount() const { return ExecutionCount; }
    614 
    615   bool hasMultipleRegions() const { return HasMultipleRegions; }
    616 
    617   bool isMapped() const { return Mapped; }
    618 
    619   unsigned getLine() const { return Line; }
    620 
    621   ArrayRef<const CoverageSegment *> getLineSegments() const {
    622     return LineSegments;
    623   }
    624 
    625   const CoverageSegment *getWrappedSegment() const { return WrappedSegment; }
    626 };
    627 
    628 /// An iterator over the \c LineCoverageStats objects for lines described by
    629 /// a \c CoverageData instance.
    630 class LineCoverageIterator
    631     : public iterator_facade_base<
    632           LineCoverageIterator, std::forward_iterator_tag, LineCoverageStats> {
    633 public:
    634   LineCoverageIterator(const CoverageData &CD)
    635       : LineCoverageIterator(CD, CD.begin()->Line) {}
    636 
    637   LineCoverageIterator(const CoverageData &CD, unsigned Line)
    638       : CD(CD), WrappedSegment(nullptr), Next(CD.begin()), Ended(false),
    639         Line(Line), Segments(), Stats() {
    640     this->operator++();
    641   }
    642 
    643   LineCoverageIterator &operator=(const LineCoverageIterator &R) = default;
    644 
    645   bool operator==(const LineCoverageIterator &R) const {
    646     return &CD == &R.CD && Next == R.Next && Ended == R.Ended;
    647   }
    648 
    649   const LineCoverageStats &operator*() const { return Stats; }
    650 
    651   LineCoverageStats &operator*() { return Stats; }
    652 
    653   LineCoverageIterator &operator++();
    654 
    655   LineCoverageIterator getEnd() const {
    656     auto EndIt = *this;
    657     EndIt.Next = CD.end();
    658     EndIt.Ended = true;
    659     return EndIt;
    660   }
    661 
    662 private:
    663   const CoverageData &CD;
    664   const CoverageSegment *WrappedSegment;
    665   std::vector<CoverageSegment>::const_iterator Next;
    666   bool Ended;
    667   unsigned Line;
    668   SmallVector<const CoverageSegment *, 4> Segments;
    669   LineCoverageStats Stats;
    670 };
    671 
    672 /// Get a \c LineCoverageIterator range for the lines described by \p CD.
    673 static inline iterator_range<LineCoverageIterator>
    674 getLineCoverageStats(const coverage::CoverageData &CD) {
    675   auto Begin = LineCoverageIterator(CD);
    676   auto End = Begin.getEnd();
    677   return make_range(Begin, End);
    678 }
    679 
    680 // Profile coverage map has the following layout:
    681 // [CoverageMapFileHeader]
    682 // [ArrayStart]
    683 //  [CovMapFunctionRecord]
    684 //  [CovMapFunctionRecord]
    685 //  ...
    686 // [ArrayEnd]
    687 // [Encoded Region Mapping Data]
    688 LLVM_PACKED_START
    689 template <class IntPtrT> struct CovMapFunctionRecordV1 {
    690 #define COVMAP_V1
    691 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
    692 #include "llvm/ProfileData/InstrProfData.inc"
    693 #undef COVMAP_V1
    694 
    695   // Return the structural hash associated with the function.
    696   template <support::endianness Endian> uint64_t getFuncHash() const {
    697     return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
    698   }
    699 
    700   // Return the coverage map data size for the funciton.
    701   template <support::endianness Endian> uint32_t getDataSize() const {
    702     return support::endian::byte_swap<uint32_t, Endian>(DataSize);
    703   }
    704 
    705   // Return function lookup key. The value is consider opaque.
    706   template <support::endianness Endian> IntPtrT getFuncNameRef() const {
    707     return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
    708   }
    709 
    710   // Return the PGO name of the function */
    711   template <support::endianness Endian>
    712   Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
    713     IntPtrT NameRef = getFuncNameRef<Endian>();
    714     uint32_t NameS = support::endian::byte_swap<uint32_t, Endian>(NameSize);
    715     FuncName = ProfileNames.getFuncName(NameRef, NameS);
    716     if (NameS && FuncName.empty())
    717       return make_error<CoverageMapError>(coveragemap_error::malformed);
    718     return Error::success();
    719   }
    720 };
    721 
    722 struct CovMapFunctionRecord {
    723 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
    724 #include "llvm/ProfileData/InstrProfData.inc"
    725 
    726   // Return the structural hash associated with the function.
    727   template <support::endianness Endian> uint64_t getFuncHash() const {
    728     return support::endian::byte_swap<uint64_t, Endian>(FuncHash);
    729   }
    730 
    731   // Return the coverage map data size for the funciton.
    732   template <support::endianness Endian> uint32_t getDataSize() const {
    733     return support::endian::byte_swap<uint32_t, Endian>(DataSize);
    734   }
    735 
    736   // Return function lookup key. The value is consider opaque.
    737   template <support::endianness Endian> uint64_t getFuncNameRef() const {
    738     return support::endian::byte_swap<uint64_t, Endian>(NameRef);
    739   }
    740 
    741   // Return the PGO name of the function */
    742   template <support::endianness Endian>
    743   Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
    744     uint64_t NameRef = getFuncNameRef<Endian>();
    745     FuncName = ProfileNames.getFuncName(NameRef);
    746     return Error::success();
    747   }
    748 };
    749 
    750 // Per module coverage mapping data header, i.e. CoverageMapFileHeader
    751 // documented above.
    752 struct CovMapHeader {
    753 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
    754 #include "llvm/ProfileData/InstrProfData.inc"
    755   template <support::endianness Endian> uint32_t getNRecords() const {
    756     return support::endian::byte_swap<uint32_t, Endian>(NRecords);
    757   }
    758 
    759   template <support::endianness Endian> uint32_t getFilenamesSize() const {
    760     return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
    761   }
    762 
    763   template <support::endianness Endian> uint32_t getCoverageSize() const {
    764     return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
    765   }
    766 
    767   template <support::endianness Endian> uint32_t getVersion() const {
    768     return support::endian::byte_swap<uint32_t, Endian>(Version);
    769   }
    770 };
    771 
    772 LLVM_PACKED_END
    773 
    774 enum CovMapVersion {
    775   Version1 = 0,
    776   // Function's name reference from CovMapFuncRecord is changed from raw
    777   // name string pointer to MD5 to support name section compression. Name
    778   // section is also compressed.
    779   Version2 = 1,
    780   // A new interpretation of the columnEnd field is added in order to mark
    781   // regions as gap areas.
    782   Version3 = 2,
    783   // The current version is Version3
    784   CurrentVersion = INSTR_PROF_COVMAP_VERSION
    785 };
    786 
    787 template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
    788   using CovMapFuncRecordType = CovMapFunctionRecord;
    789   using NameRefType = uint64_t;
    790 };
    791 
    792 template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
    793   using CovMapFuncRecordType = CovMapFunctionRecordV1<IntPtrT>;
    794   using NameRefType = IntPtrT;
    795 };
    796 
    797 } // end namespace coverage
    798 
    799 /// Provide DenseMapInfo for CounterExpression
    800 template<> struct DenseMapInfo<coverage::CounterExpression> {
    801   static inline coverage::CounterExpression getEmptyKey() {
    802     using namespace coverage;
    803 
    804     return CounterExpression(CounterExpression::ExprKind::Subtract,
    805                              Counter::getCounter(~0U),
    806                              Counter::getCounter(~0U));
    807   }
    808 
    809   static inline coverage::CounterExpression getTombstoneKey() {
    810     using namespace coverage;
    811 
    812     return CounterExpression(CounterExpression::ExprKind::Add,
    813                              Counter::getCounter(~0U),
    814                              Counter::getCounter(~0U));
    815   }
    816 
    817   static unsigned getHashValue(const coverage::CounterExpression &V) {
    818     return static_cast<unsigned>(
    819         hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
    820                      V.RHS.getKind(), V.RHS.getCounterID()));
    821   }
    822 
    823   static bool isEqual(const coverage::CounterExpression &LHS,
    824                       const coverage::CounterExpression &RHS) {
    825     return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
    826   }
    827 };
    828 
    829 } // end namespace llvm
    830 
    831 #endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
    832