LLVM 23.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/BitVector.h"
19#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/DenseSet.h"
21#include "llvm/ADT/Hashing.h"
22#include "llvm/ADT/StringRef.h"
23#include "llvm/ADT/iterator.h"
25#include "llvm/Object/BuildID.h"
30#include "llvm/Support/Debug.h"
31#include "llvm/Support/Endian.h"
32#include "llvm/Support/Error.h"
34#include <algorithm>
35#include <cassert>
36#include <cstdint>
37#include <iterator>
38#include <map>
39#include <memory>
40#include <optional>
41#include <sstream>
42#include <string>
43#include <system_error>
44#include <utility>
45#include <vector>
46
47namespace llvm {
48
50
51namespace object {
52class BuildIDFetcher;
53} // namespace object
54
55namespace vfs {
56class FileSystem;
57} // namespace vfs
58
59namespace coverage {
60
63
74
75LLVM_ABI const std::error_category &coveragemap_category();
76
77inline std::error_code make_error_code(coveragemap_error E) {
78 return std::error_code(static_cast<int>(E), coveragemap_category());
80
81class LLVM_ABI CoverageMapError : public ErrorInfo<CoverageMapError> {
82public:
84 : Err(Err), Msg(ErrStr.str()) {
85 assert(Err != coveragemap_error::success && "Not an error");
86 }
88 std::string message() const override;
90 void log(raw_ostream &OS) const override { OS << message(); }
92 std::error_code convertToErrorCode() const override {
93 return make_error_code(Err);
94 }
96 coveragemap_error get() const { return Err; }
97 const std::string &getMessage() const { return Msg; }
98
99 static char ID;
100
101private:
103 std::string Msg;
104};
105
106/// A Counter is an abstract value that describes how to compute the
107/// execution count for a region of code using the collected profile count data.
108struct Counter {
109 /// The CounterExpression kind (Add or Subtract) is encoded in bit 0 next to
110 /// the CounterKind. This means CounterKind has to leave bit 0 free.
112 static const unsigned EncodingTagBits = 2;
113 static const unsigned EncodingTagMask = 0x3;
115 EncodingTagBits + 1;
116
117private:
118 CounterKind Kind = Zero;
119 unsigned ID = 0;
120
121 Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
122
123public:
124 Counter() = default;
125
126 CounterKind getKind() const { return Kind; }
127
128 bool isZero() const { return Kind == Zero; }
129
130 bool isExpression() const { return Kind == Expression; }
131
132 unsigned getCounterID() const { return ID; }
133
134 unsigned getExpressionID() const { return ID; }
135
136 friend bool operator==(const Counter &LHS, const Counter &RHS) {
137 return LHS.Kind == RHS.Kind && LHS.ID == RHS.ID;
140 friend bool operator!=(const Counter &LHS, const Counter &RHS) {
141 return !(LHS == RHS);
143
144 friend bool operator<(const Counter &LHS, const Counter &RHS) {
145 return std::tie(LHS.Kind, LHS.ID) < std::tie(RHS.Kind, RHS.ID);
146 }
147
148 /// Return the counter that represents the number zero.
149 static Counter getZero() { return Counter(); }
150
151 /// Return the counter that corresponds to a specific profile counter.
152 static Counter getCounter(unsigned CounterId) {
153 return Counter(CounterValueReference, CounterId);
156 /// Return the counter that corresponds to a specific addition counter
157 /// expression.
158 static Counter getExpression(unsigned ExpressionId) {
159 return Counter(Expression, ExpressionId);
163/// A Counter expression is a value that represents an arithmetic operation
164/// with two counters.
167 ExprKind Kind;
174/// A Counter expression builder is used to construct the counter expressions.
175/// It avoids unnecessary duplication and simplifies algebraic expressions.
177 /// A list of all the counter expressions
178 std::vector<CounterExpression> Expressions;
179
180 /// A lookup table for the index of a given expression.
182
183 /// Return the counter which corresponds to the given expression.
184 ///
185 /// If the given expression is already stored in the builder, a counter
186 /// that references that expression is returned. Otherwise, the given
187 /// expression is added to the builder's collection of expressions.
188 Counter get(const CounterExpression &E);
189
190 /// Represents a term in a counter expression tree.
191 struct Term {
192 unsigned CounterID;
193 int Factor;
194
195 Term(unsigned CounterID, int Factor)
196 : CounterID(CounterID), Factor(Factor) {}
197 };
199 /// Gather the terms of the expression tree for processing.
200 ///
201 /// This collects each addition and subtraction referenced by the counter into
202 /// a sequence that can be sorted and combined to build a simplified counter
203 /// expression.
204 void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms);
205
206 /// Simplifies the given expression tree
207 /// by getting rid of algebraically redundant operations.
208 Counter simplify(Counter ExpressionTree);
209
210public:
211 ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
212
213 /// Return a counter that represents the expression that adds LHS and RHS.
214 LLVM_ABI Counter add(Counter LHS, Counter RHS, bool Simplify = true);
215
216 /// Return a counter that represents the expression that subtracts RHS from
217 /// LHS.
218 LLVM_ABI Counter subtract(Counter LHS, Counter RHS, bool Simplify = true);
220 /// K to V map. K will be Counter in most cases. V may be Counter or
221 /// Expression.
222 using SubstMap = std::map<Counter, Counter>;
223
224 /// \return A counter equivalent to \C, with each term in its
225 /// expression replaced with term from \p Map.
226 LLVM_ABI Counter subst(Counter C, const SubstMap &Map);
227};
228
229using LineColPair = std::pair<unsigned, unsigned>;
230
231/// A Counter mapping region associates a source range with a specific counter.
234 /// A CodeRegion associates some code with a counter
236
237 /// An ExpansionRegion represents a file expansion region that associates
238 /// a source range with the expansion of a virtual source file, such as
239 /// for a macro instantiation or #include file.
241
242 /// A SkippedRegion represents a source range with code that was skipped
243 /// by a preprocessor or similar means.
245
246 /// A GapRegion is like a CodeRegion, but its count is only set as the
247 /// line execution count when its the only region in the line.
249
250 /// A BranchRegion represents leaf-level boolean expressions and is
251 /// associated with two counters, each representing the number of times the
252 /// expression evaluates to true or false.
254
255 /// A DecisionRegion represents a top-level boolean expression and is
256 /// associated with a variable length bitmap index and condition number.
258
259 /// A Branch Region can be extended to include IDs to facilitate MC/DC.
261 };
262
263 /// Primary Counter that is also used for Branch Regions (TrueCount).
265
266 /// Secondary Counter used for Branch Regions (FalseCount).
268
269 /// Parameters used for Modified Condition/Decision Coverage
271
275
279
280 unsigned FileID = 0;
281 unsigned ExpandedFileID = 0;
283
285
286 bool isBranch() const {
287 return (Kind == BranchRegion || Kind == MCDCBranchRegion);
289
308 unsigned FileID, unsigned LineStart,
309 unsigned ColumnStart, unsigned LineEnd,
310 unsigned ColumnEnd, RegionKind Kind)
313 Kind(Kind) {}
314
317 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
320 }
321
331 makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart,
332 unsigned LineEnd, unsigned ColumnEnd) {
336
339 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
341 LineEnd, (1U << 31) | ColumnEnd, GapRegion);
342 }
343
346 unsigned LineStart, unsigned ColumnStart, unsigned LineEnd,
347 unsigned ColumnEnd,
348 const mcdc::Parameters &MCDCParams = std::monostate()) {
351 ColumnEnd,
352 (std::get_if<mcdc::BranchParameters>(&MCDCParams) ? MCDCBranchRegion
353 : BranchRegion),
354 MCDCParams);
355 }
356
364
365 inline LineColPair startLoc() const {
367 }
368
369 inline LineColPair endLoc() const { return LineColPair(LineEnd, ColumnEnd); }
370};
371
372/// Associates a source range with an execution count.
389
390/// MCDC Record grouping all information together.
392 /// CondState represents the evaluation of a condition in an executed test
393 /// vector, which can be True or False. A DontCare is used to mask an
394 /// unevaluatable condition resulting from short-circuit behavior of logical
395 /// operators in languages like C/C++. When comparing the evaluation of a
396 /// condition across executed test vectors, comparisons against a DontCare
397 /// are effectively ignored.
399
400 /// Emulate SmallVector<CondState> with a pair of BitVector.
401 ///
402 /// True False DontCare (Impossible)
403 /// Values: True False False True
404 /// Visited: True True False False
406 BitVector Values; /// True/False (False when DontCare)
407 BitVector Visited; /// ~DontCare
408
409 public:
410 /// Default values are filled with DontCare.
411 TestVector(unsigned N) : Values(N), Visited(N) {}
412
413 /// Emulate RHS SmallVector::operator[]
414 CondState operator[](int I) const {
415 return (Visited[I] ? (Values[I] ? MCDC_True : MCDC_False)
416 : MCDC_DontCare);
417 }
418
419 /// Equivalent to buildTestVector's Index.
420 auto getIndex() const { return Values.getData()[0]; }
421
422 /// Set the condition \p Val at position \p I.
423 /// This emulates LHS SmallVector::operator[].
424 void set(int I, CondState Val) {
425 Visited[I] = (Val != MCDC_DontCare);
426 Values[I] = (Val == MCDC_True);
427 }
428
429 /// Emulate SmallVector::push_back.
431 Visited.push_back(Val != MCDC_DontCare);
432 Values.push_back(Val == MCDC_True);
433 assert(Values.size() == Visited.size());
434 }
435
436 /// For each element:
437 /// - False if either is DontCare
438 /// - False if both have the same value
439 /// - True if both have the opposite value
440 /// ((A.Values ^ B.Values) & A.Visited & B.Visited)
441 /// Dedicated to findIndependencePairs().
442 auto getDifferences(const TestVector &B) const {
443 const auto &A = *this;
444 BitVector AB = A.Values;
445 AB ^= B.Values;
446 AB &= A.Visited;
447 AB &= B.Visited;
448 return AB;
449 }
450 };
451
453 using BoolVector = std::array<BitVector, 2>;
454 using TVRowPair = std::pair<unsigned, unsigned>;
458
459private:
461 TestVectors TV;
462 TestVectors NotExecutedTV;
463 std::optional<TVPairMap> IndependencePairs;
464 BoolVector Folded;
465 CondIDMap PosToID;
466 LineColPairMap CondLoc;
467
468 std::string formatTestVectorRow(const TestVector &Vec, CondState Result,
469 unsigned DisplayRowNumber) const {
470 std::ostringstream OS;
471 const auto NumConditions = getNumConditions();
472 // Add individual condition values to the string.
473 OS << " " << DisplayRowNumber << " { ";
474 for (unsigned Condition = 0; Condition < NumConditions; Condition++) {
475 if (isCondFolded(Condition))
476 OS << "C";
477 else {
478 auto It = PosToID.find(Condition);
479 assert(It != PosToID.end() && "Ordinal without CondID mapping");
480 switch (Vec[It->second]) {
481 case MCDC_DontCare:
482 OS << "-";
483 break;
484 case MCDC_True:
485 OS << "T";
486 break;
487 case MCDC_False:
488 OS << "F";
489 break;
490 }
491 }
492 if (Condition != NumConditions - 1)
493 OS << ", ";
494 }
495
496 // Add result value to the string.
497 OS << " = ";
498 if (Result == MCDC_True)
499 OS << "T";
500 else
501 OS << "F";
502 OS << " }\n";
503 return OS.str();
504 }
505
506public:
508 TestVectors &&NotExecutedTV, BoolVector &&Folded,
509 CondIDMap &&PosToID, LineColPairMap &&CondLoc)
510 : Region(Region), TV(std::move(TV)),
511 NotExecutedTV(std::move(NotExecutedTV)), Folded(std::move(Folded)),
512 PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) {
514 }
515
516 // Compare executed test vectors against each other to find an independence
517 // pairs for each condition. This processing takes the most time.
519
520 const CounterMappingRegion &getDecisionRegion() const { return Region; }
521 unsigned getNumConditions() const {
522 return Region.getDecisionParams().NumConditions;
523 }
524 unsigned getNumTestVectors() const { return TV.size(); }
525 unsigned getNumNotExecutedTestVectors() const { return NotExecutedTV.size(); }
526
527 bool isCondFolded(unsigned Condition) const {
528 return Folded[false][Condition] || Folded[true][Condition];
529 }
530
531 /// Return the evaluation of a condition (indicated by Condition) in an
532 /// executed test vector (indicated by TestVectorIndex), which will be True,
533 /// False, or DontCare if the condition is unevaluatable. Because condition
534 /// IDs are not associated based on their position in the expression,
535 /// accessing conditions in the TestVectors requires a translation from a
536 /// ordinal position to actual condition ID. This is done via PosToID[].
537 CondState getTVCondition(unsigned TestVectorIndex, unsigned Condition) {
538 return TV[TestVectorIndex].first[PosToID[Condition]];
539 }
540
541 CondState getNotExecutedTVCondition(unsigned NotExecutedIndex,
542 unsigned Condition) {
543 return NotExecutedTV[NotExecutedIndex].first[PosToID[Condition]];
544 }
545
546 /// Return the number of True and False decisions for all executed test
547 /// vectors.
548 std::pair<unsigned, unsigned> getDecisions() const {
549 const unsigned TrueDecisions =
551
552 return {TrueDecisions, TV.size() - TrueDecisions};
553 }
554
555 /// Return the Result evaluation for an executed test vector.
556 /// See MCDCRecordProcessor::RecordTestVector().
557 CondState getTVResult(unsigned TestVectorIndex) {
558 return TV[TestVectorIndex].second;
559 }
560
561 CondState getNotExecutedTVResult(unsigned NotExecutedIndex) {
562 return NotExecutedTV[NotExecutedIndex].second;
563 }
564
565 /// Determine whether a given condition (indicated by Condition) is covered
566 /// by an Independence Pair. Because condition IDs are not associated based
567 /// on their position in the expression, accessing conditions in the
568 /// TestVectors requires a translation from a ordinal position to actual
569 /// condition ID. This is done via PosToID[].
570 bool isConditionIndependencePairCovered(unsigned Condition) const {
571 assert(IndependencePairs);
572 auto It = PosToID.find(Condition);
573 assert(It != PosToID.end() && "Condition ID without an Ordinal mapping");
574 return IndependencePairs->contains(It->second);
575 }
576
577 /// Return the Independence Pair that covers the given condition. Because
578 /// condition IDs are not associated based on their position in the
579 /// expression, accessing conditions in the TestVectors requires a
580 /// translation from a ordinal position to actual condition ID. This is done
581 /// via PosToID[].
584 assert(IndependencePairs);
585 return (*IndependencePairs)[PosToID[Condition]];
586 }
587
588 float getPercentCovered() const {
589 unsigned Folded = 0;
590 unsigned Covered = 0;
591 for (unsigned C = 0; C < getNumConditions(); C++) {
592 if (isCondFolded(C))
593 Folded++;
595 Covered++;
596 }
597
598 unsigned Total = getNumConditions() - Folded;
599 if (Total == 0)
600 return 0.0;
601 return (static_cast<double>(Covered) / static_cast<double>(Total)) * 100.0;
602 }
603
604 std::string getConditionHeaderString(unsigned Condition) {
605 std::ostringstream OS;
606 const auto &[Line, Col] = CondLoc[Condition];
607 OS << "Condition C" << Condition + 1 << " --> (" << Line << ":" << Col
608 << ")\n";
609 return OS.str();
610 }
611
612 std::string getTestVectorHeaderString() const {
613 std::ostringstream OS;
614 if (getNumTestVectors() == 0 && getNumNotExecutedTestVectors() == 0) {
615 OS << "None.\n";
616 return OS.str();
617 }
618 const auto NumConditions = getNumConditions();
619 for (unsigned I = 0; I < NumConditions; I++) {
620 OS << "C" << I + 1;
621 if (I != NumConditions - 1)
622 OS << ", ";
623 }
624 OS << " Result\n";
625 return OS.str();
626 }
627
628 std::string getTestVectorString(unsigned TestVectorIndex) {
629 assert(TestVectorIndex < getNumTestVectors() &&
630 "TestVector index out of bounds!");
631 const auto &[Vec, Res] = TV[TestVectorIndex];
632 return formatTestVectorRow(Vec, Res, TestVectorIndex + 1);
633 }
634
635 std::string getNotExecutedTestVectorString(unsigned NotExecutedIndex) {
636 assert(NotExecutedIndex < getNumNotExecutedTestVectors() &&
637 "Not-executed test vector index out of bounds!");
638 const auto &[Vec, Res] = NotExecutedTV[NotExecutedIndex];
639 return formatTestVectorRow(Vec, Res,
640 getNumTestVectors() + NotExecutedIndex + 1);
641 }
642
643 std::string getConditionCoverageString(unsigned Condition) {
644 assert(Condition < getNumConditions() &&
645 "Condition index is out of bounds!");
646 std::ostringstream OS;
647
648 OS << " C" << Condition + 1 << "-Pair: ";
649 if (isCondFolded(Condition)) {
650 OS << "constant folded\n";
651 } else if (isConditionIndependencePairCovered(Condition)) {
652 TVRowPair rows = getConditionIndependencePair(Condition);
653 OS << "covered: (" << rows.first << ",";
654 OS << rows.second << ")\n";
655 } else
656 OS << "not covered\n";
657
658 return OS.str();
659 }
660};
661
662namespace mcdc {
663/// Compute TestVector Indices "TVIdx" from the Conds graph.
664///
665/// Clang CodeGen handles the bitmap index based on TVIdx.
666/// llvm-cov reconstructs conditions from TVIdx.
667///
668/// For each leaf "The final decision",
669/// - TVIdx should be unique.
670/// - TVIdx has the Width.
671/// - The width represents the number of possible paths.
672/// - The minimum width is 1 "deterministic".
673/// - The order of leaves are sorted by Width DESC. It expects
674/// latter TVIdx(s) (with Width=1) could be pruned and altered to
675/// other simple branch conditions.
676///
678public:
679 struct MCDCNode {
680 int InCount = 0; /// Reference count; temporary use
681 int Width; /// Number of accumulated paths (>= 1)
683 };
684
685#ifndef NDEBUG
686 /// This is no longer needed after the assignment.
687 /// It may be used in assert() for reconfirmation.
689#endif
690
691 /// Output: Index for TestVectors bitmap (These are not CondIDs)
693
694 /// Output: The number of test vectors.
695 /// Error with HardMaxTVs if the number has exploded.
697
698 /// Hard limit of test vectors
699 static constexpr auto HardMaxTVs =
700 std::numeric_limits<decltype(NumTestVectors)>::max();
701
702public:
703 /// Calculate and assign Indices
704 /// \param NextIDs The list of {FalseID, TrueID} indexed by ID
705 /// The first element [0] should be the root node.
706 /// \param Offset Offset of index to final decisions.
708 int Offset = 0);
709};
710} // namespace mcdc
711
712/// A Counter mapping context is used to connect the counters, expressions
713/// and the obtained counter values.
715 ArrayRef<CounterExpression> Expressions;
716 ArrayRef<uint64_t> CounterValues;
717 BitVector Bitmap;
718
719public:
721 ArrayRef<uint64_t> CounterValues = {})
722 : Expressions(Expressions), CounterValues(CounterValues) {}
723
724 void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
725 void setBitmap(BitVector &&Bitmap_) { Bitmap = std::move(Bitmap_); }
726
727 LLVM_ABI void dump(const Counter &C, raw_ostream &OS) const;
728 void dump(const Counter &C) const { dump(C, dbgs()); }
729
730 /// Return the number of times that a region of code associated with this
731 /// counter was executed.
733
734 /// Return an MCDC record that indicates executed test vectors and condition
735 /// pairs.
739 bool IsVersion11);
740
741 LLVM_ABI unsigned getMaxCounterID(const Counter &C) const;
742};
743
744/// Code coverage information for a single function.
746 /// Raw function name.
747 std::string Name;
748 /// Mapping from FileID (i.e. vector index) to filename. Used to support
749 /// macro expansions within a function in which the macro and function are
750 /// defined in separate files.
751 ///
752 /// TODO: Uniquing filenames across all function records may be a performance
753 /// optimization.
754 std::vector<std::string> Filenames;
755 /// Regions in the function along with their counts.
756 std::vector<CountedRegion> CountedRegions;
757 /// Branch Regions in the function along with their counts.
758 std::vector<CountedRegion> CountedBranchRegions;
759 /// MCDC Records record a DecisionRegion and associated BranchRegions.
760 std::vector<MCDCRecord> MCDCRecords;
761 /// The number of times this function was executed.
763
766
769
771 MCDCRecords.push_back(std::move(Record));
772 }
773
775 uint64_t FalseCount) {
776 if (Region.isBranch()) {
777 CountedBranchRegions.emplace_back(Region, Count, FalseCount);
778 // If either counter is hard-coded to zero, then this region represents a
779 // constant-folded branch.
780 CountedBranchRegions.back().TrueFolded = Region.Count.isZero();
781 CountedBranchRegions.back().FalseFolded = Region.FalseCount.isZero();
782 return;
783 }
784 if (CountedRegions.empty())
786 CountedRegions.emplace_back(Region, Count, FalseCount);
787 }
788};
789
790/// Iterator over Functions, optionally filtered to a single file.
791/// When filtering to a single file, the iterator requires a list of potential
792/// indices where to find the desired records to avoid quadratic behavior when
793/// repeatedly iterating over functions from different files.
795 : public iterator_facade_base<FunctionRecordIterator,
796 std::forward_iterator_tag, FunctionRecord> {
798 ArrayRef<unsigned> RecordIndices;
799 ArrayRef<unsigned>::iterator CurrentIndex;
801 StringRef Filename;
802
803 /// Skip records whose primary file is not \c Filename.
804 LLVM_ABI void skipOtherFiles();
805
806public:
808 StringRef Filename = "",
809 ArrayRef<unsigned> RecordIndices_ = {})
810 : Records(Records_), RecordIndices(RecordIndices_),
811 CurrentIndex(RecordIndices.begin()),
812 // If `RecordIndices` is provided, we can skip directly to the first
813 // index it provides.
814 Current(CurrentIndex == RecordIndices.end() ? Records.begin()
815 : &Records[*CurrentIndex]),
817 assert(Filename.empty() == RecordIndices_.empty() &&
818 "If `Filename` is specified, `RecordIndices` must also be provided");
819 skipOtherFiles();
820 }
821
822 FunctionRecordIterator() : Current(Records.begin()) {}
823
825 return Current == RHS.Current && Filename == RHS.Filename;
826 }
827
828 const FunctionRecord &operator*() const { return *Current; }
829
831 advanceOne();
832 skipOtherFiles();
833 return *this;
834 }
835
836private:
837 void advanceOne() {
838 if (RecordIndices.empty()) {
839 // Iteration over all entries, advance in the list of records.
840 assert(Current != Records.end() && "incremented past end");
841 ++Current;
842 } else {
843 // Iterator over entries filtered by file name. Advance in the list of
844 // indices, and adjust the cursor in the list of records accordingly.
845 assert(CurrentIndex != RecordIndices.end() && "incremented past end");
846 ++CurrentIndex;
847 if (CurrentIndex == RecordIndices.end()) {
848 Current = Records.end();
849 } else {
850 Current = &Records[*CurrentIndex];
851 }
852 }
853 }
854};
855
856/// Coverage information for a macro expansion or #included file.
857///
858/// When covered code has pieces that can be expanded for more detail, such as a
859/// preprocessor macro use and its definition, these are represented as
860/// expansions whose coverage can be looked up independently.
862 /// The abstract file this expansion covers.
863 unsigned FileID;
864 /// The region that expands to this record.
866 /// Coverage for the expansion.
868
872};
873
874/// The execution count information starting at a point in a file.
875///
876/// A sequence of CoverageSegments gives execution counts for a file in format
877/// that's simple to iterate through for processing.
879 /// The line where this segment begins.
880 unsigned Line;
881 /// The column where this segment begins.
882 unsigned Col;
883 /// The execution count, or zero if no count was recorded.
885 /// When false, the segment was uninstrumented or skipped.
887 /// Whether this enters a new region or returns to a previous count.
889 /// Whether this enters a gap region.
891
895
896 CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
897 bool IsRegionEntry, bool IsGapRegion = false,
898 bool IsBranchRegion = false)
901
902 friend bool operator==(const CoverageSegment &L, const CoverageSegment &R) {
903 return std::tie(L.Line, L.Col, L.Count, L.HasCount, L.IsRegionEntry,
904 L.IsGapRegion) == std::tie(R.Line, R.Col, R.Count,
905 R.HasCount, R.IsRegionEntry,
906 R.IsGapRegion);
907 }
908};
909
910/// An instantiation group contains a \c FunctionRecord list, such that each
911/// record corresponds to a distinct instantiation of the same function.
912///
913/// Note that it's possible for a function to have more than one instantiation
914/// (consider C++ template specializations or static inline functions).
915class InstantiationGroup {
916 friend class CoverageMapping;
917
918 unsigned Line;
919 unsigned Col;
920 std::vector<const FunctionRecord *> Instantiations;
921
922 InstantiationGroup(unsigned Line, unsigned Col,
923 std::vector<const FunctionRecord *> Instantiations)
924 : Line(Line), Col(Col), Instantiations(std::move(Instantiations)) {}
925
926public:
927 InstantiationGroup(const InstantiationGroup &) = delete;
928 InstantiationGroup(InstantiationGroup &&) = default;
929
930 /// Get the number of instantiations in this group.
931 size_t size() const { return Instantiations.size(); }
932
933 /// Get the line where the common function was defined.
934 unsigned getLine() const { return Line; }
935
936 /// Get the column where the common function was defined.
937 unsigned getColumn() const { return Col; }
938
939 /// Check if the instantiations in this group have a common mangled name.
940 bool hasName() const {
941 for (unsigned I = 1, E = Instantiations.size(); I < E; ++I)
942 if (Instantiations[I]->Name != Instantiations[0]->Name)
943 return false;
944 return true;
945 }
946
947 /// Get the common mangled name for instantiations in this group.
949 assert(hasName() && "Instantiations don't have a shared name");
950 return Instantiations[0]->Name;
951 }
952
953 /// Get the total execution count of all instantiations in this group.
955 uint64_t Count = 0;
956 for (const FunctionRecord *F : Instantiations)
957 Count += F->ExecutionCount;
958 return Count;
959 }
960
961 /// Get the instantiations in this group.
963 return Instantiations;
964 }
965};
966
967/// Coverage information to be processed or displayed.
968///
969/// This represents the coverage of an entire file, expansion, or function. It
970/// provides a sequence of CoverageSegments to iterate through, as well as the
971/// list of expansions that can be further processed.
973 friend class CoverageMapping;
974
975protected:
976 std::string Filename;
977 std::vector<CoverageSegment> Segments;
978 std::vector<ExpansionRecord> Expansions;
979 std::vector<CountedRegion> BranchRegions;
980 std::vector<MCDCRecord> MCDCRecords;
981
982 bool SingleByteCoverage = false;
983
984public:
985 CoverageData() = default;
986
989
991
992 /// Get the name of the file this data covers.
993 StringRef getFilename() const { return Filename; }
994
996
997 /// Get an iterator over the coverage segments for this object. The segments
998 /// are guaranteed to be uniqued and sorted by location.
999 std::vector<CoverageSegment>::const_iterator begin() const {
1000 return Segments.begin();
1001 }
1002
1003 std::vector<CoverageSegment>::const_iterator end() const {
1004 return Segments.end();
1005 }
1006
1007 bool empty() const { return Segments.empty(); }
1008
1009 /// Expansions that can be further processed.
1011
1012 /// Branches that can be further processed.
1014
1015 /// MCDC Records that can be further processed.
1017};
1018
1019/// The mapping of profile information to coverage data.
1020///
1021/// This is the main interface to get coverage information, using a profile to
1022/// fill out execution counts.
1023class CoverageMapping {
1024 DenseMap<size_t, DenseSet<size_t>> RecordProvenance;
1025 std::vector<FunctionRecord> Functions;
1026 DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices;
1027 std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
1028
1029 std::optional<bool> SingleByteCoverage;
1030
1031 CoverageMapping() = default;
1032
1033 // Load coverage records from readers.
1034 static Error loadFromReaders(
1035 ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
1036 std::optional<std::reference_wrapper<IndexedInstrProfReader>>
1037 &ProfileReader,
1038 CoverageMapping &Coverage);
1039
1040 // Load coverage records from file.
1041 static Error
1042 loadFromFile(StringRef Filename, StringRef Arch, StringRef CompilationDir,
1043 std::optional<std::reference_wrapper<IndexedInstrProfReader>>
1044 &ProfileReader,
1045 CoverageMapping &Coverage, bool &DataFound,
1046 SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr);
1048 /// Add a function record corresponding to \p Record.
1049 Error loadFunctionRecord(
1051 const std::optional<std::reference_wrapper<IndexedInstrProfReader>>
1052 &ProfileReader);
1053
1054 /// Look up the indices for function records which are at least partially
1055 /// defined in the specified file. This is guaranteed to return a superset of
1056 /// such records: extra records not in the file may be included if there is
1057 /// a hash collision on the filename. Clients must be robust to collisions.
1059 getImpreciseRecordIndicesForFilename(StringRef Filename) const;
1060
1061public:
1062 CoverageMapping(const CoverageMapping &) = delete;
1064
1065 /// Load the coverage mapping using the given readers.
1067 load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
1068 std::optional<std::reference_wrapper<IndexedInstrProfReader>>
1069 &ProfileReader);
1071 /// Load the coverage mapping from the given object files and profile. If
1072 /// \p Arches is non-empty, it must specify an architecture for each object.
1073 /// Ignores non-instrumented object files unless all are not instrumented.
1075 load(ArrayRef<StringRef> ObjectFilenames,
1076 std::optional<StringRef> ProfileFilename, vfs::FileSystem &FS,
1077 ArrayRef<StringRef> Arches = {}, StringRef CompilationDir = "",
1078 const object::BuildIDFetcher *BIDFetcher = nullptr,
1079 bool CheckBinaryIDs = false);
1080
1081 /// The number of functions that couldn't have their profiles mapped.
1082 ///
1083 /// This is a count of functions whose profile is out of date or otherwise
1084 /// can't be associated with any coverage information.
1085 unsigned getMismatchedCount() const { return FuncHashMismatches.size(); }
1086
1087 /// A hash mismatch occurs when a profile record for a symbol does not have
1088 /// the same hash as a coverage mapping record for the same symbol. This
1089 /// returns a list of hash mismatches, where each mismatch is a pair of the
1090 /// symbol name and its coverage mapping hash.
1092 return FuncHashMismatches;
1093 }
1094
1095 /// Returns a lexicographically sorted, unique list of files that are
1096 /// covered.
1097 LLVM_ABI std::vector<StringRef> getUniqueSourceFiles() const;
1098
1099 /// Get the coverage for a particular file.
1100 ///
1101 /// The given filename must be the name as recorded in the coverage
1102 /// information. That is, only names returned from getUniqueSourceFiles will
1103 /// yield a result.
1105
1106 /// Get the coverage for a particular function.
1109
1110 /// Get the coverage for an expansion within a coverage set.
1113
1114 /// Gets all of the functions covered by this profile.
1119
1120 /// Gets all of the functions in a particular file.
1123 return make_range(
1125 getImpreciseRecordIndicesForFilename(Filename)),
1127 }
1128
1129 /// Get the list of function instantiation groups in a particular file.
1130 ///
1131 /// Every instantiation group in a program is attributed to exactly one file:
1132 /// the file in which the definition for the common function begins.
1133 LLVM_ABI std::vector<InstantiationGroup>
1135};
1136
1137/// Coverage statistics for a single line.
1138class LineCoverageStats {
1139 uint64_t ExecutionCount;
1140 bool HasMultipleRegions;
1141 bool Mapped;
1142 unsigned Line;
1144 const CoverageSegment *WrappedSegment;
1145
1147 LineCoverageStats() = default;
1148
1149public:
1150 LLVM_ABI LineCoverageStats(ArrayRef<const CoverageSegment *> LineSegments,
1151 const CoverageSegment *WrappedSegment,
1152 unsigned Line);
1153
1154 uint64_t getExecutionCount() const { return ExecutionCount; }
1155
1156 bool hasMultipleRegions() const { return HasMultipleRegions; }
1157
1158 bool isMapped() const { return Mapped; }
1159
1160 unsigned getLine() const { return Line; }
1161
1163 return LineSegments;
1164 }
1165
1166 const CoverageSegment *getWrappedSegment() const { return WrappedSegment; }
1167};
1168
1169/// An iterator over the \c LineCoverageStats objects for lines described by
1170/// a \c CoverageData instance.
1172 : public iterator_facade_base<LineCoverageIterator,
1173 std::forward_iterator_tag,
1174 const LineCoverageStats> {
1175public:
1177 : LineCoverageIterator(CD, CD.begin()->Line) {}
1178
1179 LineCoverageIterator(const CoverageData &CD, unsigned Line)
1180 : CD(CD), WrappedSegment(nullptr), Next(CD.begin()), Ended(false),
1181 Line(Line) {
1182 this->operator++();
1183 }
1184
1185 bool operator==(const LineCoverageIterator &R) const {
1186 return &CD == &R.CD && Next == R.Next && Ended == R.Ended;
1187 }
1188
1189 const LineCoverageStats &operator*() const { return Stats; }
1190
1192
1194 auto EndIt = *this;
1195 EndIt.Next = CD.end();
1196 EndIt.Ended = true;
1197 return EndIt;
1198 }
1199
1200private:
1201 const CoverageData &CD;
1202 const CoverageSegment *WrappedSegment;
1203 std::vector<CoverageSegment>::const_iterator Next;
1204 bool Ended;
1205 unsigned Line;
1208};
1209
1210/// Get a \c LineCoverageIterator range for the lines described by \p CD.
1213 auto Begin = LineCoverageIterator(CD);
1214 auto End = Begin.getEnd();
1215 return make_range(Begin, End);
1216}
1217
1218// Coverage mappping data (V2) has the following layout:
1219// IPSK_covmap:
1220// [CoverageMapFileHeader]
1221// [ArrayStart]
1222// [CovMapFunctionRecordV2]
1223// [CovMapFunctionRecordV2]
1224// ...
1225// [ArrayEnd]
1226// [Encoded Filenames and Region Mapping Data]
1227//
1228// Coverage mappping data (V3) has the following layout:
1229// IPSK_covmap:
1230// [CoverageMapFileHeader]
1231// [Encoded Filenames]
1232// IPSK_covfun:
1233// [ArrayStart]
1234// odr_name_1: [CovMapFunctionRecordV3]
1235// odr_name_2: [CovMapFunctionRecordV3]
1236// ...
1237// [ArrayEnd]
1238//
1239// Both versions of the coverage mapping format encode the same information,
1240// but the V3 format does so more compactly by taking advantage of linkonce_odr
1241// semantics (it allows exactly 1 function record per name reference).
1242
1243/// This namespace defines accessors shared by different versions of coverage
1244/// mapping records.
1245namespace accessors {
1246
1247/// Return the structural hash associated with the function.
1248template <class FuncRecordTy, llvm::endianness Endian>
1249uint64_t getFuncHash(const FuncRecordTy *Record) {
1250 return support::endian::byte_swap<uint64_t>(Record->FuncHash, Endian);
1251}
1252
1253/// Return the coverage map data size for the function.
1254template <class FuncRecordTy, llvm::endianness Endian>
1255uint64_t getDataSize(const FuncRecordTy *Record) {
1256 return support::endian::byte_swap<uint32_t>(Record->DataSize, Endian);
1257}
1258
1259/// Return the function lookup key. The value is considered opaque.
1260template <class FuncRecordTy, llvm::endianness Endian>
1261uint64_t getFuncNameRef(const FuncRecordTy *Record) {
1262 return support::endian::byte_swap<uint64_t>(Record->NameRef, Endian);
1263}
1264
1265/// Return the PGO name of the function. Used for formats in which the name is
1266/// a hash.
1267template <class FuncRecordTy, llvm::endianness Endian>
1268Error getFuncNameViaRef(const FuncRecordTy *Record,
1269 InstrProfSymtab &ProfileNames, StringRef &FuncName) {
1271 FuncName = ProfileNames.getFuncOrVarName(NameRef);
1272 return Error::success();
1273}
1274
1275/// Read coverage mapping out-of-line, from \p MappingBuf. This is used when the
1276/// coverage mapping is attached to the file header, instead of to the function
1277/// record.
1278template <class FuncRecordTy, llvm::endianness Endian>
1280 const char *MappingBuf) {
1281 return {MappingBuf, size_t(getDataSize<FuncRecordTy, Endian>(Record))};
1282}
1283
1284/// Advance to the next out-of-line coverage mapping and its associated
1285/// function record.
1286template <class FuncRecordTy, llvm::endianness Endian>
1287std::pair<const char *, const FuncRecordTy *>
1288advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) {
1289 return {MappingBuf + getDataSize<FuncRecordTy, Endian>(Record), Record + 1};
1290}
1291
1292} // end namespace accessors
1293
1295template <class IntPtrT>
1298
1299#define COVMAP_V1
1300#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1302#undef COVMAP_V1
1303 CovMapFunctionRecordV1() = delete;
1304
1305 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1307 }
1308
1309 template <llvm::endianness Endian> uint64_t getDataSize() const {
1311 }
1312
1313 /// Return function lookup key. The value is consider opaque.
1314 template <llvm::endianness Endian> IntPtrT getFuncNameRef() const {
1316 }
1317
1318 /// Return the PGO name of the function.
1319 template <llvm::endianness Endian>
1320 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1321 IntPtrT NameRef = getFuncNameRef<Endian>();
1322 uint32_t NameS = support::endian::byte_swap<uint32_t>(NameSize, Endian);
1323 FuncName = ProfileNames.getFuncName(NameRef, NameS);
1324 if (NameS && FuncName.empty())
1326 "function name is empty");
1327 return Error::success();
1328 }
1329
1330 template <llvm::endianness Endian>
1331 std::pair<const char *, const ThisT *>
1332 advanceByOne(const char *MappingBuf) const {
1333 return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
1334 }
1335
1336 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1337 llvm_unreachable("V1 function format does not contain a filenames ref");
1338 }
1339
1340 template <llvm::endianness Endian>
1341 StringRef getCoverageMapping(const char *MappingBuf) const {
1343 MappingBuf);
1344 }
1345};
1346
1349
1350#define COVMAP_V2
1351#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1353#undef COVMAP_V2
1354 CovMapFunctionRecordV2() = delete;
1355
1356 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1358 }
1359
1360 template <llvm::endianness Endian> uint64_t getDataSize() const {
1362 }
1363
1364 template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
1366 }
1367
1368 template <llvm::endianness Endian>
1369 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1370 return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
1371 FuncName);
1372 }
1373
1374 template <llvm::endianness Endian>
1375 std::pair<const char *, const ThisT *>
1376 advanceByOne(const char *MappingBuf) const {
1377 return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
1378 }
1379
1380 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1381 llvm_unreachable("V2 function format does not contain a filenames ref");
1382 }
1383
1384 template <llvm::endianness Endian>
1385 StringRef getCoverageMapping(const char *MappingBuf) const {
1387 MappingBuf);
1388 }
1389};
1390
1393
1394#define COVMAP_V3
1395#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1397#undef COVMAP_V3
1398 CovMapFunctionRecordV3() = delete;
1399
1400 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1402 }
1403
1404 template <llvm::endianness Endian> uint64_t getDataSize() const {
1406 }
1407
1408 template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
1410 }
1411
1412 template <llvm::endianness Endian>
1413 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1414 return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
1415 FuncName);
1416 }
1417
1418 /// Get the filename set reference.
1419 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1421 }
1422
1423 /// Read the inline coverage mapping. Ignore the buffer parameter, it is for
1424 /// out-of-line coverage mapping data only.
1425 template <llvm::endianness Endian>
1426 StringRef getCoverageMapping(const char *) const {
1427 return StringRef(&CoverageMapping, getDataSize<Endian>());
1428 }
1429
1430 // Advance to the next inline coverage mapping and its associated function
1431 // record. Ignore the out-of-line coverage mapping buffer.
1432 template <llvm::endianness Endian>
1433 std::pair<const char *, const CovMapFunctionRecordV3 *>
1434 advanceByOne(const char *) const {
1435 assert(isAddrAligned(Align(8), this) && "Function record not aligned");
1436 const char *Next = ((const char *)this) + sizeof(CovMapFunctionRecordV3) -
1437 sizeof(char) + getDataSize<Endian>();
1438 // Each function record has an alignment of 8, so we need to adjust
1439 // alignment before reading the next record.
1441 return {nullptr, reinterpret_cast<const CovMapFunctionRecordV3 *>(Next)};
1442 }
1443};
1444
1445// Per module coverage mapping data header, i.e. CoverageMapFileHeader
1446// documented above.
1448#define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
1450 template <llvm::endianness Endian> uint32_t getNRecords() const {
1452 }
1453
1454 template <llvm::endianness Endian> uint32_t getFilenamesSize() const {
1456 }
1457
1458 template <llvm::endianness Endian> uint32_t getCoverageSize() const {
1460 }
1461
1462 template <llvm::endianness Endian> uint32_t getVersion() const {
1464 }
1465};
1466
1468
1471 // Function's name reference from CovMapFuncRecord is changed from raw
1472 // name string pointer to MD5 to support name section compression. Name
1473 // section is also compressed.
1475 // A new interpretation of the columnEnd field is added in order to mark
1476 // regions as gap areas.
1478 // Function records are named, uniqued, and moved to a dedicated section.
1480 // Branch regions referring to two counters are added
1482 // Compilation directory is stored separately and combined with relative
1483 // filenames to produce an absolute file path.
1485 // Branch regions extended and Decision Regions added for MC/DC.
1487 // The current version is Version7.
1489};
1490
1491// Correspond to "llvmcovm", in little-endian.
1492constexpr uint64_t TestingFormatMagic = 0x6d766f636d766c6c;
1493
1495 // The first version's number corresponds to the string "testdata" in
1496 // little-endian. This is for a historical reason.
1497 Version1 = 0x6174616474736574,
1498 // Version1 has a defect that it can't store multiple file records. Version2
1499 // fix this problem by adding a new field before the file records section.
1501 // The current testing format version is Version2.
1503};
1504
1505template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
1508};
1509
1510template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version3, IntPtrT> {
1513};
1514
1515template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version2, IntPtrT> {
1518};
1519
1520template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
1522 using NameRefType = IntPtrT;
1523};
1524
1525} // end namespace coverage
1526
1527/// Provide DenseMapInfo for CounterExpression
1528template<> struct DenseMapInfo<coverage::CounterExpression> {
1530 using namespace coverage;
1531
1532 return CounterExpression(CounterExpression::ExprKind::Subtract,
1533 Counter::getCounter(~0U),
1534 Counter::getCounter(~0U));
1535 }
1536
1538 using namespace coverage;
1539
1540 return CounterExpression(CounterExpression::ExprKind::Add,
1541 Counter::getCounter(~0U),
1542 Counter::getCounter(~0U));
1543 }
1544
1545 static unsigned getHashValue(const coverage::CounterExpression &V) {
1546 return static_cast<unsigned>(
1547 hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
1548 V.RHS.getKind(), V.RHS.getCounterID()));
1549 }
1550
1553 return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
1554 }
1555};
1556
1557} // end namespace llvm
1558
1559#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AMDGPU Mark last scratch load
This file implements the BitVector class.
This file declares a library for handling Build IDs and using them to find debug info.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_PACKED_START
Definition Compiler.h:554
DXIL Intrinsic Expansion
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
hexagon bit simplify
#define INSTR_PROF_COVMAP_VERSION
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
block placement Basic Block Placement Stats
static constexpr StringLiteral Filename
Value * RHS
Value * LHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
iterator end() const
Definition ArrayRef.h:131
const_pointer iterator
Definition ArrayRef.h:47
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:137
Base class for user error types.
Definition Error.h:354
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Class representing an expression and its matching format.
Reader for the indexed binary instrprof format.
A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...
Definition InstrProf.h:505
StringRef getFuncOrVarName(uint64_t ValMD5Hash) const
Return name of functions or global variables from the name's md5 hash value.
Definition InstrProf.h:777
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
A Counter expression builder is used to construct the counter expressions.
ArrayRef< CounterExpression > getExpressions() const
LLVM_ABI Counter subtract(Counter LHS, Counter RHS, bool Simplify=true)
Return a counter that represents the expression that subtracts RHS from LHS.
LLVM_ABI Counter add(Counter LHS, Counter RHS, bool Simplify=true)
Return a counter that represents the expression that adds LHS and RHS.
LLVM_ABI Counter subst(Counter C, const SubstMap &Map)
std::map< Counter, Counter > SubstMap
K to V map.
LLVM_ABI Expected< MCDCRecord > evaluateMCDCRegion(const CounterMappingRegion &Region, ArrayRef< const CounterMappingRegion * > Branches, bool IsVersion11)
Return an MCDC record that indicates executed test vectors and condition pairs.
void setCounts(ArrayRef< uint64_t > Counts)
void dump(const Counter &C) const
LLVM_ABI Expected< int64_t > evaluate(const Counter &C) const
Return the number of times that a region of code associated with this counter was executed.
void setBitmap(BitVector &&Bitmap_)
LLVM_ABI unsigned getMaxCounterID(const Counter &C) const
CounterMappingContext(ArrayRef< CounterExpression > Expressions, ArrayRef< uint64_t > CounterValues={})
LLVM_ABI void dump(const Counter &C, raw_ostream &OS) const
Coverage information to be processed or displayed.
CoverageData(CoverageData &&RHS)=default
std::vector< CountedRegion > BranchRegions
ArrayRef< ExpansionRecord > getExpansions() const
Expansions that can be further processed.
std::vector< CoverageSegment > Segments
std::vector< ExpansionRecord > Expansions
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
std::vector< MCDCRecord > MCDCRecords
StringRef getFilename() const
Get the name of the file this data covers.
ArrayRef< MCDCRecord > getMCDCRecords() const
MCDC Records that can be further processed.
CoverageData(bool Single, 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.
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.
LLVM_ABI std::vector< StringRef > getUniqueSourceFiles() const
Returns a lexicographically sorted, unique list of files that are covered.
LLVM_ABI 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.
LLVM_ABI CoverageData getCoverageForFunction(const FunctionRecord &Function) const
Get the coverage for a particular function.
CoverageMapping(const CoverageMapping &)=delete
LLVM_ABI std::vector< InstantiationGroup > getInstantiationGroups(StringRef Filename) const
Get the list of function instantiation groups in a particular file.
LLVM_ABI CoverageData getCoverageForFile(StringRef Filename) const
Get the coverage for a particular file.
CoverageMapping & operator=(const CoverageMapping &)=delete
Iterator over Functions, optionally filtered to a single file.
FunctionRecordIterator(ArrayRef< FunctionRecord > Records_, StringRef Filename="", ArrayRef< unsigned > RecordIndices_={})
FunctionRecordIterator & operator++()
bool operator==(const FunctionRecordIterator &RHS) const
const FunctionRecord & operator*() const
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
LLVM_ABI LineCoverageIterator & operator++()
LineCoverageIterator(const CoverageData &CD, unsigned Line)
Coverage statistics for a single line.
const CoverageSegment * getWrappedSegment() const
ArrayRef< const CoverageSegment * > getLineSegments() const
Emulate SmallVector<CondState> with a pair of BitVector.
auto getIndex() const
Equivalent to buildTestVector's Index.
CondState operator[](int I) const
Emulate RHS SmallVector::operator[].
void set(int I, CondState Val)
Set the condition Val at position I.
auto getDifferences(const TestVector &B) const
For each element:
void push_back(CondState Val)
Emulate SmallVector::push_back.
static constexpr auto HardMaxTVs
Hard limit of test vectors.
LLVM_ABI TVIdxBuilder(const SmallVectorImpl< ConditionIDs > &NextIDs, int Offset=0)
Calculate and assign Indices.
SmallVector< std::array< int, 2 > > Indices
Output: Index for TestVectors bitmap (These are not CondIDs)
int NumTestVectors
Output: The number of test vectors.
SmallVector< MCDCNode > SavedNodes
This is no longer needed after the assignment.
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:40
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
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.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
This namespace defines accessors shared by different versions of coverage mapping records.
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.
static auto & getParams(MaybeConstMCDCParameters &MCDCParams)
Check and get underlying params in MCDCParams.
Definition MCDCTypes.h:64
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
Definition MCDCTypes.h:56
std::array< ConditionID, 2 > ConditionIDs
Definition MCDCTypes.h:26
LLVM_ABI const std::error_category & coveragemap_category()
std::error_code make_error_code(coveragemap_error E)
std::pair< unsigned, unsigned > LineColPair
static iterator_range< LineCoverageIterator > getLineCoverageStats(const coverage::CoverageData &CD)
Get a LineCoverageIterator range for the lines described by CD.
constexpr uint64_t TestingFormatMagic
value_type byte_swap(value_type value, endianness endian)
Definition Endian.h:44
This is an optimization pass for GlobalISel generic memory operations.
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
@ Offset
Definition DWP.cpp:532
LLVM_PACKED_END
Definition VPlan.h:1108
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:192
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
FunctionAddr VTableAddr Next
Definition InstrProf.h:141
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
Definition STLExtras.h:2012
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
Definition STLExtras.h:1409
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:1917
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition Hashing.h:592
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
Definition Alignment.h:139
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
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...
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 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)
CounterMappingRegion(Counter Count, Counter FalseCount, unsigned FileID, unsigned ExpandedFileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind, const mcdc::Parameters &MCDCParams=std::monostate())
static CounterMappingRegion makeRegion(Counter Count, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd)
static CounterMappingRegion makeDecisionRegion(const mcdc::DecisionParameters &MCDCParams, 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).
static CounterMappingRegion makeBranchRegion(Counter Count, Counter FalseCount, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd, const mcdc::Parameters &MCDCParams=std::monostate())
mcdc::Parameters MCDCParams
Parameters used for Modified Condition/Decision Coverage.
@ ExpansionRegion
An ExpansionRegion represents a file expansion region that associates a source range with the expansi...
@ MCDCDecisionRegion
A DecisionRegion represents a top-level boolean expression and is associated with a variable length b...
@ MCDCBranchRegion
A Branch Region can be extended to include IDs to facilitate MC/DC.
@ 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
FunctionAddr VTableAddr uintptr_t uintptr_t NamePtr
Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const
Return the PGO name of the function.
CovMapFunctionRecordV1< IntPtrT > ThisT
FunctionAddr VTableAddr uintptr_t uintptr_t NameSize
FunctionAddr ConstantInt::get(llvm::Type::getInt32Ty(Ctx), NumBitmapBytes)) INSTR_PROF_VTABLE_DATA(const uint64_t
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
FunctionAddr VTableAddr uintptr_t uintptr_t FilenamesRef
FunctionAddr VTableAddr uintptr_t uintptr_t CoverageMapping
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
FunctionAddr VTableAddr uintptr_t uintptr_t Version
FunctionAddr VTableAddr uintptr_t uintptr_t NRecords
FunctionAddr VTableAddr uintptr_t uintptr_t CoverageSize
FunctionAddr VTableAddr uintptr_t uintptr_t FilenamesSize
CovMapFunctionRecordV3 CovMapFuncRecordType
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
void pushMCDCRecord(MCDCRecord &&Record)
std::vector< MCDCRecord > MCDCRecords
MCDC Records record a DecisionRegion and associated BranchRegions.
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)
MCDC Record grouping all information together.
std::pair< unsigned, unsigned > TVRowPair
MCDCRecord(const CounterMappingRegion &Region, TestVectors &&TV, TestVectors &&NotExecutedTV, BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc)
CondState getNotExecutedTVCondition(unsigned NotExecutedIndex, unsigned Condition)
CondState getNotExecutedTVResult(unsigned NotExecutedIndex)
std::string getConditionCoverageString(unsigned Condition)
std::pair< unsigned, unsigned > getDecisions() const
Return the number of True and False decisions for all executed test vectors.
std::string getConditionHeaderString(unsigned Condition)
unsigned getNumTestVectors() const
llvm::SmallVector< std::pair< TestVector, CondState > > TestVectors
unsigned getNumNotExecutedTestVectors() const
LLVM_ABI void findIndependencePairs()
std::string getTestVectorString(unsigned TestVectorIndex)
llvm::DenseMap< unsigned, unsigned > CondIDMap
llvm::DenseMap< unsigned, LineColPair > LineColPairMap
TVRowPair getConditionIndependencePair(unsigned Condition)
Return the Independence Pair that covers the given condition.
bool isConditionIndependencePairCovered(unsigned Condition) const
Determine whether a given condition (indicated by Condition) is covered by an Independence Pair.
CondState
CondState represents the evaluation of a condition in an executed test vector, which can be True or F...
std::string getTestVectorHeaderString() const
CondState getTVCondition(unsigned TestVectorIndex, unsigned Condition)
Return the evaluation of a condition (indicated by Condition) in an executed test vector (indicated b...
std::string getNotExecutedTestVectorString(unsigned NotExecutedIndex)
unsigned getNumConditions() const
std::array< BitVector, 2 > BoolVector
const CounterMappingRegion & getDecisionRegion() const
llvm::DenseMap< unsigned, TVRowPair > TVPairMap
CondState getTVResult(unsigned TestVectorIndex)
Return the Result evaluation for an executed test vector.
bool isCondFolded(unsigned Condition) const
ConditionIDs NextIDs
Number of accumulated paths (>= 1)
int Width
Reference count; temporary use.