LLVM 18.0.0git
CoverageMapping.h
Go to the documentation of this file.
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"
24#include "llvm/Object/BuildID.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
42namespace llvm {
43
44class IndexedInstrProfReader;
45
46namespace object {
47class BuildIDFetcher;
48} // namespace object
49
50namespace vfs {
51class FileSystem;
52} // namespace vfs
53
54namespace coverage {
55
58
60 success = 0,
61 eof,
68};
69
70const std::error_category &coveragemap_category();
71
72inline std::error_code make_error_code(coveragemap_error E) {
73 return std::error_code(static_cast<int>(E), coveragemap_category());
74}
75
76class CoverageMapError : public ErrorInfo<CoverageMapError> {
77public:
79 : Err(Err), Msg(ErrStr.str()) {
80 assert(Err != coveragemap_error::success && "Not an error");
81 }
82
83 std::string message() const override;
84
85 void log(raw_ostream &OS) const override { OS << message(); }
86
87 std::error_code convertToErrorCode() const override {
88 return make_error_code(Err);
89 }
90
91 coveragemap_error get() const { return Err; }
92 const std::string &getMessage() const { return Msg; }
93
94 static char ID;
95
96private:
98 std::string Msg;
99};
100
101/// A Counter is an abstract value that describes how to compute the
102/// execution count for a region of code using the collected profile count data.
103struct Counter {
104 /// The CounterExpression kind (Add or Subtract) is encoded in bit 0 next to
105 /// the CounterKind. This means CounterKind has to leave bit 0 free.
107 static const unsigned EncodingTagBits = 2;
108 static const unsigned EncodingTagMask = 0x3;
110 EncodingTagBits + 1;
111
112private:
113 CounterKind Kind = Zero;
114 unsigned ID = 0;
115
116 Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
117
118public:
119 Counter() = default;
120
121 CounterKind getKind() const { return Kind; }
122
123 bool isZero() const { return Kind == Zero; }
124
125 bool isExpression() const { return Kind == Expression; }
126
127 unsigned getCounterID() const { return ID; }
128
129 unsigned getExpressionID() const { return ID; }
130
131 friend bool operator==(const Counter &LHS, const Counter &RHS) {
132 return LHS.Kind == RHS.Kind && LHS.ID == RHS.ID;
133 }
134
135 friend bool operator!=(const Counter &LHS, const Counter &RHS) {
136 return !(LHS == RHS);
137 }
138
139 friend bool operator<(const Counter &LHS, const Counter &RHS) {
140 return std::tie(LHS.Kind, LHS.ID) < std::tie(RHS.Kind, RHS.ID);
141 }
142
143 /// Return the counter that represents the number zero.
144 static Counter getZero() { return Counter(); }
145
146 /// Return the counter that corresponds to a specific profile counter.
147 static Counter getCounter(unsigned CounterId) {
148 return Counter(CounterValueReference, CounterId);
149 }
150
151 /// Return the counter that corresponds to a specific addition counter
152 /// expression.
153 static Counter getExpression(unsigned ExpressionId) {
154 return Counter(Expression, ExpressionId);
155 }
156};
157
158/// A Counter expression is a value that represents an arithmetic operation
159/// with two counters.
164
166 : Kind(Kind), LHS(LHS), RHS(RHS) {}
167};
168
169/// A Counter expression builder is used to construct the counter expressions.
170/// It avoids unnecessary duplication and simplifies algebraic expressions.
172 /// A list of all the counter expressions
173 std::vector<CounterExpression> Expressions;
174
175 /// A lookup table for the index of a given expression.
177
178 /// Return the counter which corresponds to the given expression.
179 ///
180 /// If the given expression is already stored in the builder, a counter
181 /// that references that expression is returned. Otherwise, the given
182 /// expression is added to the builder's collection of expressions.
183 Counter get(const CounterExpression &E);
184
185 /// Represents a term in a counter expression tree.
186 struct Term {
187 unsigned CounterID;
188 int Factor;
189
190 Term(unsigned CounterID, int Factor)
191 : CounterID(CounterID), Factor(Factor) {}
192 };
193
194 /// Gather the terms of the expression tree for processing.
195 ///
196 /// This collects each addition and subtraction referenced by the counter into
197 /// a sequence that can be sorted and combined to build a simplified counter
198 /// expression.
199 void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms);
200
201 /// Simplifies the given expression tree
202 /// by getting rid of algebraically redundant operations.
203 Counter simplify(Counter ExpressionTree);
204
205public:
206 ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
207
208 /// Return a counter that represents the expression that adds LHS and RHS.
209 Counter add(Counter LHS, Counter RHS, bool Simplify = true);
210
211 /// Return a counter that represents the expression that subtracts RHS from
212 /// LHS.
213 Counter subtract(Counter LHS, Counter RHS, bool Simplify = true);
214};
215
216using LineColPair = std::pair<unsigned, unsigned>;
217
218/// A Counter mapping region associates a source range with a specific counter.
221 /// A CodeRegion associates some code with a counter
223
224 /// An ExpansionRegion represents a file expansion region that associates
225 /// a source range with the expansion of a virtual source file, such as
226 /// for a macro instantiation or #include file.
228
229 /// A SkippedRegion represents a source range with code that was skipped
230 /// by a preprocessor or similar means.
232
233 /// A GapRegion is like a CodeRegion, but its count is only set as the
234 /// line execution count when its the only region in the line.
236
237 /// A BranchRegion represents leaf-level boolean expressions and is
238 /// associated with two counters, each representing the number of times the
239 /// expression evaluates to true or false.
241 };
242
243 /// Primary Counter that is also used for Branch Regions (TrueCount).
245
246 /// Secondary Counter used for Branch Regions (FalseCount).
248
252
254 unsigned LineStart, unsigned ColumnStart,
255 unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
259
261 unsigned ExpandedFileID, unsigned LineStart,
262 unsigned ColumnStart, unsigned LineEnd,
263 unsigned ColumnEnd, RegionKind Kind)
267 Kind(Kind) {}
268
271 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
274 }
275
277 makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart,
278 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
282 }
283
285 makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart,
286 unsigned LineEnd, unsigned ColumnEnd) {
289 }
290
293 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
295 LineEnd, (1U << 31) | ColumnEnd, GapRegion);
296 }
297
300 unsigned LineStart, unsigned ColumnStart, unsigned LineEnd,
301 unsigned ColumnEnd) {
304 }
305
306 inline LineColPair startLoc() const {
308 }
309
310 inline LineColPair endLoc() const { return LineColPair(LineEnd, ColumnEnd); }
311};
312
313/// Associates a source range with an execution count.
317 bool Folded;
318
322
327};
328
329/// A Counter mapping context is used to connect the counters, expressions
330/// and the obtained counter values.
332 ArrayRef<CounterExpression> Expressions;
333 ArrayRef<uint64_t> CounterValues;
334
335public:
337 ArrayRef<uint64_t> CounterValues = std::nullopt)
338 : Expressions(Expressions), CounterValues(CounterValues) {}
339
340 void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
341
342 void dump(const Counter &C, raw_ostream &OS) const;
343 void dump(const Counter &C) const { dump(C, dbgs()); }
344
345 /// Return the number of times that a region of code associated with this
346 /// counter was executed.
347 Expected<int64_t> evaluate(const Counter &C) const;
348
349 unsigned getMaxCounterID(const Counter &C) const;
350};
351
352/// Code coverage information for a single function.
354 /// Raw function name.
355 std::string Name;
356 /// Mapping from FileID (i.e. vector index) to filename. Used to support
357 /// macro expansions within a function in which the macro and function are
358 /// defined in separate files.
359 ///
360 /// TODO: Uniquing filenames across all function records may be a performance
361 /// optimization.
362 std::vector<std::string> Filenames;
363 /// Regions in the function along with their counts.
364 std::vector<CountedRegion> CountedRegions;
365 /// Branch Regions in the function along with their counts.
366 std::vector<CountedRegion> CountedBranchRegions;
367 /// The number of times this function was executed.
369
371 : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
372
375
377 uint64_t FalseCount) {
379 CountedBranchRegions.emplace_back(Region, Count, FalseCount);
380 // If both counters are hard-coded to zero, then this region represents a
381 // constant-folded branch.
382 if (Region.Count.isZero() && Region.FalseCount.isZero())
383 CountedBranchRegions.back().Folded = true;
384 return;
385 }
386 if (CountedRegions.empty())
387 ExecutionCount = Count;
388 CountedRegions.emplace_back(Region, Count, FalseCount);
389 }
390};
391
392/// Iterator over Functions, optionally filtered to a single file.
394 : public iterator_facade_base<FunctionRecordIterator,
395 std::forward_iterator_tag, FunctionRecord> {
398 StringRef Filename;
399
400 /// Skip records whose primary file is not \c Filename.
401 void skipOtherFiles();
402
403public:
405 StringRef Filename = "")
406 : Records(Records_), Current(Records.begin()), Filename(Filename) {
407 skipOtherFiles();
408 }
409
410 FunctionRecordIterator() : Current(Records.begin()) {}
411
413 return Current == RHS.Current && Filename == RHS.Filename;
414 }
415
416 const FunctionRecord &operator*() const { return *Current; }
417
419 assert(Current != Records.end() && "incremented past end");
420 ++Current;
421 skipOtherFiles();
422 return *this;
423 }
424};
425
426/// Coverage information for a macro expansion or #included file.
427///
428/// When covered code has pieces that can be expanded for more detail, such as a
429/// preprocessor macro use and its definition, these are represented as
430/// expansions whose coverage can be looked up independently.
432 /// The abstract file this expansion covers.
433 unsigned FileID;
434 /// The region that expands to this record.
436 /// Coverage for the expansion.
438
441 : FileID(Region.ExpandedFileID), Region(Region), Function(Function) {}
442};
443
444/// The execution count information starting at a point in a file.
445///
446/// A sequence of CoverageSegments gives execution counts for a file in format
447/// that's simple to iterate through for processing.
449 /// The line where this segment begins.
450 unsigned Line;
451 /// The column where this segment begins.
452 unsigned Col;
453 /// The execution count, or zero if no count was recorded.
455 /// When false, the segment was uninstrumented or skipped.
457 /// Whether this enters a new region or returns to a previous count.
459 /// Whether this enters a gap region.
461
462 CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
463 : Line(Line), Col(Col), Count(0), HasCount(false),
465
466 CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
467 bool IsRegionEntry, bool IsGapRegion = false,
468 bool IsBranchRegion = false)
471
472 friend bool operator==(const CoverageSegment &L, const CoverageSegment &R) {
473 return std::tie(L.Line, L.Col, L.Count, L.HasCount, L.IsRegionEntry,
474 L.IsGapRegion) == std::tie(R.Line, R.Col, R.Count,
475 R.HasCount, R.IsRegionEntry,
476 R.IsGapRegion);
477 }
478};
479
480/// An instantiation group contains a \c FunctionRecord list, such that each
481/// record corresponds to a distinct instantiation of the same function.
482///
483/// Note that it's possible for a function to have more than one instantiation
484/// (consider C++ template specializations or static inline functions).
486 friend class CoverageMapping;
487
488 unsigned Line;
489 unsigned Col;
490 std::vector<const FunctionRecord *> Instantiations;
491
492 InstantiationGroup(unsigned Line, unsigned Col,
493 std::vector<const FunctionRecord *> Instantiations)
494 : Line(Line), Col(Col), Instantiations(std::move(Instantiations)) {}
495
496public:
499
500 /// Get the number of instantiations in this group.
501 size_t size() const { return Instantiations.size(); }
502
503 /// Get the line where the common function was defined.
504 unsigned getLine() const { return Line; }
505
506 /// Get the column where the common function was defined.
507 unsigned getColumn() const { return Col; }
508
509 /// Check if the instantiations in this group have a common mangled name.
510 bool hasName() const {
511 for (unsigned I = 1, E = Instantiations.size(); I < E; ++I)
512 if (Instantiations[I]->Name != Instantiations[0]->Name)
513 return false;
514 return true;
515 }
516
517 /// Get the common mangled name for instantiations in this group.
519 assert(hasName() && "Instantiations don't have a shared name");
520 return Instantiations[0]->Name;
521 }
522
523 /// Get the total execution count of all instantiations in this group.
525 uint64_t Count = 0;
526 for (const FunctionRecord *F : Instantiations)
527 Count += F->ExecutionCount;
528 return Count;
529 }
530
531 /// Get the instantiations in this group.
533 return Instantiations;
534 }
535};
536
537/// Coverage information to be processed or displayed.
538///
539/// This represents the coverage of an entire file, expansion, or function. It
540/// provides a sequence of CoverageSegments to iterate through, as well as the
541/// list of expansions that can be further processed.
543 friend class CoverageMapping;
544
545 std::string Filename;
546 std::vector<CoverageSegment> Segments;
547 std::vector<ExpansionRecord> Expansions;
548 std::vector<CountedRegion> BranchRegions;
549
550public:
551 CoverageData() = default;
552
553 CoverageData(StringRef Filename) : Filename(Filename) {}
554
555 /// Get the name of the file this data covers.
556 StringRef getFilename() const { return Filename; }
557
558 /// Get an iterator over the coverage segments for this object. The segments
559 /// are guaranteed to be uniqued and sorted by location.
560 std::vector<CoverageSegment>::const_iterator begin() const {
561 return Segments.begin();
562 }
563
564 std::vector<CoverageSegment>::const_iterator end() const {
565 return Segments.end();
566 }
567
568 bool empty() const { return Segments.empty(); }
569
570 /// Expansions that can be further processed.
571 ArrayRef<ExpansionRecord> getExpansions() const { return Expansions; }
572
573 /// Branches that can be further processed.
574 ArrayRef<CountedRegion> getBranches() const { return BranchRegions; }
575};
576
577/// The mapping of profile information to coverage data.
578///
579/// This is the main interface to get coverage information, using a profile to
580/// fill out execution counts.
582 DenseMap<size_t, DenseSet<size_t>> RecordProvenance;
583 std::vector<FunctionRecord> Functions;
584 DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices;
585 std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
586
587 CoverageMapping() = default;
588
589 // Load coverage records from readers.
590 static Error loadFromReaders(
591 ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
592 IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage);
593
594 // Load coverage records from file.
595 static Error
596 loadFromFile(StringRef Filename, StringRef Arch, StringRef CompilationDir,
597 IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
598 bool &DataFound,
599 SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr);
600
601 /// Add a function record corresponding to \p Record.
602 Error loadFunctionRecord(const CoverageMappingRecord &Record,
603 IndexedInstrProfReader &ProfileReader);
604
605 /// Look up the indices for function records which are at least partially
606 /// defined in the specified file. This is guaranteed to return a superset of
607 /// such records: extra records not in the file may be included if there is
608 /// a hash collision on the filename. Clients must be robust to collisions.
610 getImpreciseRecordIndicesForFilename(StringRef Filename) const;
611
612public:
615
616 /// Load the coverage mapping using the given readers.
618 load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
619 IndexedInstrProfReader &ProfileReader);
620
621 /// Load the coverage mapping from the given object files and profile. If
622 /// \p Arches is non-empty, it must specify an architecture for each object.
623 /// Ignores non-instrumented object files unless all are not instrumented.
625 load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
626 vfs::FileSystem &FS, ArrayRef<StringRef> Arches = std::nullopt,
627 StringRef CompilationDir = "",
628 const object::BuildIDFetcher *BIDFetcher = nullptr,
629 bool CheckBinaryIDs = false);
630
631 /// The number of functions that couldn't have their profiles mapped.
632 ///
633 /// This is a count of functions whose profile is out of date or otherwise
634 /// can't be associated with any coverage information.
635 unsigned getMismatchedCount() const { return FuncHashMismatches.size(); }
636
637 /// A hash mismatch occurs when a profile record for a symbol does not have
638 /// the same hash as a coverage mapping record for the same symbol. This
639 /// returns a list of hash mismatches, where each mismatch is a pair of the
640 /// symbol name and its coverage mapping hash.
642 return FuncHashMismatches;
643 }
644
645 /// Returns a lexicographically sorted, unique list of files that are
646 /// covered.
647 std::vector<StringRef> getUniqueSourceFiles() const;
648
649 /// Get the coverage for a particular file.
650 ///
651 /// The given filename must be the name as recorded in the coverage
652 /// information. That is, only names returned from getUniqueSourceFiles will
653 /// yield a result.
655
656 /// Get the coverage for a particular function.
658
659 /// Get the coverage for an expansion within a coverage set.
661
662 /// Gets all of the functions covered by this profile.
664 return make_range(FunctionRecordIterator(Functions),
666 }
667
668 /// Gets all of the functions in a particular file.
671 return make_range(FunctionRecordIterator(Functions, Filename),
673 }
674
675 /// Get the list of function instantiation groups in a particular file.
676 ///
677 /// Every instantiation group in a program is attributed to exactly one file:
678 /// the file in which the definition for the common function begins.
679 std::vector<InstantiationGroup>
680 getInstantiationGroups(StringRef Filename) const;
681};
682
683/// Coverage statistics for a single line.
685 uint64_t ExecutionCount;
686 bool HasMultipleRegions;
687 bool Mapped;
688 unsigned Line;
690 const CoverageSegment *WrappedSegment;
691
693 LineCoverageStats() = default;
694
695public:
697 const CoverageSegment *WrappedSegment, unsigned Line);
698
699 uint64_t getExecutionCount() const { return ExecutionCount; }
700
701 bool hasMultipleRegions() const { return HasMultipleRegions; }
702
703 bool isMapped() const { return Mapped; }
704
705 unsigned getLine() const { return Line; }
706
708 return LineSegments;
709 }
710
711 const CoverageSegment *getWrappedSegment() const { return WrappedSegment; }
712};
713
714/// An iterator over the \c LineCoverageStats objects for lines described by
715/// a \c CoverageData instance.
717 : public iterator_facade_base<LineCoverageIterator,
718 std::forward_iterator_tag,
719 const LineCoverageStats> {
720public:
722 : LineCoverageIterator(CD, CD.begin()->Line) {}
723
724 LineCoverageIterator(const CoverageData &CD, unsigned Line)
725 : CD(CD), WrappedSegment(nullptr), Next(CD.begin()), Ended(false),
726 Line(Line) {
727 this->operator++();
728 }
729
730 bool operator==(const LineCoverageIterator &R) const {
731 return &CD == &R.CD && Next == R.Next && Ended == R.Ended;
732 }
733
734 const LineCoverageStats &operator*() const { return Stats; }
735
737
739 auto EndIt = *this;
740 EndIt.Next = CD.end();
741 EndIt.Ended = true;
742 return EndIt;
743 }
744
745private:
746 const CoverageData &CD;
747 const CoverageSegment *WrappedSegment;
748 std::vector<CoverageSegment>::const_iterator Next;
749 bool Ended;
750 unsigned Line;
752 LineCoverageStats Stats;
753};
754
755/// Get a \c LineCoverageIterator range for the lines described by \p CD.
758 auto Begin = LineCoverageIterator(CD);
759 auto End = Begin.getEnd();
760 return make_range(Begin, End);
761}
762
763// Coverage mappping data (V2) has the following layout:
764// IPSK_covmap:
765// [CoverageMapFileHeader]
766// [ArrayStart]
767// [CovMapFunctionRecordV2]
768// [CovMapFunctionRecordV2]
769// ...
770// [ArrayEnd]
771// [Encoded Filenames and Region Mapping Data]
772//
773// Coverage mappping data (V3) has the following layout:
774// IPSK_covmap:
775// [CoverageMapFileHeader]
776// [Encoded Filenames]
777// IPSK_covfun:
778// [ArrayStart]
779// odr_name_1: [CovMapFunctionRecordV3]
780// odr_name_2: [CovMapFunctionRecordV3]
781// ...
782// [ArrayEnd]
783//
784// Both versions of the coverage mapping format encode the same information,
785// but the V3 format does so more compactly by taking advantage of linkonce_odr
786// semantics (it allows exactly 1 function record per name reference).
787
788/// This namespace defines accessors shared by different versions of coverage
789/// mapping records.
790namespace accessors {
791
792/// Return the structural hash associated with the function.
793template <class FuncRecordTy, llvm::endianness Endian>
794uint64_t getFuncHash(const FuncRecordTy *Record) {
795 return support::endian::byte_swap<uint64_t, Endian>(Record->FuncHash);
796}
797
798/// Return the coverage map data size for the function.
799template <class FuncRecordTy, llvm::endianness Endian>
800uint64_t getDataSize(const FuncRecordTy *Record) {
801 return support::endian::byte_swap<uint32_t, Endian>(Record->DataSize);
802}
803
804/// Return the function lookup key. The value is considered opaque.
805template <class FuncRecordTy, llvm::endianness Endian>
806uint64_t getFuncNameRef(const FuncRecordTy *Record) {
807 return support::endian::byte_swap<uint64_t, Endian>(Record->NameRef);
808}
809
810/// Return the PGO name of the function. Used for formats in which the name is
811/// a hash.
812template <class FuncRecordTy, llvm::endianness Endian>
813Error getFuncNameViaRef(const FuncRecordTy *Record,
814 InstrProfSymtab &ProfileNames, StringRef &FuncName) {
815 uint64_t NameRef = getFuncNameRef<FuncRecordTy, Endian>(Record);
816 FuncName = ProfileNames.getFuncOrVarName(NameRef);
817 return Error::success();
818}
819
820/// Read coverage mapping out-of-line, from \p MappingBuf. This is used when the
821/// coverage mapping is attached to the file header, instead of to the function
822/// record.
823template <class FuncRecordTy, llvm::endianness Endian>
825 const char *MappingBuf) {
826 return {MappingBuf, size_t(getDataSize<FuncRecordTy, Endian>(Record))};
827}
828
829/// Advance to the next out-of-line coverage mapping and its associated
830/// function record.
831template <class FuncRecordTy, llvm::endianness Endian>
832std::pair<const char *, const FuncRecordTy *>
833advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) {
834 return {MappingBuf + getDataSize<FuncRecordTy, Endian>(Record), Record + 1};
835}
836
837} // end namespace accessors
838
840template <class IntPtrT>
843
844#define COVMAP_V1
845#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
847#undef COVMAP_V1
849
850 template <llvm::endianness Endian> uint64_t getFuncHash() const {
851 return accessors::getFuncHash<ThisT, Endian>(this);
852 }
853
854 template <llvm::endianness Endian> uint64_t getDataSize() const {
855 return accessors::getDataSize<ThisT, Endian>(this);
856 }
857
858 /// Return function lookup key. The value is consider opaque.
859 template <llvm::endianness Endian> IntPtrT getFuncNameRef() const {
860 return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
861 }
862
863 /// Return the PGO name of the function.
864 template <llvm::endianness Endian>
865 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
866 IntPtrT NameRef = getFuncNameRef<Endian>();
867 uint32_t NameS = support::endian::byte_swap<uint32_t, Endian>(NameSize);
868 FuncName = ProfileNames.getFuncName(NameRef, NameS);
869 if (NameS && FuncName.empty())
870 return make_error<CoverageMapError>(coveragemap_error::malformed,
871 "function name is empty");
872 return Error::success();
873 }
874
875 template <llvm::endianness Endian>
876 std::pair<const char *, const ThisT *>
877 advanceByOne(const char *MappingBuf) const {
878 return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
879 }
880
881 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
882 llvm_unreachable("V1 function format does not contain a filenames ref");
883 }
884
885 template <llvm::endianness Endian>
886 StringRef getCoverageMapping(const char *MappingBuf) const {
887 return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
888 MappingBuf);
889 }
890};
891
894
895#define COVMAP_V2
896#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
898#undef COVMAP_V2
900
901 template <llvm::endianness Endian> uint64_t getFuncHash() const {
902 return accessors::getFuncHash<ThisT, Endian>(this);
903 }
904
905 template <llvm::endianness Endian> uint64_t getDataSize() const {
906 return accessors::getDataSize<ThisT, Endian>(this);
907 }
908
909 template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
910 return accessors::getFuncNameRef<ThisT, Endian>(this);
911 }
912
913 template <llvm::endianness Endian>
914 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
915 return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
916 FuncName);
917 }
918
919 template <llvm::endianness Endian>
920 std::pair<const char *, const ThisT *>
921 advanceByOne(const char *MappingBuf) const {
922 return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
923 }
924
925 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
926 llvm_unreachable("V2 function format does not contain a filenames ref");
927 }
928
929 template <llvm::endianness Endian>
930 StringRef getCoverageMapping(const char *MappingBuf) const {
931 return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
932 MappingBuf);
933 }
934};
935
938
939#define COVMAP_V3
940#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
942#undef COVMAP_V3
944
945 template <llvm::endianness Endian> uint64_t getFuncHash() const {
946 return accessors::getFuncHash<ThisT, Endian>(this);
947 }
948
949 template <llvm::endianness Endian> uint64_t getDataSize() const {
950 return accessors::getDataSize<ThisT, Endian>(this);
951 }
952
953 template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
954 return accessors::getFuncNameRef<ThisT, Endian>(this);
955 }
956
957 template <llvm::endianness Endian>
958 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
959 return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
960 FuncName);
961 }
962
963 /// Get the filename set reference.
964 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
965 return support::endian::byte_swap<uint64_t, Endian>(FilenamesRef);
966 }
967
968 /// Read the inline coverage mapping. Ignore the buffer parameter, it is for
969 /// out-of-line coverage mapping data only.
970 template <llvm::endianness Endian>
971 StringRef getCoverageMapping(const char *) const {
972 return StringRef(&CoverageMapping, getDataSize<Endian>());
973 }
974
975 // Advance to the next inline coverage mapping and its associated function
976 // record. Ignore the out-of-line coverage mapping buffer.
977 template <llvm::endianness Endian>
978 std::pair<const char *, const CovMapFunctionRecordV3 *>
979 advanceByOne(const char *) const {
980 assert(isAddrAligned(Align(8), this) && "Function record not aligned");
981 const char *Next = ((const char *)this) + sizeof(CovMapFunctionRecordV3) -
982 sizeof(char) + getDataSize<Endian>();
983 // Each function record has an alignment of 8, so we need to adjust
984 // alignment before reading the next record.
985 Next += offsetToAlignedAddr(Next, Align(8));
986 return {nullptr, reinterpret_cast<const CovMapFunctionRecordV3 *>(Next)};
987 }
988};
989
990// Per module coverage mapping data header, i.e. CoverageMapFileHeader
991// documented above.
993#define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
995 template <llvm::endianness Endian> uint32_t getNRecords() const {
996 return support::endian::byte_swap<uint32_t, Endian>(NRecords);
997 }
998
999 template <llvm::endianness Endian> uint32_t getFilenamesSize() const {
1000 return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
1001 }
1002
1003 template <llvm::endianness Endian> uint32_t getCoverageSize() const {
1004 return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
1005 }
1006
1007 template <llvm::endianness Endian> uint32_t getVersion() const {
1008 return support::endian::byte_swap<uint32_t, Endian>(Version);
1009 }
1010};
1011
1013
1016 // Function's name reference from CovMapFuncRecord is changed from raw
1017 // name string pointer to MD5 to support name section compression. Name
1018 // section is also compressed.
1020 // A new interpretation of the columnEnd field is added in order to mark
1021 // regions as gap areas.
1023 // Function records are named, uniqued, and moved to a dedicated section.
1025 // Branch regions referring to two counters are added
1027 // Compilation directory is stored separately and combined with relative
1028 // filenames to produce an absolute file path.
1030 // Branch regions extended and Decision Regions added for MC/DC.
1032 // The current version is Version7.
1033 CurrentVersion = INSTR_PROF_COVMAP_VERSION
1035
1036// Correspond to "llvmcovm", in little-endian.
1037constexpr uint64_t TestingFormatMagic = 0x6d766f636d766c6c;
1038
1040 // The first version's number corresponds to the string "testdata" in
1041 // little-endian. This is for a historical reason.
1042 Version1 = 0x6174616474736574,
1043 // Version1 has a defect that it can't store multiple file records. Version2
1044 // fix this problem by adding a new field before the file records section.
1045 Version2 = 1,
1046 // The current testing format version is Version2.
1048};
1049
1050template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
1053};
1054
1055template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version3, IntPtrT> {
1058};
1059
1060template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version2, IntPtrT> {
1063};
1064
1065template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
1068};
1069
1070} // end namespace coverage
1071
1072/// Provide DenseMapInfo for CounterExpression
1073template<> struct DenseMapInfo<coverage::CounterExpression> {
1075 using namespace coverage;
1076
1077 return CounterExpression(CounterExpression::ExprKind::Subtract,
1078 Counter::getCounter(~0U),
1079 Counter::getCounter(~0U));
1080 }
1081
1083 using namespace coverage;
1084
1085 return CounterExpression(CounterExpression::ExprKind::Add,
1086 Counter::getCounter(~0U),
1087 Counter::getCounter(~0U));
1088 }
1089
1090 static unsigned getHashValue(const coverage::CounterExpression &V) {
1091 return static_cast<unsigned>(
1092 hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
1093 V.RHS.getKind(), V.RHS.getCounterID()));
1094 }
1095
1098 return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
1099 }
1100};
1101
1102} // end namespace llvm
1103
1104#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
basic Basic Alias true
This file declares a library for handling Build IDs and using them to find debug info.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_PACKED_END
Definition: Compiler.h:404
#define LLVM_PACKED_START
Definition: Compiler.h:403
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
std::string Name
bool End
Definition: ELF_riscv.cpp:478
hexagon bit simplify
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Value * RHS
Value * LHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
iterator end() const
Definition: ArrayRef.h:154
Base class for user error types.
Definition: Error.h:352
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
Tagged union holding either a T or a Error.
Definition: Error.h:474
Class representing an expression and its matching format.
Reader for the indexed binary instrprof format.
A symbol table used for function PGO name look-up with keys (such as pointers, md5hash values) to the...
Definition: InstrProf.h:425
StringRef getFuncOrVarName(uint64_t ValMD5Hash)
Return name of functions or global variables from the name's md5 hash value.
Definition: InstrProf.h:573
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize)
Return function's PGO name from the function name's symbol address in the object file.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
A Counter expression builder is used to construct the counter expressions.
ArrayRef< CounterExpression > getExpressions() const
Counter subtract(Counter LHS, Counter RHS, bool Simplify=true)
Return a counter that represents the expression that subtracts RHS from LHS.
Counter add(Counter LHS, Counter RHS, bool Simplify=true)
Return a counter that represents the expression that adds LHS and RHS.
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
CounterMappingContext(ArrayRef< CounterExpression > Expressions, ArrayRef< uint64_t > CounterValues=std::nullopt)
void setCounts(ArrayRef< uint64_t > Counts)
void dump(const Counter &C) const
Expected< int64_t > evaluate(const Counter &C) const
Return the number of times that a region of code associated with this counter was executed.
unsigned getMaxCounterID(const Counter &C) const
void dump(const Counter &C, raw_ostream &OS) const
Coverage information to be processed or displayed.
ArrayRef< ExpansionRecord > getExpansions() const
Expansions that can be further processed.
ArrayRef< CountedRegion > getBranches() const
Branches that can be further processed.
std::vector< CoverageSegment >::const_iterator begin() const
Get an iterator over the coverage segments for this object.
std::vector< CoverageSegment >::const_iterator end() const
StringRef getFilename() const
Get the name of the file this data covers.
CoverageData(StringRef Filename)
std::string message() const override
Return the error message as a string.
CoverageMapError(coveragemap_error Err, const Twine &ErrStr=Twine())
void log(raw_ostream &OS) const override
Print an error message to an output stream.
coveragemap_error get() const
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
const std::string & getMessage() const
The mapping of profile information to coverage data.
unsigned getMismatchedCount() const
The number of functions that couldn't have their profiles mapped.
std::vector< StringRef > getUniqueSourceFiles() const
Returns a lexicographically sorted, unique list of files that are covered.
CoverageData getCoverageForExpansion(const ExpansionRecord &Expansion) const
Get the coverage for an expansion within a coverage set.
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...
iterator_range< FunctionRecordIterator > getCoveredFunctions(StringRef Filename) const
Gets all of the functions in a particular file.
iterator_range< FunctionRecordIterator > getCoveredFunctions() const
Gets all of the functions covered by this profile.
CoverageData getCoverageForFunction(const FunctionRecord &Function) const
Get the coverage for a particular function.
CoverageMapping(const CoverageMapping &)=delete
std::vector< InstantiationGroup > getInstantiationGroups(StringRef Filename) const
Get the list of function instantiation groups in a particular file.
CoverageData getCoverageForFile(StringRef Filename) const
Get the coverage for a particular file.
CoverageMapping & operator=(const CoverageMapping &)=delete
static Expected< std::unique_ptr< CoverageMapping > > load(ArrayRef< std::unique_ptr< CoverageMappingReader > > CoverageReaders, IndexedInstrProfReader &ProfileReader)
Load the coverage mapping using the given readers.
Iterator over Functions, optionally filtered to a single file.
FunctionRecordIterator & operator++()
bool operator==(const FunctionRecordIterator &RHS) const
const FunctionRecord & operator*() const
FunctionRecordIterator(ArrayRef< FunctionRecord > Records_, StringRef Filename="")
An instantiation group contains a FunctionRecord list, such that each record corresponds to a distinc...
InstantiationGroup(const InstantiationGroup &)=delete
unsigned getLine() const
Get the line where the common function was defined.
unsigned getColumn() const
Get the column where the common function was defined.
bool hasName() const
Check if the instantiations in this group have a common mangled name.
size_t size() const
Get the number of instantiations in this group.
ArrayRef< const FunctionRecord * > getInstantiations() const
Get the instantiations in this group.
uint64_t getTotalExecutionCount() const
Get the total execution count of all instantiations in this group.
InstantiationGroup(InstantiationGroup &&)=default
StringRef getName() const
Get the common mangled name for instantiations in this group.
An iterator over the LineCoverageStats objects for lines described by a CoverageData instance.
LineCoverageIterator(const CoverageData &CD)
const LineCoverageStats & operator*() const
bool operator==(const LineCoverageIterator &R) const
LineCoverageIterator getEnd() const
LineCoverageIterator(const CoverageData &CD, unsigned Line)
Coverage statistics for a single line.
const CoverageSegment * getWrappedSegment() const
ArrayRef< const CoverageSegment * > getLineSegments() const
CRTP base class which implements the entire standard iterator facade in terms of a minimal subset of ...
Definition: iterator.h:80
A range adaptor for a pair of iterators.
BuildIDFetcher searches local cache directories for debug info.
Definition: BuildID.h:39
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
The virtual file system interface.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
constexpr size_t NameSize
Definition: XCOFF.h:29
uint64_t getFuncNameRef(const FuncRecordTy *Record)
Return the function lookup key. The value is considered opaque.
StringRef getCoverageMappingOutOfLine(const FuncRecordTy *Record, const char *MappingBuf)
Read coverage mapping out-of-line, from MappingBuf.
uint64_t getDataSize(const FuncRecordTy *Record)
Return the coverage map data size for the function.
Error getFuncNameViaRef(const FuncRecordTy *Record, InstrProfSymtab &ProfileNames, StringRef &FuncName)
Return the PGO name of the function.
std::pair< const char *, const FuncRecordTy * > advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf)
Advance to the next out-of-line coverage mapping and its associated function record.
uint64_t getFuncHash(const FuncRecordTy *Record)
Return the structural hash associated with the function.
const std::error_category & coveragemap_category()
std::error_code make_error_code(coveragemap_error E)
static iterator_range< LineCoverageIterator > getLineCoverageStats(const coverage::CoverageData &CD)
Get a LineCoverageIterator range for the lines described by CD.
constexpr uint64_t TestingFormatMagic
std::pair< unsigned, unsigned > LineColPair
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment)
Returns the necessary adjustment for aligning Addr to Alignment bytes, rounding up.
Definition: Alignment.h:203
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1853
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:613
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
Definition: Alignment.h:150
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
static coverage::CounterExpression getTombstoneKey()
static bool isEqual(const coverage::CounterExpression &LHS, const coverage::CounterExpression &RHS)
static unsigned getHashValue(const coverage::CounterExpression &V)
static coverage::CounterExpression getEmptyKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:50
Associates a source range with an execution count.
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, uint64_t FalseExecutionCount)
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
A Counter expression is a value that represents an arithmetic operation with two counters.
CounterExpression(ExprKind Kind, Counter LHS, Counter RHS)
A Counter mapping region associates a source range with a specific counter.
static CounterMappingRegion makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
static CounterMappingRegion makeBranchRegion(Counter Count, Counter FalseCount, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
CounterMappingRegion(Counter Count, Counter FalseCount, unsigned FileID, unsigned ExpandedFileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
static CounterMappingRegion makeGapRegion(Counter Count, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
CounterMappingRegion(Counter Count, unsigned FileID, unsigned ExpandedFileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
static CounterMappingRegion makeRegion(Counter Count, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
Counter FalseCount
Secondary Counter used for Branch Regions (FalseCount).
static CounterMappingRegion makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
Counter Count
Primary Counter that is also used for Branch Regions (TrueCount).
@ ExpansionRegion
An ExpansionRegion represents a file expansion region that associates a source range with the expansi...
@ SkippedRegion
A SkippedRegion represents a source range with code that was skipped by a preprocessor or similar mea...
@ GapRegion
A GapRegion is like a CodeRegion, but its count is only set as the line execution count when its the ...
@ BranchRegion
A BranchRegion represents leaf-level boolean expressions and is associated with two counters,...
@ CodeRegion
A CodeRegion associates some code with a counter.
A Counter is an abstract value that describes how to compute the execution count for a region of code...
static const unsigned EncodingTagBits
static Counter getZero()
Return the counter that represents the number zero.
static Counter getCounter(unsigned CounterId)
Return the counter that corresponds to a specific profile counter.
friend bool operator==(const Counter &LHS, const Counter &RHS)
unsigned getCounterID() const
CounterKind
The CounterExpression kind (Add or Subtract) is encoded in bit 0 next to the CounterKind.
unsigned getExpressionID() const
static const unsigned EncodingCounterTagAndExpansionRegionTagBits
CounterKind getKind() const
friend bool operator!=(const Counter &LHS, const Counter &RHS)
friend bool operator<(const Counter &LHS, const Counter &RHS)
static const unsigned EncodingTagMask
static Counter getExpression(unsigned ExpressionId)
Return the counter that corresponds to a specific addition counter expression.
std::pair< const char *, const ThisT * > advanceByOne(const char *MappingBuf) const
StringRef getCoverageMapping(const char *MappingBuf) const
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const
Return the PGO name of the function.
IntPtrT getFuncNameRef() const
Return function lookup key. The value is consider opaque.
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const
std::pair< const char *, const ThisT * > advanceByOne(const char *MappingBuf) const
StringRef getCoverageMapping(const char *MappingBuf) const
std::pair< const char *, const CovMapFunctionRecordV3 * > advanceByOne(const char *) const
StringRef getCoverageMapping(const char *) const
Read the inline coverage mapping.
uint64_t getFilenamesRef() const
Get the filename set reference.
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const
uint32_t getFilenamesSize() const
Coverage mapping information for a single function.
The execution count information starting at a point in a file.
CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
bool HasCount
When false, the segment was uninstrumented or skipped.
unsigned Col
The column where this segment begins.
friend bool operator==(const CoverageSegment &L, const CoverageSegment &R)
bool IsRegionEntry
Whether this enters a new region or returns to a previous count.
uint64_t Count
The execution count, or zero if no count was recorded.
unsigned Line
The line where this segment begins.
CoverageSegment(unsigned Line, unsigned Col, uint64_t Count, bool IsRegionEntry, bool IsGapRegion=false, bool IsBranchRegion=false)
bool IsGapRegion
Whether this enters a gap region.
Coverage information for a macro expansion or #included file.
const CountedRegion & Region
The region that expands to this record.
unsigned FileID
The abstract file this expansion covers.
ExpansionRecord(const CountedRegion &Region, const FunctionRecord &Function)
const FunctionRecord & Function
Coverage for the expansion.
Code coverage information for a single function.
std::vector< CountedRegion > CountedBranchRegions
Branch Regions in the function along with their counts.
std::string Name
Raw function name.
std::vector< CountedRegion > CountedRegions
Regions in the function along with their counts.
FunctionRecord & operator=(FunctionRecord &&)=default
std::vector< std::string > Filenames
Mapping from FileID (i.e.
FunctionRecord(FunctionRecord &&FR)=default
FunctionRecord(StringRef Name, ArrayRef< StringRef > Filenames)
uint64_t ExecutionCount
The number of times this function was executed.
void pushRegion(CounterMappingRegion Region, uint64_t Count, uint64_t FalseCount)