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