LLVM  6.0.0svn
CoverageMapping.h
Go to the documentation of this file.
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"
27 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/Endian.h"
30 #include "llvm/Support/Error.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 
50 
51 enum class coveragemap_error {
52  success = 0,
53  eof,
56  truncated,
57  malformed
58 };
59 
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:
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:
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.
146  enum ExprKind { Subtract, Add };
148  Counter LHS, RHS;
149 
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.
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:
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.
205  enum RegionKind {
206  /// A CodeRegion associates some code with a counter
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.
213 
214  /// A SkippedRegion represents a source range with code that was skipped
215  /// by a preprocessor or similar means.
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 
224  unsigned FileID, ExpandedFileID;
225  unsigned LineStart, ColumnStart, LineEnd, ColumnEnd;
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.
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.
283  ArrayRef<uint64_t> CounterValues;
284 
285 public:
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.
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 
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.
326  : public iterator_facade_base<FunctionRecordIterator,
327  std::forward_iterator_tag, FunctionRecord> {
328  ArrayRef<FunctionRecord> Records;
330  StringRef Filename;
331 
332  /// Skip records whose primary file is not \c Filename.
333  void skipOtherFiles();
334 
335 public:
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 
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.
364  /// The abstract file this expansion covers.
365  unsigned FileID;
366  /// The region that expands to this record.
368  /// Coverage for the expansion.
370 
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.
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.
391  /// Whether this enters a gap region.
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).
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;
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.
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.
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.
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.
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.
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.
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.
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.
578  return make_range(FunctionRecordIterator(Functions),
580  }
581 
582  /// Gets all of the functions in a particular file.
584  getCoveredFunctions(StringRef Filename) const {
585  return make_range(FunctionRecordIterator(Functions, Filename),
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.
599  uint64_t ExecutionCount;
600  bool HasMultipleRegions;
601  bool Mapped;
602  unsigned Line;
604  const CoverageSegment *WrappedSegment;
605 
606  friend class LineCoverageIterator;
607  LineCoverageStats() = default;
608 
609 public:
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 
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.
631  : public iterator_facade_base<
632  LineCoverageIterator, std::forward_iterator_tag, LineCoverageStats> {
633 public:
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 
652 
653  LineCoverageIterator &operator++();
654 
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;
670 };
671 
672 /// Get a \c LineCoverageIterator range for the lines described by \p 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]
689 template <class IntPtrT> struct CovMapFunctionRecordV1 {
690 #define COVMAP_V1
691 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
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 
723 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
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;
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 
773 
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 {
789  using NameRefType = uint64_t;
790 };
791 
792 template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
794  using NameRefType = IntPtrT;
795 };
796 
797 } // end namespace coverage
798 
799 /// Provide DenseMapInfo for CounterExpression
800 template<> struct DenseMapInfo<coverage::CounterExpression> {
802  using namespace coverage;
803 
804  return CounterExpression(CounterExpression::ExprKind::Subtract,
805  Counter::getCounter(~0U),
806  Counter::getCounter(~0U));
807  }
808 
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>(
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
const NoneType None
Definition: None.h:24
uint64_t CallInst * C
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:244
static coverage::CounterExpression getTombstoneKey()
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:411
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:235
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
static Counter getZero()
Return the counter that represents the number zero.
unsigned getMismatchedCount() const
The number of functions that couldn&#39;t have their profiles mapped.
static CounterMappingRegion makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
void setCounts(ArrayRef< uint64_t > Counts)
CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
This provides a very simple, boring adaptor for a begin and end iterator into a range type...
static bool isEqual(const coverage::CounterExpression &LHS, const coverage::CounterExpression &RHS)
LineCoverageIterator(const CoverageData &CD)
std::error_code make_error_code(coveragemap_error E)
friend bool operator==(const Counter &LHS, const Counter &RHS)
const CoverageSegment * getWrappedSegment() const
ArrayRef< std::pair< std::string, uint64_t > > getCounterMismatches() const
A counter mismatch occurs when there is an error when evaluating the counter expressions in a coverag...
F(f)
void pushRegion(CounterMappingRegion Region, uint64_t Count)
unsigned getLine() const
Get the line where the common function was defined.
A Counter expression is a value that represents an arithmetic operation with two counters.
FunctionRecord(StringRef Name, ArrayRef< StringRef > Filenames)
uint64_t getTotalExecutionCount() const
Get the total execution count of all instantiations in this group.
ArrayRef< std::pair< std::string, uint64_t > > getHashMismatches() const
A hash mismatch occurs when a profile record for a symbol does not have the same hash as a coverage m...
void log(raw_ostream &OS) const override
Print an error message to an output stream.
friend bool operator!=(const Counter &LHS, const Counter &RHS)
friend bool operator<(const Counter &LHS, const Counter &RHS)
friend bool operator==(const CoverageSegment &L, const CoverageSegment &R)
gvn Early GVN Hoisting of Expressions
Definition: GVNHoist.cpp:1204
Iterator over Functions, optionally filtered to a single file.
const LineCoverageStats & operator*() const
Definition: BitVector.h:920
unsigned Col
The column where this segment begins.
ArrayRef< CounterExpression > getExpressions() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
An iterator over the LineCoverageStats objects for lines described by a CoverageData instance...
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
block placement Basic Block Placement Stats
CoverageSegment(unsigned Line, unsigned Col, uint64_t Count, bool IsRegionEntry, bool IsGapRegion=false)
const CountedRegion & Region
The region that expands to this record.
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize)
Return function&#39;s PGO name from the function name&#39;s symbol address in the object file.
std::pair< unsigned, unsigned > LineColPair
const FunctionRecord & operator*() const
Coverage information to be processed or displayed.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
ArrayRef< const FunctionRecord * > getInstantiations() const
Get the instantiations in this group.
CoverageMapError(coveragemap_error Err)
static CounterMappingRegion makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:68
ArrayRef< const CoverageSegment * > getLineSegments() const
const std::error_category & coveragemap_category()
iterator_range< FunctionRecordIterator > getCoveredFunctions(StringRef Filename) const
Gets all of the functions in a particular file.
The execution count information starting at a point in a file.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
static CounterMappingRegion makeRegion(Counter Count, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
Coverage mapping information for a single function.
uint64_t ExecutionCount
The number of times this function was executed.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
An instantiation group contains a FunctionRecord list, such that each record corresponds to a distinc...
A CodeRegion associates some code with a counter.
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
A Counter mapping region associates a source range with a specific counter.
bool IsRegionEntry
Whether this enters a new region or returns to a previous count.
bool operator==(const FunctionRecordIterator &RHS) const
static ManagedStatic< _object_error_category > error_category
Definition: Error.cpp:74
size_t size() const
Get the number of instantiations in this group.
static const unsigned End
CounterMappingRegion(Counter Count, unsigned FileID, unsigned ExpandedFileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
Associates a source range with an execution count.
static coverage::CounterExpression getEmptyKey()
static unsigned getHashValue(const coverage::CounterExpression &V)
CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
uint32_t getCoverageSize() const
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Code coverage information for a single function.
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
iterator_range< FunctionRecordIterator > getCoveredFunctions() const
Gets all of the functions covered by this profile.
Coverage statistics for a single line.
FunctionRecordIterator(ArrayRef< FunctionRecord > Records_, StringRef Filename="")
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
bool operator==(const LineCoverageIterator &R) const
ExpansionRecord(const CountedRegion &Region, const FunctionRecord &Function)
iterator end() const
Definition: ArrayRef.h:138
uint64_t Count
The execution count, or zero if no count was recorded.
bool HasCount
When false, the segment was uninstrumented or skipped.
std::vector< CoverageSegment >::const_iterator begin() const
Get an iterator over the coverage segments for this object.
An ExpansionRegion represents a file expansion region that associates a source range with the expansi...
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
A range adaptor for a pair of iterators.
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:602
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const
std::vector< CoverageSegment >::const_iterator end() const
Base class for user error types.
Definition: Error.h:331
LineCoverageIterator getEnd() const
The mapping of profile information to coverage data.
unsigned Line
The line where this segment begins.
CoverageData(StringRef Filename)
Basic Alias true
void dump(const Counter &C) const
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
unsigned getExpressionID() const
CounterKind getKind() const
bool hasName() const
Check if the instantiations in this group have a common mangled name.
#define I(x, y, z)
Definition: MD5.cpp:58
CounterMappingContext(ArrayRef< CounterExpression > Expressions, ArrayRef< uint64_t > CounterValues=None)
std::vector< CountedRegion > CountedRegions
Regions in the function along with their counts.
#define LLVM_PACKED_START
Definition: Compiler.h:349
std::string Name
Raw function name.
ArrayRef< ExpansionRecord > getExpansions() const
Expansions that can be further processed.
const unsigned Kind
unsigned FileID
The abstract file this expansion covers.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool IsGapRegion
Whether this enters a gap region.
unsigned getCounterID() const
std::vector< std::string > Filenames
Associated files.
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
StringSet - A wrapper for StringMap that provides set-like functionality.
Definition: StringSet.h:28
StringRef getName() const
Get the common mangled name for instantiations in this group.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
LineCoverageIterator(const CoverageData &CD, unsigned Line)
uint32_t getFilenamesSize() const
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
Reader for the indexed binary instrprof format.
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
A Counter expression builder is used to construct the counter expressions.
loop simplify
static iterator_range< LineCoverageIterator > getLineCoverageStats(const coverage::CoverageData &CD)
Get a LineCoverageIterator range for the lines described by CD.
A Counter is an abstract value that describes how to compute the execution count for a region of code...
unsigned getColumn() const
Get the column where the common function was defined.
const uint64_t Version
Definition: InstrProf.h:867
static CounterMappingRegion makeGapRegion(Counter Count, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
const FunctionRecord & Function
Coverage for the expansion.
#define LLVM_PACKED_END
Definition: Compiler.h:350
StringRef getFilename() const
Get the name of the file this data covers.
Coverage information for a macro expansion or #included file.
FunctionRecordIterator & operator++()