Home | History | Annotate | Line # | Download | only in Coverage
      1 //===- CoverageMapping.h - Code coverage mapping support --------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // Code coverage mapping data is generated by clang and read by
     10 // llvm-cov to show code coverage statistics for a file.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
     15 #define LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
     16 
     17 #include "llvm/ADT/ArrayRef.h"
     18 #include "llvm/ADT/DenseMap.h"
     19 #include "llvm/ADT/DenseSet.h"
     20 #include "llvm/ADT/Hashing.h"
     21 #include "llvm/ADT/None.h"
     22 #include "llvm/ADT/StringRef.h"
     23 #include "llvm/ADT/iterator.h"
     24 #include "llvm/ADT/iterator_range.h"
     25 #include "llvm/ProfileData/InstrProf.h"
     26 #include "llvm/Support/Alignment.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   decompression_failed,
     59   invalid_or_missing_arch_specifier
     60 };
     61 
     62 const std::error_category &coveragemap_category();
     63 
     64 inline std::error_code make_error_code(coveragemap_error E) {
     65   return std::error_code(static_cast<int>(E), coveragemap_category());
     66 }
     67 
     68 class CoverageMapError : public ErrorInfo<CoverageMapError> {
     69 public:
     70   CoverageMapError(coveragemap_error Err) : Err(Err) {
     71     assert(Err != coveragemap_error::success && "Not an error");
     72   }
     73 
     74   std::string message() const override;
     75 
     76   void log(raw_ostream &OS) const override { OS << message(); }
     77 
     78   std::error_code convertToErrorCode() const override {
     79     return make_error_code(Err);
     80   }
     81 
     82   coveragemap_error get() const { return Err; }
     83 
     84   static char ID;
     85 
     86 private:
     87   coveragemap_error Err;
     88 };
     89 
     90 /// A Counter is an abstract value that describes how to compute the
     91 /// execution count for a region of code using the collected profile count data.
     92 struct Counter {
     93   /// The CounterExpression kind (Add or Subtract) is encoded in bit 0 next to
     94   /// the CounterKind. This means CounterKind has to leave bit 0 free.
     95   enum CounterKind { Zero, CounterValueReference, Expression };
     96   static const unsigned EncodingTagBits = 2;
     97   static const unsigned EncodingTagMask = 0x3;
     98   static const unsigned EncodingCounterTagAndExpansionRegionTagBits =
     99       EncodingTagBits + 1;
    100 
    101 private:
    102   CounterKind Kind = Zero;
    103   unsigned ID = 0;
    104 
    105   Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
    106 
    107 public:
    108   Counter() = default;
    109 
    110   CounterKind getKind() const { return Kind; }
    111 
    112   bool isZero() const { return Kind == Zero; }
    113 
    114   bool isExpression() const { return Kind == Expression; }
    115 
    116   unsigned getCounterID() const { return ID; }
    117 
    118   unsigned getExpressionID() const { return ID; }
    119 
    120   friend bool operator==(const Counter &LHS, const Counter &RHS) {
    121     return LHS.Kind == RHS.Kind && LHS.ID == RHS.ID;
    122   }
    123 
    124   friend bool operator!=(const Counter &LHS, const Counter &RHS) {
    125     return !(LHS == RHS);
    126   }
    127 
    128   friend bool operator<(const Counter &LHS, const Counter &RHS) {
    129     return std::tie(LHS.Kind, LHS.ID) < std::tie(RHS.Kind, RHS.ID);
    130   }
    131 
    132   /// Return the counter that represents the number zero.
    133   static Counter getZero() { return Counter(); }
    134 
    135   /// Return the counter that corresponds to a specific profile counter.
    136   static Counter getCounter(unsigned CounterId) {
    137     return Counter(CounterValueReference, CounterId);
    138   }
    139 
    140   /// Return the counter that corresponds to a specific addition counter
    141   /// expression.
    142   static Counter getExpression(unsigned ExpressionId) {
    143     return Counter(Expression, ExpressionId);
    144   }
    145 };
    146 
    147 /// A Counter expression is a value that represents an arithmetic operation
    148 /// with two counters.
    149 struct CounterExpression {
    150   enum ExprKind { Subtract, Add };
    151   ExprKind Kind;
    152   Counter LHS, RHS;
    153 
    154   CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
    155       : Kind(Kind), LHS(LHS), RHS(RHS) {}
    156 };
    157 
    158 /// A Counter expression builder is used to construct the counter expressions.
    159 /// It avoids unnecessary duplication and simplifies algebraic expressions.
    160 class CounterExpressionBuilder {
    161   /// A list of all the counter expressions
    162   std::vector<CounterExpression> Expressions;
    163 
    164   /// A lookup table for the index of a given expression.
    165   DenseMap<CounterExpression, unsigned> ExpressionIndices;
    166 
    167   /// Return the counter which corresponds to the given expression.
    168   ///
    169   /// If the given expression is already stored in the builder, a counter
    170   /// that references that expression is returned. Otherwise, the given
    171   /// expression is added to the builder's collection of expressions.
    172   Counter get(const CounterExpression &E);
    173 
    174   /// Represents a term in a counter expression tree.
    175   struct Term {
    176     unsigned CounterID;
    177     int Factor;
    178 
    179     Term(unsigned CounterID, int Factor)
    180         : CounterID(CounterID), Factor(Factor) {}
    181   };
    182 
    183   /// Gather the terms of the expression tree for processing.
    184   ///
    185   /// This collects each addition and subtraction referenced by the counter into
    186   /// a sequence that can be sorted and combined to build a simplified counter
    187   /// expression.
    188   void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms);
    189 
    190   /// Simplifies the given expression tree
    191   /// by getting rid of algebraically redundant operations.
    192   Counter simplify(Counter ExpressionTree);
    193 
    194 public:
    195   ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
    196 
    197   /// Return a counter that represents the expression that adds LHS and RHS.
    198   Counter add(Counter LHS, Counter RHS);
    199 
    200   /// Return a counter that represents the expression that subtracts RHS from
    201   /// LHS.
    202   Counter subtract(Counter LHS, Counter RHS);
    203 };
    204 
    205 using LineColPair = std::pair<unsigned, unsigned>;
    206 
    207 /// A Counter mapping region associates a source range with a specific counter.
    208 struct CounterMappingRegion {
    209   enum RegionKind {
    210     /// A CodeRegion associates some code with a counter
    211     CodeRegion,
    212 
    213     /// An ExpansionRegion represents a file expansion region that associates
    214     /// a source range with the expansion of a virtual source file, such as
    215     /// for a macro instantiation or #include file.
    216     ExpansionRegion,
    217 
    218     /// A SkippedRegion represents a source range with code that was skipped
    219     /// by a preprocessor or similar means.
    220     SkippedRegion,
    221 
    222     /// A GapRegion is like a CodeRegion, but its count is only set as the
    223     /// line execution count when its the only region in the line.
    224     GapRegion,
    225 
    226     /// A BranchRegion represents leaf-level boolean expressions and is
    227     /// associated with two counters, each representing the number of times the
    228     /// expression evaluates to true or false.
    229     BranchRegion
    230   };
    231 
    232   /// Primary Counter that is also used for Branch Regions (TrueCount).
    233   Counter Count;
    234 
    235   /// Secondary Counter used for Branch Regions (FalseCount).
    236   Counter FalseCount;
    237 
    238   unsigned FileID, ExpandedFileID;
    239   unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
    240   RegionKind Kind;
    241 
    242   CounterMappingRegion(Counter Count, unsigned FileID, unsigned ExpandedFileID,
    243                        unsigned LineStart, unsigned ColumnStart,
    244                        unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
    245       : Count(Count), FileID(FileID), ExpandedFileID(ExpandedFileID),
    246         LineStart(LineStart), ColumnStart(ColumnStart), LineEnd(LineEnd),
    247         ColumnEnd(ColumnEnd), Kind(Kind) {}
    248 
    249   CounterMappingRegion(Counter Count, Counter FalseCount, unsigned FileID,
    250                        unsigned ExpandedFileID, unsigned LineStart,
    251                        unsigned ColumnStart, unsigned LineEnd,
    252                        unsigned ColumnEnd, RegionKind Kind)
    253       : Count(Count), FalseCount(FalseCount), FileID(FileID),
    254         ExpandedFileID(ExpandedFileID), LineStart(LineStart),
    255         ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd),
    256         Kind(Kind) {}
    257 
    258   static CounterMappingRegion
    259   makeRegion(Counter Count, unsigned FileID, unsigned LineStart,
    260              unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
    261     return CounterMappingRegion(Count, FileID, 0, LineStart, ColumnStart,
    262                                 LineEnd, ColumnEnd, CodeRegion);
    263   }
    264 
    265   static CounterMappingRegion
    266   makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart,
    267                 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
    268     return CounterMappingRegion(Counter(), FileID, ExpandedFileID, LineStart,
    269                                 ColumnStart, LineEnd, ColumnEnd,
    270                                 ExpansionRegion);
    271   }
    272 
    273   static CounterMappingRegion
    274   makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart,
    275               unsigned LineEnd, unsigned ColumnEnd) {
    276     return CounterMappingRegion(Counter(), FileID, 0, LineStart, ColumnStart,
    277                                 LineEnd, ColumnEnd, SkippedRegion);
    278   }
    279 
    280   static CounterMappingRegion
    281   makeGapRegion(Counter Count, unsigned FileID, unsigned LineStart,
    282                 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
    283     return CounterMappingRegion(Count, FileID, 0, LineStart, ColumnStart,
    284                                 LineEnd, (1U << 31) | ColumnEnd, GapRegion);
    285   }
    286 
    287   static CounterMappingRegion
    288   makeBranchRegion(Counter Count, Counter FalseCount, unsigned FileID,
    289                    unsigned LineStart, unsigned ColumnStart, unsigned LineEnd,
    290                    unsigned ColumnEnd) {
    291     return CounterMappingRegion(Count, FalseCount, FileID, 0, LineStart,
    292                                 ColumnStart, LineEnd, ColumnEnd, BranchRegion);
    293   }
    294 
    295   inline LineColPair startLoc() const {
    296     return LineColPair(LineStart, ColumnStart);
    297   }
    298 
    299   inline LineColPair endLoc() const { return LineColPair(LineEnd, ColumnEnd); }
    300 };
    301 
    302 /// Associates a source range with an execution count.
    303 struct CountedRegion : public CounterMappingRegion {
    304   uint64_t ExecutionCount;
    305   uint64_t FalseExecutionCount;
    306   bool Folded;
    307 
    308   CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
    309       : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
    310         FalseExecutionCount(0), Folded(false) {}
    311 
    312   CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
    313                 uint64_t FalseExecutionCount)
    314       : CounterMappingRegion(R), ExecutionCount(ExecutionCount),
    315         FalseExecutionCount(FalseExecutionCount), Folded(false) {}
    316 };
    317 
    318 /// A Counter mapping context is used to connect the counters, expressions
    319 /// and the obtained counter values.
    320 class CounterMappingContext {
    321   ArrayRef<CounterExpression> Expressions;
    322   ArrayRef<uint64_t> CounterValues;
    323 
    324 public:
    325   CounterMappingContext(ArrayRef<CounterExpression> Expressions,
    326                         ArrayRef<uint64_t> CounterValues = None)
    327       : Expressions(Expressions), CounterValues(CounterValues) {}
    328 
    329   void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
    330 
    331   void dump(const Counter &C, raw_ostream &OS) const;
    332   void dump(const Counter &C) const { dump(C, dbgs()); }
    333 
    334   /// Return the number of times that a region of code associated with this
    335   /// counter was executed.
    336   Expected<int64_t> evaluate(const Counter &C) const;
    337 
    338   unsigned getMaxCounterID(const Counter &C) const;
    339 };
    340 
    341 /// Code coverage information for a single function.
    342 struct FunctionRecord {
    343   /// Raw function name.
    344   std::string Name;
    345   /// Mapping from FileID (i.e. vector index) to filename. Used to support
    346   /// macro expansions within a function in which the macro and function are
    347   /// defined in separate files.
    348   ///
    349   /// TODO: Uniquing filenames across all function records may be a performance
    350   /// optimization.
    351   std::vector<std::string> Filenames;
    352   /// Regions in the function along with their counts.
    353   std::vector<CountedRegion> CountedRegions;
    354   /// Branch Regions in the function along with their counts.
    355   std::vector<CountedRegion> CountedBranchRegions;
    356   /// The number of times this function was executed.
    357   uint64_t ExecutionCount = 0;
    358 
    359   FunctionRecord(StringRef Name, ArrayRef<StringRef> Filenames)
    360       : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
    361 
    362   FunctionRecord(FunctionRecord &&FR) = default;
    363   FunctionRecord &operator=(FunctionRecord &&) = default;
    364 
    365   void pushRegion(CounterMappingRegion Region, uint64_t Count,
    366                   uint64_t FalseCount) {
    367     if (Region.Kind == CounterMappingRegion::BranchRegion) {
    368       CountedBranchRegions.emplace_back(Region, Count, FalseCount);
    369       // If both counters are hard-coded to zero, then this region represents a
    370       // constant-folded branch.
    371       if (Region.Count.isZero() && Region.FalseCount.isZero())
    372         CountedBranchRegions.back().Folded = true;
    373       return;
    374     }
    375     if (CountedRegions.empty())
    376       ExecutionCount = Count;
    377     CountedRegions.emplace_back(Region, Count, FalseCount);
    378   }
    379 };
    380 
    381 /// Iterator over Functions, optionally filtered to a single file.
    382 class FunctionRecordIterator
    383     : public iterator_facade_base<FunctionRecordIterator,
    384                                   std::forward_iterator_tag, FunctionRecord> {
    385   ArrayRef<FunctionRecord> Records;
    386   ArrayRef<FunctionRecord>::iterator Current;
    387   StringRef Filename;
    388 
    389   /// Skip records whose primary file is not \c Filename.
    390   void skipOtherFiles();
    391 
    392 public:
    393   FunctionRecordIterator(ArrayRef<FunctionRecord> Records_,
    394                          StringRef Filename = "")
    395       : Records(Records_), Current(Records.begin()), Filename(Filename) {
    396     skipOtherFiles();
    397   }
    398 
    399   FunctionRecordIterator() : Current(Records.begin()) {}
    400 
    401   bool operator==(const FunctionRecordIterator &RHS) const {
    402     return Current == RHS.Current && Filename == RHS.Filename;
    403   }
    404 
    405   const FunctionRecord &operator*() const { return *Current; }
    406 
    407   FunctionRecordIterator &operator++() {
    408     assert(Current != Records.end() && "incremented past end");
    409     ++Current;
    410     skipOtherFiles();
    411     return *this;
    412   }
    413 };
    414 
    415 /// Coverage information for a macro expansion or #included file.
    416 ///
    417 /// When covered code has pieces that can be expanded for more detail, such as a
    418 /// preprocessor macro use and its definition, these are represented as
    419 /// expansions whose coverage can be looked up independently.
    420 struct ExpansionRecord {
    421   /// The abstract file this expansion covers.
    422   unsigned FileID;
    423   /// The region that expands to this record.
    424   const CountedRegion &Region;
    425   /// Coverage for the expansion.
    426   const FunctionRecord &Function;
    427 
    428   ExpansionRecord(const CountedRegion &Region,
    429                   const FunctionRecord &Function)
    430       : FileID(Region.ExpandedFileID), Region(Region), Function(Function) {}
    431 };
    432 
    433 /// The execution count information starting at a point in a file.
    434 ///
    435 /// A sequence of CoverageSegments gives execution counts for a file in format
    436 /// that's simple to iterate through for processing.
    437 struct CoverageSegment {
    438   /// The line where this segment begins.
    439   unsigned Line;
    440   /// The column where this segment begins.
    441   unsigned Col;
    442   /// The execution count, or zero if no count was recorded.
    443   uint64_t Count;
    444   /// When false, the segment was uninstrumented or skipped.
    445   bool HasCount;
    446   /// Whether this enters a new region or returns to a previous count.
    447   bool IsRegionEntry;
    448   /// Whether this enters a gap region.
    449   bool IsGapRegion;
    450 
    451   CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
    452       : Line(Line), Col(Col), Count(0), HasCount(false),
    453         IsRegionEntry(IsRegionEntry), IsGapRegion(false) {}
    454 
    455   CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
    456                   bool IsRegionEntry, bool IsGapRegion = false,
    457                   bool IsBranchRegion = false)
    458       : Line(Line), Col(Col), Count(Count), HasCount(true),
    459         IsRegionEntry(IsRegionEntry), IsGapRegion(IsGapRegion) {}
    460 
    461   friend bool operator==(const CoverageSegment &L, const CoverageSegment &R) {
    462     return std::tie(L.Line, L.Col, L.Count, L.HasCount, L.IsRegionEntry,
    463                     L.IsGapRegion) == std::tie(R.Line, R.Col, R.Count,
    464                                                R.HasCount, R.IsRegionEntry,
    465                                                R.IsGapRegion);
    466   }
    467 };
    468 
    469 /// An instantiation group contains a \c FunctionRecord list, such that each
    470 /// record corresponds to a distinct instantiation of the same function.
    471 ///
    472 /// Note that it's possible for a function to have more than one instantiation
    473 /// (consider C++ template specializations or static inline functions).
    474 class InstantiationGroup {
    475   friend class CoverageMapping;
    476 
    477   unsigned Line;
    478   unsigned Col;
    479   std::vector<const FunctionRecord *> Instantiations;
    480 
    481   InstantiationGroup(unsigned Line, unsigned Col,
    482                      std::vector<const FunctionRecord *> Instantiations)
    483       : Line(Line), Col(Col), Instantiations(std::move(Instantiations)) {}
    484 
    485 public:
    486   InstantiationGroup(const InstantiationGroup &) = delete;
    487   InstantiationGroup(InstantiationGroup &&) = default;
    488 
    489   /// Get the number of instantiations in this group.
    490   size_t size() const { return Instantiations.size(); }
    491 
    492   /// Get the line where the common function was defined.
    493   unsigned getLine() const { return Line; }
    494 
    495   /// Get the column where the common function was defined.
    496   unsigned getColumn() const { return Col; }
    497 
    498   /// Check if the instantiations in this group have a common mangled name.
    499   bool hasName() const {
    500     for (unsigned I = 1, E = Instantiations.size(); I < E; ++I)
    501       if (Instantiations[I]->Name != Instantiations[0]->Name)
    502         return false;
    503     return true;
    504   }
    505 
    506   /// Get the common mangled name for instantiations in this group.
    507   StringRef getName() const {
    508     assert(hasName() && "Instantiations don't have a shared name");
    509     return Instantiations[0]->Name;
    510   }
    511 
    512   /// Get the total execution count of all instantiations in this group.
    513   uint64_t getTotalExecutionCount() const {
    514     uint64_t Count = 0;
    515     for (const FunctionRecord *F : Instantiations)
    516       Count += F->ExecutionCount;
    517     return Count;
    518   }
    519 
    520   /// Get the instantiations in this group.
    521   ArrayRef<const FunctionRecord *> getInstantiations() const {
    522     return Instantiations;
    523   }
    524 };
    525 
    526 /// Coverage information to be processed or displayed.
    527 ///
    528 /// This represents the coverage of an entire file, expansion, or function. It
    529 /// provides a sequence of CoverageSegments to iterate through, as well as the
    530 /// list of expansions that can be further processed.
    531 class CoverageData {
    532   friend class CoverageMapping;
    533 
    534   std::string Filename;
    535   std::vector<CoverageSegment> Segments;
    536   std::vector<ExpansionRecord> Expansions;
    537   std::vector<CountedRegion> BranchRegions;
    538 
    539 public:
    540   CoverageData() = default;
    541 
    542   CoverageData(StringRef Filename) : Filename(Filename) {}
    543 
    544   /// Get the name of the file this data covers.
    545   StringRef getFilename() const { return Filename; }
    546 
    547   /// Get an iterator over the coverage segments for this object. The segments
    548   /// are guaranteed to be uniqued and sorted by location.
    549   std::vector<CoverageSegment>::const_iterator begin() const {
    550     return Segments.begin();
    551   }
    552 
    553   std::vector<CoverageSegment>::const_iterator end() const {
    554     return Segments.end();
    555   }
    556 
    557   bool empty() const { return Segments.empty(); }
    558 
    559   /// Expansions that can be further processed.
    560   ArrayRef<ExpansionRecord> getExpansions() const { return Expansions; }
    561 
    562   /// Branches that can be further processed.
    563   ArrayRef<CountedRegion> getBranches() const { return BranchRegions; }
    564 };
    565 
    566 /// The mapping of profile information to coverage data.
    567 ///
    568 /// This is the main interface to get coverage information, using a profile to
    569 /// fill out execution counts.
    570 class CoverageMapping {
    571   DenseMap<size_t, DenseSet<size_t>> RecordProvenance;
    572   std::vector<FunctionRecord> Functions;
    573   DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices;
    574   std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
    575 
    576   CoverageMapping() = default;
    577 
    578   // Load coverage records from readers.
    579   static Error loadFromReaders(
    580       ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
    581       IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage);
    582 
    583   /// Add a function record corresponding to \p Record.
    584   Error loadFunctionRecord(const CoverageMappingRecord &Record,
    585                            IndexedInstrProfReader &ProfileReader);
    586 
    587   /// Look up the indices for function records which are at least partially
    588   /// defined in the specified file. This is guaranteed to return a superset of
    589   /// such records: extra records not in the file may be included if there is
    590   /// a hash collision on the filename. Clients must be robust to collisions.
    591   ArrayRef<unsigned>
    592   getImpreciseRecordIndicesForFilename(StringRef Filename) const;
    593 
    594 public:
    595   CoverageMapping(const CoverageMapping &) = delete;
    596   CoverageMapping &operator=(const CoverageMapping &) = delete;
    597 
    598   /// Load the coverage mapping using the given readers.
    599   static Expected<std::unique_ptr<CoverageMapping>>
    600   load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
    601        IndexedInstrProfReader &ProfileReader);
    602 
    603   /// Load the coverage mapping from the given object files and profile. If
    604   /// \p Arches is non-empty, it must specify an architecture for each object.
    605   /// Ignores non-instrumented object files unless all are not instrumented.
    606   static Expected<std::unique_ptr<CoverageMapping>>
    607   load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
    608        ArrayRef<StringRef> Arches = None, StringRef CompilationDir = "");
    609 
    610   /// The number of functions that couldn't have their profiles mapped.
    611   ///
    612   /// This is a count of functions whose profile is out of date or otherwise
    613   /// can't be associated with any coverage information.
    614   unsigned getMismatchedCount() const { return FuncHashMismatches.size(); }
    615 
    616   /// A hash mismatch occurs when a profile record for a symbol does not have
    617   /// the same hash as a coverage mapping record for the same symbol. This
    618   /// returns a list of hash mismatches, where each mismatch is a pair of the
    619   /// symbol name and its coverage mapping hash.
    620   ArrayRef<std::pair<std::string, uint64_t>> getHashMismatches() const {
    621     return FuncHashMismatches;
    622   }
    623 
    624   /// Returns a lexicographically sorted, unique list of files that are
    625   /// covered.
    626   std::vector<StringRef> getUniqueSourceFiles() const;
    627 
    628   /// Get the coverage for a particular file.
    629   ///
    630   /// The given filename must be the name as recorded in the coverage
    631   /// information. That is, only names returned from getUniqueSourceFiles will
    632   /// yield a result.
    633   CoverageData getCoverageForFile(StringRef Filename) const;
    634 
    635   /// Get the coverage for a particular function.
    636   CoverageData getCoverageForFunction(const FunctionRecord &Function) const;
    637 
    638   /// Get the coverage for an expansion within a coverage set.
    639   CoverageData getCoverageForExpansion(const ExpansionRecord &Expansion) const;
    640 
    641   /// Gets all of the functions covered by this profile.
    642   iterator_range<FunctionRecordIterator> getCoveredFunctions() const {
    643     return make_range(FunctionRecordIterator(Functions),
    644                       FunctionRecordIterator());
    645   }
    646 
    647   /// Gets all of the functions in a particular file.
    648   iterator_range<FunctionRecordIterator>
    649   getCoveredFunctions(StringRef Filename) const {
    650     return make_range(FunctionRecordIterator(Functions, Filename),
    651                       FunctionRecordIterator());
    652   }
    653 
    654   /// Get the list of function instantiation groups in a particular file.
    655   ///
    656   /// Every instantiation group in a program is attributed to exactly one file:
    657   /// the file in which the definition for the common function begins.
    658   std::vector<InstantiationGroup>
    659   getInstantiationGroups(StringRef Filename) const;
    660 };
    661 
    662 /// Coverage statistics for a single line.
    663 class LineCoverageStats {
    664   uint64_t ExecutionCount;
    665   bool HasMultipleRegions;
    666   bool Mapped;
    667   unsigned Line;
    668   ArrayRef<const CoverageSegment *> LineSegments;
    669   const CoverageSegment *WrappedSegment;
    670 
    671   friend class LineCoverageIterator;
    672   LineCoverageStats() = default;
    673 
    674 public:
    675   LineCoverageStats(ArrayRef<const CoverageSegment *> LineSegments,
    676                     const CoverageSegment *WrappedSegment, unsigned Line);
    677 
    678   uint64_t getExecutionCount() const { return ExecutionCount; }
    679 
    680   bool hasMultipleRegions() const { return HasMultipleRegions; }
    681 
    682   bool isMapped() const { return Mapped; }
    683 
    684   unsigned getLine() const { return Line; }
    685 
    686   ArrayRef<const CoverageSegment *> getLineSegments() const {
    687     return LineSegments;
    688   }
    689 
    690   const CoverageSegment *getWrappedSegment() const { return WrappedSegment; }
    691 };
    692 
    693 /// An iterator over the \c LineCoverageStats objects for lines described by
    694 /// a \c CoverageData instance.
    695 class LineCoverageIterator
    696     : public iterator_facade_base<
    697           LineCoverageIterator, std::forward_iterator_tag, LineCoverageStats> {
    698 public:
    699   LineCoverageIterator(const CoverageData &CD)
    700       : LineCoverageIterator(CD, CD.begin()->Line) {}
    701 
    702   LineCoverageIterator(const CoverageData &CD, unsigned Line)
    703       : CD(CD), WrappedSegment(nullptr), Next(CD.begin()), Ended(false),
    704         Line(Line), Segments(), Stats() {
    705     this->operator++();
    706   }
    707 
    708   bool operator==(const LineCoverageIterator &R) const {
    709     return &CD == &R.CD && Next == R.Next && Ended == R.Ended;
    710   }
    711 
    712   const LineCoverageStats &operator*() const { return Stats; }
    713 
    714   LineCoverageStats &operator*() { return Stats; }
    715 
    716   LineCoverageIterator &operator++();
    717 
    718   LineCoverageIterator getEnd() const {
    719     auto EndIt = *this;
    720     EndIt.Next = CD.end();
    721     EndIt.Ended = true;
    722     return EndIt;
    723   }
    724 
    725 private:
    726   const CoverageData &CD;
    727   const CoverageSegment *WrappedSegment;
    728   std::vector<CoverageSegment>::const_iterator Next;
    729   bool Ended;
    730   unsigned Line;
    731   SmallVector<const CoverageSegment *, 4> Segments;
    732   LineCoverageStats Stats;
    733 };
    734 
    735 /// Get a \c LineCoverageIterator range for the lines described by \p CD.
    736 static inline iterator_range<LineCoverageIterator>
    737 getLineCoverageStats(const coverage::CoverageData &CD) {
    738   auto Begin = LineCoverageIterator(CD);
    739   auto End = Begin.getEnd();
    740   return make_range(Begin, End);
    741 }
    742 
    743 // Coverage mappping data (V2) has the following layout:
    744 // IPSK_covmap:
    745 //   [CoverageMapFileHeader]
    746 //   [ArrayStart]
    747 //    [CovMapFunctionRecordV2]
    748 //    [CovMapFunctionRecordV2]
    749 //    ...
    750 //   [ArrayEnd]
    751 //   [Encoded Filenames and Region Mapping Data]
    752 //
    753 // Coverage mappping data (V3) has the following layout:
    754 // IPSK_covmap:
    755 //   [CoverageMapFileHeader]
    756 //   [Encoded Filenames]
    757 // IPSK_covfun:
    758 //   [ArrayStart]
    759 //     odr_name_1: [CovMapFunctionRecordV3]
    760 //     odr_name_2: [CovMapFunctionRecordV3]
    761 //     ...
    762 //   [ArrayEnd]
    763 //
    764 // Both versions of the coverage mapping format encode the same information,
    765 // but the V3 format does so more compactly by taking advantage of linkonce_odr
    766 // semantics (it allows exactly 1 function record per name reference).
    767 
    768 /// This namespace defines accessors shared by different versions of coverage
    769 /// mapping records.
    770 namespace accessors {
    771 
    772 /// Return the structural hash associated with the function.
    773 template <class FuncRecordTy, support::endianness Endian>
    774 uint64_t getFuncHash(const FuncRecordTy *Record) {
    775   return support::endian::byte_swap<uint64_t, Endian>(Record->FuncHash);
    776 }
    777 
    778 /// Return the coverage map data size for the function.
    779 template <class FuncRecordTy, support::endianness Endian>
    780 uint64_t getDataSize(const FuncRecordTy *Record) {
    781   return support::endian::byte_swap<uint32_t, Endian>(Record->DataSize);
    782 }
    783 
    784 /// Return the function lookup key. The value is considered opaque.
    785 template <class FuncRecordTy, support::endianness Endian>
    786 uint64_t getFuncNameRef(const FuncRecordTy *Record) {
    787   return support::endian::byte_swap<uint64_t, Endian>(Record->NameRef);
    788 }
    789 
    790 /// Return the PGO name of the function. Used for formats in which the name is
    791 /// a hash.
    792 template <class FuncRecordTy, support::endianness Endian>
    793 Error getFuncNameViaRef(const FuncRecordTy *Record,
    794                         InstrProfSymtab &ProfileNames, StringRef &FuncName) {
    795   uint64_t NameRef = getFuncNameRef<FuncRecordTy, Endian>(Record);
    796   FuncName = ProfileNames.getFuncName(NameRef);
    797   return Error::success();
    798 }
    799 
    800 /// Read coverage mapping out-of-line, from \p MappingBuf. This is used when the
    801 /// coverage mapping is attached to the file header, instead of to the function
    802 /// record.
    803 template <class FuncRecordTy, support::endianness Endian>
    804 StringRef getCoverageMappingOutOfLine(const FuncRecordTy *Record,
    805                                       const char *MappingBuf) {
    806   return {MappingBuf, size_t(getDataSize<FuncRecordTy, Endian>(Record))};
    807 }
    808 
    809 /// Advance to the next out-of-line coverage mapping and its associated
    810 /// function record.
    811 template <class FuncRecordTy, support::endianness Endian>
    812 std::pair<const char *, const FuncRecordTy *>
    813 advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) {
    814   return {MappingBuf + getDataSize<FuncRecordTy, Endian>(Record), Record + 1};
    815 }
    816 
    817 } // end namespace accessors
    818 
    819 LLVM_PACKED_START
    820 template <class IntPtrT>
    821 struct CovMapFunctionRecordV1 {
    822   using ThisT = CovMapFunctionRecordV1<IntPtrT>;
    823 
    824 #define COVMAP_V1
    825 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
    826 #include "llvm/ProfileData/InstrProfData.inc"
    827 #undef COVMAP_V1
    828   CovMapFunctionRecordV1() = delete;
    829 
    830   template <support::endianness Endian> uint64_t getFuncHash() const {
    831     return accessors::getFuncHash<ThisT, Endian>(this);
    832   }
    833 
    834   template <support::endianness Endian> uint64_t getDataSize() const {
    835     return accessors::getDataSize<ThisT, Endian>(this);
    836   }
    837 
    838   /// Return function lookup key. The value is consider opaque.
    839   template <support::endianness Endian> IntPtrT getFuncNameRef() const {
    840     return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
    841   }
    842 
    843   /// Return the PGO name of the function.
    844   template <support::endianness Endian>
    845   Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
    846     IntPtrT NameRef = getFuncNameRef<Endian>();
    847     uint32_t NameS = support::endian::byte_swap<uint32_t, Endian>(NameSize);
    848     FuncName = ProfileNames.getFuncName(NameRef, NameS);
    849     if (NameS && FuncName.empty())
    850       return make_error<CoverageMapError>(coveragemap_error::malformed);
    851     return Error::success();
    852   }
    853 
    854   template <support::endianness Endian>
    855   std::pair<const char *, const ThisT *>
    856   advanceByOne(const char *MappingBuf) const {
    857     return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
    858   }
    859 
    860   template <support::endianness Endian> uint64_t getFilenamesRef() const {
    861     llvm_unreachable("V1 function format does not contain a filenames ref");
    862   }
    863 
    864   template <support::endianness Endian>
    865   StringRef getCoverageMapping(const char *MappingBuf) const {
    866     return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
    867                                                                  MappingBuf);
    868   }
    869 };
    870 
    871 struct CovMapFunctionRecordV2 {
    872   using ThisT = CovMapFunctionRecordV2;
    873 
    874 #define COVMAP_V2
    875 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
    876 #include "llvm/ProfileData/InstrProfData.inc"
    877 #undef COVMAP_V2
    878   CovMapFunctionRecordV2() = delete;
    879 
    880   template <support::endianness Endian> uint64_t getFuncHash() const {
    881     return accessors::getFuncHash<ThisT, Endian>(this);
    882   }
    883 
    884   template <support::endianness Endian> uint64_t getDataSize() const {
    885     return accessors::getDataSize<ThisT, Endian>(this);
    886   }
    887 
    888   template <support::endianness Endian> uint64_t getFuncNameRef() const {
    889     return accessors::getFuncNameRef<ThisT, Endian>(this);
    890   }
    891 
    892   template <support::endianness Endian>
    893   Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
    894     return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
    895                                                        FuncName);
    896   }
    897 
    898   template <support::endianness Endian>
    899   std::pair<const char *, const ThisT *>
    900   advanceByOne(const char *MappingBuf) const {
    901     return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
    902   }
    903 
    904   template <support::endianness Endian> uint64_t getFilenamesRef() const {
    905     llvm_unreachable("V2 function format does not contain a filenames ref");
    906   }
    907 
    908   template <support::endianness Endian>
    909   StringRef getCoverageMapping(const char *MappingBuf) const {
    910     return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
    911                                                                  MappingBuf);
    912   }
    913 };
    914 
    915 struct CovMapFunctionRecordV3 {
    916   using ThisT = CovMapFunctionRecordV3;
    917 
    918 #define COVMAP_V3
    919 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
    920 #include "llvm/ProfileData/InstrProfData.inc"
    921 #undef COVMAP_V3
    922   CovMapFunctionRecordV3() = delete;
    923 
    924   template <support::endianness Endian> uint64_t getFuncHash() const {
    925     return accessors::getFuncHash<ThisT, Endian>(this);
    926   }
    927 
    928   template <support::endianness Endian> uint64_t getDataSize() const {
    929     return accessors::getDataSize<ThisT, Endian>(this);
    930   }
    931 
    932   template <support::endianness Endian> uint64_t getFuncNameRef() const {
    933     return accessors::getFuncNameRef<ThisT, Endian>(this);
    934   }
    935 
    936   template <support::endianness Endian>
    937   Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
    938     return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
    939                                                        FuncName);
    940   }
    941 
    942   /// Get the filename set reference.
    943   template <support::endianness Endian> uint64_t getFilenamesRef() const {
    944     return support::endian::byte_swap<uint64_t, Endian>(FilenamesRef);
    945   }
    946 
    947   /// Read the inline coverage mapping. Ignore the buffer parameter, it is for
    948   /// out-of-line coverage mapping data only.
    949   template <support::endianness Endian>
    950   StringRef getCoverageMapping(const char *) const {
    951     return StringRef(&CoverageMapping, getDataSize<Endian>());
    952   }
    953 
    954   // Advance to the next inline coverage mapping and its associated function
    955   // record. Ignore the out-of-line coverage mapping buffer.
    956   template <support::endianness Endian>
    957   std::pair<const char *, const CovMapFunctionRecordV3 *>
    958   advanceByOne(const char *) const {
    959     assert(isAddrAligned(Align(8), this) && "Function record not aligned");
    960     const char *Next = ((const char *)this) + sizeof(CovMapFunctionRecordV3) -
    961                        sizeof(char) + getDataSize<Endian>();
    962     // Each function record has an alignment of 8, so we need to adjust
    963     // alignment before reading the next record.
    964     Next += offsetToAlignedAddr(Next, Align(8));
    965     return {nullptr, reinterpret_cast<const CovMapFunctionRecordV3 *>(Next)};
    966   }
    967 };
    968 
    969 // Per module coverage mapping data header, i.e. CoverageMapFileHeader
    970 // documented above.
    971 struct CovMapHeader {
    972 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
    973 #include "llvm/ProfileData/InstrProfData.inc"
    974   template <support::endianness Endian> uint32_t getNRecords() const {
    975     return support::endian::byte_swap<uint32_t, Endian>(NRecords);
    976   }
    977 
    978   template <support::endianness Endian> uint32_t getFilenamesSize() const {
    979     return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
    980   }
    981 
    982   template <support::endianness Endian> uint32_t getCoverageSize() const {
    983     return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
    984   }
    985 
    986   template <support::endianness Endian> uint32_t getVersion() const {
    987     return support::endian::byte_swap<uint32_t, Endian>(Version);
    988   }
    989 };
    990 
    991 LLVM_PACKED_END
    992 
    993 enum CovMapVersion {
    994   Version1 = 0,
    995   // Function's name reference from CovMapFuncRecord is changed from raw
    996   // name string pointer to MD5 to support name section compression. Name
    997   // section is also compressed.
    998   Version2 = 1,
    999   // A new interpretation of the columnEnd field is added in order to mark
   1000   // regions as gap areas.
   1001   Version3 = 2,
   1002   // Function records are named, uniqued, and moved to a dedicated section.
   1003   Version4 = 3,
   1004   // Branch regions referring to two counters are added
   1005   Version5 = 4,
   1006   // Compilation directory is stored separately and combined with relative
   1007   // filenames to produce an absolute file path.
   1008   Version6 = 5,
   1009   // The current version is Version6.
   1010   CurrentVersion = INSTR_PROF_COVMAP_VERSION
   1011 };
   1012 
   1013 template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
   1014   using CovMapFuncRecordType = CovMapFunctionRecordV3;
   1015   using NameRefType = uint64_t;
   1016 };
   1017 
   1018 template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version3, IntPtrT> {
   1019   using CovMapFuncRecordType = CovMapFunctionRecordV2;
   1020   using NameRefType = uint64_t;
   1021 };
   1022 
   1023 template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version2, IntPtrT> {
   1024   using CovMapFuncRecordType = CovMapFunctionRecordV2;
   1025   using NameRefType = uint64_t;
   1026 };
   1027 
   1028 template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
   1029   using CovMapFuncRecordType = CovMapFunctionRecordV1<IntPtrT>;
   1030   using NameRefType = IntPtrT;
   1031 };
   1032 
   1033 } // end namespace coverage
   1034 
   1035 /// Provide DenseMapInfo for CounterExpression
   1036 template<> struct DenseMapInfo<coverage::CounterExpression> {
   1037   static inline coverage::CounterExpression getEmptyKey() {
   1038     using namespace coverage;
   1039 
   1040     return CounterExpression(CounterExpression::ExprKind::Subtract,
   1041                              Counter::getCounter(~0U),
   1042                              Counter::getCounter(~0U));
   1043   }
   1044 
   1045   static inline coverage::CounterExpression getTombstoneKey() {
   1046     using namespace coverage;
   1047 
   1048     return CounterExpression(CounterExpression::ExprKind::Add,
   1049                              Counter::getCounter(~0U),
   1050                              Counter::getCounter(~0U));
   1051   }
   1052 
   1053   static unsigned getHashValue(const coverage::CounterExpression &V) {
   1054     return static_cast<unsigned>(
   1055         hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
   1056                      V.RHS.getKind(), V.RHS.getCounterID()));
   1057   }
   1058 
   1059   static bool isEqual(const coverage::CounterExpression &LHS,
   1060                       const coverage::CounterExpression &RHS) {
   1061     return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
   1062   }
   1063 };
   1064 
   1065 } // end namespace llvm
   1066 
   1067 #endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
   1068