LLVM 22.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
49class IndexedInstrProfReader;
50
51namespace object {
52class BuildIDFetcher;
53} // namespace object
54
55namespace vfs {
56class FileSystem;
57} // namespace vfs
58
59namespace coverage {
60
63
65 success = 0,
66 eof,
73};
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());
79}
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 }
87
88 std::string message() const override;
89
90 void log(raw_ostream &OS) const override { OS << message(); }
91
92 std::error_code convertToErrorCode() const override {
93 return make_error_code(Err);
94 }
95
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;
138 }
139
140 friend bool operator!=(const Counter &LHS, const Counter &RHS) {
141 return !(LHS == RHS);
142 }
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);
154 }
155
156 /// Return the counter that corresponds to a specific addition counter
157 /// expression.
158 static Counter getExpression(unsigned ExpressionId) {
159 return Counter(Expression, ExpressionId);
160 }
161};
162
163/// A Counter expression is a value that represents an arithmetic operation
164/// with two counters.
169
171 : Kind(Kind), LHS(LHS), RHS(RHS) {}
172};
173
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 };
198
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);
219
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
272 const auto &getDecisionParams() const {
273 return mcdc::getParams<const mcdc::DecisionParameters>(MCDCParams);
274 }
275
276 const auto &getBranchParams() const {
277 return mcdc::getParams<const mcdc::BranchParameters>(MCDCParams);
278 }
279
280 unsigned FileID = 0;
281 unsigned ExpandedFileID = 0;
283
285
286 bool isBranch() const {
287 return (Kind == BranchRegion || Kind == MCDCBranchRegion);
288 }
289
291 unsigned LineStart, unsigned ColumnStart,
292 unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
296
298 unsigned ExpandedFileID, unsigned LineStart,
299 unsigned ColumnStart, unsigned LineEnd,
300 unsigned ColumnEnd, RegionKind Kind,
301 const mcdc::Parameters &MCDCParams = std::monostate())
305 Kind(Kind) {}
306
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
323 makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart,
324 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
328 }
329
331 makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart,
332 unsigned LineEnd, unsigned ColumnEnd) {
335 }
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
359 unsigned FileID, unsigned LineStart, unsigned ColumnStart,
360 unsigned LineEnd, unsigned ColumnEnd) {
363 }
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.
378
382
388};
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 std::optional<TVPairMap> IndependencePairs;
463 BoolVector Folded;
464 CondIDMap PosToID;
465 LineColPairMap CondLoc;
466
467public:
469 BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc)
470 : Region(Region), TV(std::move(TV)), Folded(std::move(Folded)),
471 PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) {
473 }
474
475 // Compare executed test vectors against each other to find an independence
476 // pairs for each condition. This processing takes the most time.
478
480 unsigned getNumConditions() const {
481 return Region.getDecisionParams().NumConditions;
482 }
483 unsigned getNumTestVectors() const { return TV.size(); }
484 bool isCondFolded(unsigned Condition) const {
485 return Folded[false][Condition] || Folded[true][Condition];
486 }
487
488 /// Return the evaluation of a condition (indicated by Condition) in an
489 /// executed test vector (indicated by TestVectorIndex), which will be True,
490 /// False, or DontCare if the condition is unevaluatable. Because condition
491 /// IDs are not associated based on their position in the expression,
492 /// accessing conditions in the TestVectors requires a translation from a
493 /// ordinal position to actual condition ID. This is done via PosToID[].
494 CondState getTVCondition(unsigned TestVectorIndex, unsigned Condition) {
495 return TV[TestVectorIndex].first[PosToID[Condition]];
496 }
497
498 /// Return the number of True and False decisions for all executed test
499 /// vectors.
500 std::pair<unsigned, unsigned> getDecisions() const {
501 const unsigned TrueDecisions =
503
504 return {TrueDecisions, TV.size() - TrueDecisions};
505 }
506
507 /// Return the Result evaluation for an executed test vector.
508 /// See MCDCRecordProcessor::RecordTestVector().
509 CondState getTVResult(unsigned TestVectorIndex) {
510 return TV[TestVectorIndex].second;
511 }
512
513 /// Determine whether a given condition (indicated by Condition) is covered
514 /// by an Independence Pair. Because condition IDs are not associated based
515 /// on their position in the expression, accessing conditions in the
516 /// TestVectors requires a translation from a ordinal position to actual
517 /// condition ID. This is done via PosToID[].
518 bool isConditionIndependencePairCovered(unsigned Condition) const {
519 assert(IndependencePairs);
520 auto It = PosToID.find(Condition);
521 assert(It != PosToID.end() && "Condition ID without an Ordinal mapping");
522 return IndependencePairs->contains(It->second);
523 }
524
525 /// Return the Independence Pair that covers the given condition. Because
526 /// condition IDs are not associated based on their position in the
527 /// expression, accessing conditions in the TestVectors requires a
528 /// translation from a ordinal position to actual condition ID. This is done
529 /// via PosToID[].
532 assert(IndependencePairs);
533 return (*IndependencePairs)[PosToID[Condition]];
534 }
535
536 float getPercentCovered() const {
537 unsigned Folded = 0;
538 unsigned Covered = 0;
539 for (unsigned C = 0; C < getNumConditions(); C++) {
540 if (isCondFolded(C))
541 Folded++;
543 Covered++;
544 }
545
546 unsigned Total = getNumConditions() - Folded;
547 if (Total == 0)
548 return 0.0;
549 return (static_cast<double>(Covered) / static_cast<double>(Total)) * 100.0;
550 }
551
552 std::string getConditionHeaderString(unsigned Condition) {
553 std::ostringstream OS;
554 const auto &[Line, Col] = CondLoc[Condition];
555 OS << "Condition C" << Condition + 1 << " --> (" << Line << ":" << Col
556 << ")\n";
557 return OS.str();
558 }
559
560 std::string getTestVectorHeaderString() const {
561 std::ostringstream OS;
562 if (getNumTestVectors() == 0) {
563 OS << "None.\n";
564 return OS.str();
565 }
566 const auto NumConditions = getNumConditions();
567 for (unsigned I = 0; I < NumConditions; I++) {
568 OS << "C" << I + 1;
569 if (I != NumConditions - 1)
570 OS << ", ";
571 }
572 OS << " Result\n";
573 return OS.str();
574 }
575
576 std::string getTestVectorString(unsigned TestVectorIndex) {
577 assert(TestVectorIndex < getNumTestVectors() &&
578 "TestVector index out of bounds!");
579 std::ostringstream OS;
580 const auto NumConditions = getNumConditions();
581 // Add individual condition values to the string.
582 OS << " " << TestVectorIndex + 1 << " { ";
583 for (unsigned Condition = 0; Condition < NumConditions; Condition++) {
584 if (isCondFolded(Condition))
585 OS << "C";
586 else {
587 switch (getTVCondition(TestVectorIndex, Condition)) {
589 OS << "-";
590 break;
592 OS << "T";
593 break;
595 OS << "F";
596 break;
597 }
598 }
599 if (Condition != NumConditions - 1)
600 OS << ", ";
601 }
602
603 // Add result value to the string.
604 OS << " = ";
605 if (getTVResult(TestVectorIndex) == MCDC_True)
606 OS << "T";
607 else
608 OS << "F";
609 OS << " }\n";
610
611 return OS.str();
612 }
613
614 std::string getConditionCoverageString(unsigned Condition) {
615 assert(Condition < getNumConditions() &&
616 "Condition index is out of bounds!");
617 std::ostringstream OS;
618
619 OS << " C" << Condition + 1 << "-Pair: ";
620 if (isCondFolded(Condition)) {
621 OS << "constant folded\n";
622 } else if (isConditionIndependencePairCovered(Condition)) {
623 TVRowPair rows = getConditionIndependencePair(Condition);
624 OS << "covered: (" << rows.first << ",";
625 OS << rows.second << ")\n";
626 } else
627 OS << "not covered\n";
628
629 return OS.str();
630 }
631};
632
633namespace mcdc {
634/// Compute TestVector Indices "TVIdx" from the Conds graph.
635///
636/// Clang CodeGen handles the bitmap index based on TVIdx.
637/// llvm-cov reconstructs conditions from TVIdx.
638///
639/// For each leaf "The final decision",
640/// - TVIdx should be unique.
641/// - TVIdx has the Width.
642/// - The width represents the number of possible paths.
643/// - The minimum width is 1 "deterministic".
644/// - The order of leaves are sorted by Width DESC. It expects
645/// latter TVIdx(s) (with Width=1) could be pruned and altered to
646/// other simple branch conditions.
647///
649public:
650 struct MCDCNode {
651 int InCount = 0; /// Reference count; temporary use
652 int Width; /// Number of accumulated paths (>= 1)
654 };
655
656#ifndef NDEBUG
657 /// This is no longer needed after the assignment.
658 /// It may be used in assert() for reconfirmation.
660#endif
661
662 /// Output: Index for TestVectors bitmap (These are not CondIDs)
664
665 /// Output: The number of test vectors.
666 /// Error with HardMaxTVs if the number has exploded.
668
669 /// Hard limit of test vectors
670 static constexpr auto HardMaxTVs =
671 std::numeric_limits<decltype(NumTestVectors)>::max();
672
673public:
674 /// Calculate and assign Indices
675 /// \param NextIDs The list of {FalseID, TrueID} indexed by ID
676 /// The first element [0] should be the root node.
677 /// \param Offset Offset of index to final decisions.
679 int Offset = 0);
680};
681} // namespace mcdc
682
683/// A Counter mapping context is used to connect the counters, expressions
684/// and the obtained counter values.
686 ArrayRef<CounterExpression> Expressions;
687 ArrayRef<uint64_t> CounterValues;
688 BitVector Bitmap;
689
690public:
692 ArrayRef<uint64_t> CounterValues = {})
693 : Expressions(Expressions), CounterValues(CounterValues) {}
694
695 void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
696 void setBitmap(BitVector &&Bitmap_) { Bitmap = std::move(Bitmap_); }
697
698 LLVM_ABI void dump(const Counter &C, raw_ostream &OS) const;
699 void dump(const Counter &C) const { dump(C, dbgs()); }
700
701 /// Return the number of times that a region of code associated with this
702 /// counter was executed.
704
705 /// Return an MCDC record that indicates executed test vectors and condition
706 /// pairs.
710 bool IsVersion11);
711
712 LLVM_ABI unsigned getMaxCounterID(const Counter &C) const;
713};
714
715/// Code coverage information for a single function.
717 /// Raw function name.
718 std::string Name;
719 /// Mapping from FileID (i.e. vector index) to filename. Used to support
720 /// macro expansions within a function in which the macro and function are
721 /// defined in separate files.
722 ///
723 /// TODO: Uniquing filenames across all function records may be a performance
724 /// optimization.
725 std::vector<std::string> Filenames;
726 /// Regions in the function along with their counts.
727 std::vector<CountedRegion> CountedRegions;
728 /// Branch Regions in the function along with their counts.
729 std::vector<CountedRegion> CountedBranchRegions;
730 /// MCDC Records record a DecisionRegion and associated BranchRegions.
731 std::vector<MCDCRecord> MCDCRecords;
732 /// The number of times this function was executed.
734
736 : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
737
740
742 MCDCRecords.push_back(std::move(Record));
743 }
744
746 uint64_t FalseCount) {
747 if (Region.isBranch()) {
748 CountedBranchRegions.emplace_back(Region, Count, FalseCount);
749 // If either counter is hard-coded to zero, then this region represents a
750 // constant-folded branch.
751 CountedBranchRegions.back().TrueFolded = Region.Count.isZero();
752 CountedBranchRegions.back().FalseFolded = Region.FalseCount.isZero();
753 return;
754 }
755 if (CountedRegions.empty())
756 ExecutionCount = Count;
757 CountedRegions.emplace_back(Region, Count, FalseCount);
758 }
759};
760
761/// Iterator over Functions, optionally filtered to a single file.
762/// When filtering to a single file, the iterator requires a list of potential
763/// indices where to find the desired records to avoid quadratic behavior when
764/// repeatedly iterating over functions from different files.
766 : public iterator_facade_base<FunctionRecordIterator,
767 std::forward_iterator_tag, FunctionRecord> {
769 ArrayRef<unsigned> RecordIndices;
770 ArrayRef<unsigned>::iterator CurrentIndex;
772 StringRef Filename;
773
774 /// Skip records whose primary file is not \c Filename.
775 LLVM_ABI void skipOtherFiles();
776
777public:
779 StringRef Filename = "",
780 ArrayRef<unsigned> RecordIndices_ = {})
781 : Records(Records_), RecordIndices(RecordIndices_),
782 CurrentIndex(RecordIndices.begin()),
783 // If `RecordIndices` is provided, we can skip directly to the first
784 // index it provides.
785 Current(CurrentIndex == RecordIndices.end() ? Records.begin()
786 : &Records[*CurrentIndex]),
787 Filename(Filename) {
788 assert(Filename.empty() == RecordIndices_.empty() &&
789 "If `Filename` is specified, `RecordIndices` must also be provided");
790 skipOtherFiles();
791 }
792
793 FunctionRecordIterator() : Current(Records.begin()) {}
794
796 return Current == RHS.Current && Filename == RHS.Filename;
797 }
798
799 const FunctionRecord &operator*() const { return *Current; }
800
802 advanceOne();
803 skipOtherFiles();
804 return *this;
805 }
806
807private:
808 void advanceOne() {
809 if (RecordIndices.empty()) {
810 // Iteration over all entries, advance in the list of records.
811 assert(Current != Records.end() && "incremented past end");
812 ++Current;
813 } else {
814 // Iterator over entries filtered by file name. Advance in the list of
815 // indices, and adjust the cursor in the list of records accordingly.
816 assert(CurrentIndex != RecordIndices.end() && "incremented past end");
817 ++CurrentIndex;
818 if (CurrentIndex == RecordIndices.end()) {
819 Current = Records.end();
820 } else {
821 Current = &Records[*CurrentIndex];
822 }
823 }
824 }
825};
826
827/// Coverage information for a macro expansion or #included file.
828///
829/// When covered code has pieces that can be expanded for more detail, such as a
830/// preprocessor macro use and its definition, these are represented as
831/// expansions whose coverage can be looked up independently.
833 /// The abstract file this expansion covers.
834 unsigned FileID;
835 /// The region that expands to this record.
837 /// Coverage for the expansion.
839
842 : FileID(Region.ExpandedFileID), Region(Region), Function(Function) {}
843};
844
845/// The execution count information starting at a point in a file.
846///
847/// A sequence of CoverageSegments gives execution counts for a file in format
848/// that's simple to iterate through for processing.
850 /// The line where this segment begins.
851 unsigned Line;
852 /// The column where this segment begins.
853 unsigned Col;
854 /// The execution count, or zero if no count was recorded.
856 /// When false, the segment was uninstrumented or skipped.
858 /// Whether this enters a new region or returns to a previous count.
860 /// Whether this enters a gap region.
862
863 CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
864 : Line(Line), Col(Col), Count(0), HasCount(false),
866
867 CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
868 bool IsRegionEntry, bool IsGapRegion = false,
869 bool IsBranchRegion = false)
872
873 friend bool operator==(const CoverageSegment &L, const CoverageSegment &R) {
874 return std::tie(L.Line, L.Col, L.Count, L.HasCount, L.IsRegionEntry,
875 L.IsGapRegion) == std::tie(R.Line, R.Col, R.Count,
876 R.HasCount, R.IsRegionEntry,
877 R.IsGapRegion);
878 }
879};
880
881/// An instantiation group contains a \c FunctionRecord list, such that each
882/// record corresponds to a distinct instantiation of the same function.
883///
884/// Note that it's possible for a function to have more than one instantiation
885/// (consider C++ template specializations or static inline functions).
887 friend class CoverageMapping;
888
889 unsigned Line;
890 unsigned Col;
891 std::vector<const FunctionRecord *> Instantiations;
892
893 InstantiationGroup(unsigned Line, unsigned Col,
894 std::vector<const FunctionRecord *> Instantiations)
895 : Line(Line), Col(Col), Instantiations(std::move(Instantiations)) {}
896
897public:
900
901 /// Get the number of instantiations in this group.
902 size_t size() const { return Instantiations.size(); }
903
904 /// Get the line where the common function was defined.
905 unsigned getLine() const { return Line; }
906
907 /// Get the column where the common function was defined.
908 unsigned getColumn() const { return Col; }
909
910 /// Check if the instantiations in this group have a common mangled name.
911 bool hasName() const {
912 for (unsigned I = 1, E = Instantiations.size(); I < E; ++I)
913 if (Instantiations[I]->Name != Instantiations[0]->Name)
914 return false;
915 return true;
916 }
917
918 /// Get the common mangled name for instantiations in this group.
920 assert(hasName() && "Instantiations don't have a shared name");
921 return Instantiations[0]->Name;
922 }
923
924 /// Get the total execution count of all instantiations in this group.
926 uint64_t Count = 0;
927 for (const FunctionRecord *F : Instantiations)
928 Count += F->ExecutionCount;
929 return Count;
930 }
931
932 /// Get the instantiations in this group.
934 return Instantiations;
935 }
936};
937
938/// Coverage information to be processed or displayed.
939///
940/// This represents the coverage of an entire file, expansion, or function. It
941/// provides a sequence of CoverageSegments to iterate through, as well as the
942/// list of expansions that can be further processed.
944 friend class CoverageMapping;
945
946 std::string Filename;
947 std::vector<CoverageSegment> Segments;
948 std::vector<ExpansionRecord> Expansions;
949 std::vector<CountedRegion> BranchRegions;
950 std::vector<MCDCRecord> MCDCRecords;
951
952 bool SingleByteCoverage = false;
953
954public:
955 CoverageData() = default;
956
957 CoverageData(bool Single, StringRef Filename)
958 : Filename(Filename), SingleByteCoverage(Single) {}
959
960 /// Get the name of the file this data covers.
961 StringRef getFilename() const { return Filename; }
962
964
965 /// Get an iterator over the coverage segments for this object. The segments
966 /// are guaranteed to be uniqued and sorted by location.
967 std::vector<CoverageSegment>::const_iterator begin() const {
968 return Segments.begin();
969 }
970
971 std::vector<CoverageSegment>::const_iterator end() const {
972 return Segments.end();
973 }
974
975 bool empty() const { return Segments.empty(); }
976
977 /// Expansions that can be further processed.
978 ArrayRef<ExpansionRecord> getExpansions() const { return Expansions; }
979
980 /// Branches that can be further processed.
981 ArrayRef<CountedRegion> getBranches() const { return BranchRegions; }
982
983 /// MCDC Records that can be further processed.
984 ArrayRef<MCDCRecord> getMCDCRecords() const { return MCDCRecords; }
985};
986
987/// The mapping of profile information to coverage data.
988///
989/// This is the main interface to get coverage information, using a profile to
990/// fill out execution counts.
992 DenseMap<size_t, DenseSet<size_t>> RecordProvenance;
993 std::vector<FunctionRecord> Functions;
994 DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices;
995 std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
996
997 std::optional<bool> SingleByteCoverage;
998
999 CoverageMapping() = default;
1000
1001 // Load coverage records from readers.
1002 static Error loadFromReaders(
1003 ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
1004 std::optional<std::reference_wrapper<IndexedInstrProfReader>>
1005 &ProfileReader,
1006 CoverageMapping &Coverage);
1007
1008 // Load coverage records from file.
1009 static Error
1010 loadFromFile(StringRef Filename, StringRef Arch, StringRef CompilationDir,
1011 std::optional<std::reference_wrapper<IndexedInstrProfReader>>
1012 &ProfileReader,
1013 CoverageMapping &Coverage, bool &DataFound,
1014 SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr);
1015
1016 /// Add a function record corresponding to \p Record.
1017 Error loadFunctionRecord(
1019 const std::optional<std::reference_wrapper<IndexedInstrProfReader>>
1020 &ProfileReader);
1021
1022 /// Look up the indices for function records which are at least partially
1023 /// defined in the specified file. This is guaranteed to return a superset of
1024 /// such records: extra records not in the file may be included if there is
1025 /// a hash collision on the filename. Clients must be robust to collisions.
1027 getImpreciseRecordIndicesForFilename(StringRef Filename) const;
1028
1029public:
1032
1033 /// Load the coverage mapping using the given readers.
1035 load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
1036 std::optional<std::reference_wrapper<IndexedInstrProfReader>>
1037 &ProfileReader);
1038
1039 /// Load the coverage mapping from the given object files and profile. If
1040 /// \p Arches is non-empty, it must specify an architecture for each object.
1041 /// Ignores non-instrumented object files unless all are not instrumented.
1043 load(ArrayRef<StringRef> ObjectFilenames,
1044 std::optional<StringRef> ProfileFilename, vfs::FileSystem &FS,
1045 ArrayRef<StringRef> Arches = {}, StringRef CompilationDir = "",
1046 const object::BuildIDFetcher *BIDFetcher = nullptr,
1047 bool CheckBinaryIDs = false);
1048
1049 /// The number of functions that couldn't have their profiles mapped.
1050 ///
1051 /// This is a count of functions whose profile is out of date or otherwise
1052 /// can't be associated with any coverage information.
1053 unsigned getMismatchedCount() const { return FuncHashMismatches.size(); }
1054
1055 /// A hash mismatch occurs when a profile record for a symbol does not have
1056 /// the same hash as a coverage mapping record for the same symbol. This
1057 /// returns a list of hash mismatches, where each mismatch is a pair of the
1058 /// symbol name and its coverage mapping hash.
1060 return FuncHashMismatches;
1061 }
1062
1063 /// Returns a lexicographically sorted, unique list of files that are
1064 /// covered.
1065 LLVM_ABI std::vector<StringRef> getUniqueSourceFiles() const;
1066
1067 /// Get the coverage for a particular file.
1068 ///
1069 /// The given filename must be the name as recorded in the coverage
1070 /// information. That is, only names returned from getUniqueSourceFiles will
1071 /// yield a result.
1073
1074 /// Get the coverage for a particular function.
1077
1078 /// Get the coverage for an expansion within a coverage set.
1081
1082 /// Gets all of the functions covered by this profile.
1084 return make_range(FunctionRecordIterator(Functions),
1086 }
1087
1088 /// Gets all of the functions in a particular file.
1091 return make_range(
1092 FunctionRecordIterator(Functions, Filename,
1093 getImpreciseRecordIndicesForFilename(Filename)),
1095 }
1096
1097 /// Get the list of function instantiation groups in a particular file.
1098 ///
1099 /// Every instantiation group in a program is attributed to exactly one file:
1100 /// the file in which the definition for the common function begins.
1101 LLVM_ABI std::vector<InstantiationGroup>
1102 getInstantiationGroups(StringRef Filename) const;
1103};
1104
1105/// Coverage statistics for a single line.
1107 uint64_t ExecutionCount;
1108 bool HasMultipleRegions;
1109 bool Mapped;
1110 unsigned Line;
1112 const CoverageSegment *WrappedSegment;
1113
1115 LineCoverageStats() = default;
1116
1117public:
1119 const CoverageSegment *WrappedSegment,
1120 unsigned Line);
1121
1122 uint64_t getExecutionCount() const { return ExecutionCount; }
1123
1124 bool hasMultipleRegions() const { return HasMultipleRegions; }
1125
1126 bool isMapped() const { return Mapped; }
1127
1128 unsigned getLine() const { return Line; }
1129
1131 return LineSegments;
1132 }
1133
1134 const CoverageSegment *getWrappedSegment() const { return WrappedSegment; }
1135};
1136
1137/// An iterator over the \c LineCoverageStats objects for lines described by
1138/// a \c CoverageData instance.
1140 : public iterator_facade_base<LineCoverageIterator,
1141 std::forward_iterator_tag,
1142 const LineCoverageStats> {
1143public:
1145 : LineCoverageIterator(CD, CD.begin()->Line) {}
1146
1147 LineCoverageIterator(const CoverageData &CD, unsigned Line)
1148 : CD(CD), WrappedSegment(nullptr), Next(CD.begin()), Ended(false),
1149 Line(Line) {
1150 this->operator++();
1151 }
1152
1153 bool operator==(const LineCoverageIterator &R) const {
1154 return &CD == &R.CD && Next == R.Next && Ended == R.Ended;
1155 }
1156
1157 const LineCoverageStats &operator*() const { return Stats; }
1158
1160
1162 auto EndIt = *this;
1163 EndIt.Next = CD.end();
1164 EndIt.Ended = true;
1165 return EndIt;
1166 }
1167
1168private:
1169 const CoverageData &CD;
1170 const CoverageSegment *WrappedSegment;
1171 std::vector<CoverageSegment>::const_iterator Next;
1172 bool Ended;
1173 unsigned Line;
1175 LineCoverageStats Stats;
1176};
1177
1178/// Get a \c LineCoverageIterator range for the lines described by \p CD.
1181 auto Begin = LineCoverageIterator(CD);
1182 auto End = Begin.getEnd();
1183 return make_range(Begin, End);
1184}
1185
1186// Coverage mappping data (V2) has the following layout:
1187// IPSK_covmap:
1188// [CoverageMapFileHeader]
1189// [ArrayStart]
1190// [CovMapFunctionRecordV2]
1191// [CovMapFunctionRecordV2]
1192// ...
1193// [ArrayEnd]
1194// [Encoded Filenames and Region Mapping Data]
1195//
1196// Coverage mappping data (V3) has the following layout:
1197// IPSK_covmap:
1198// [CoverageMapFileHeader]
1199// [Encoded Filenames]
1200// IPSK_covfun:
1201// [ArrayStart]
1202// odr_name_1: [CovMapFunctionRecordV3]
1203// odr_name_2: [CovMapFunctionRecordV3]
1204// ...
1205// [ArrayEnd]
1206//
1207// Both versions of the coverage mapping format encode the same information,
1208// but the V3 format does so more compactly by taking advantage of linkonce_odr
1209// semantics (it allows exactly 1 function record per name reference).
1210
1211/// This namespace defines accessors shared by different versions of coverage
1212/// mapping records.
1213namespace accessors {
1214
1215/// Return the structural hash associated with the function.
1216template <class FuncRecordTy, llvm::endianness Endian>
1217uint64_t getFuncHash(const FuncRecordTy *Record) {
1218 return support::endian::byte_swap<uint64_t, Endian>(Record->FuncHash);
1219}
1220
1221/// Return the coverage map data size for the function.
1222template <class FuncRecordTy, llvm::endianness Endian>
1223uint64_t getDataSize(const FuncRecordTy *Record) {
1224 return support::endian::byte_swap<uint32_t, Endian>(Record->DataSize);
1225}
1226
1227/// Return the function lookup key. The value is considered opaque.
1228template <class FuncRecordTy, llvm::endianness Endian>
1229uint64_t getFuncNameRef(const FuncRecordTy *Record) {
1230 return support::endian::byte_swap<uint64_t, Endian>(Record->NameRef);
1231}
1232
1233/// Return the PGO name of the function. Used for formats in which the name is
1234/// a hash.
1235template <class FuncRecordTy, llvm::endianness Endian>
1236Error getFuncNameViaRef(const FuncRecordTy *Record,
1237 InstrProfSymtab &ProfileNames, StringRef &FuncName) {
1238 uint64_t NameRef = getFuncNameRef<FuncRecordTy, Endian>(Record);
1239 FuncName = ProfileNames.getFuncOrVarName(NameRef);
1240 return Error::success();
1241}
1242
1243/// Read coverage mapping out-of-line, from \p MappingBuf. This is used when the
1244/// coverage mapping is attached to the file header, instead of to the function
1245/// record.
1246template <class FuncRecordTy, llvm::endianness Endian>
1248 const char *MappingBuf) {
1249 return {MappingBuf, size_t(getDataSize<FuncRecordTy, Endian>(Record))};
1250}
1251
1252/// Advance to the next out-of-line coverage mapping and its associated
1253/// function record.
1254template <class FuncRecordTy, llvm::endianness Endian>
1255std::pair<const char *, const FuncRecordTy *>
1256advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) {
1257 return {MappingBuf + getDataSize<FuncRecordTy, Endian>(Record), Record + 1};
1258}
1259
1260} // end namespace accessors
1261
1263template <class IntPtrT>
1266
1267#define COVMAP_V1
1268#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1270#undef COVMAP_V1
1272
1273 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1274 return accessors::getFuncHash<ThisT, Endian>(this);
1275 }
1276
1277 template <llvm::endianness Endian> uint64_t getDataSize() const {
1278 return accessors::getDataSize<ThisT, Endian>(this);
1279 }
1280
1281 /// Return function lookup key. The value is consider opaque.
1282 template <llvm::endianness Endian> IntPtrT getFuncNameRef() const {
1283 return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
1284 }
1285
1286 /// Return the PGO name of the function.
1287 template <llvm::endianness Endian>
1288 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1289 IntPtrT NameRef = getFuncNameRef<Endian>();
1290 uint32_t NameS = support::endian::byte_swap<uint32_t, Endian>(NameSize);
1291 FuncName = ProfileNames.getFuncName(NameRef, NameS);
1292 if (NameS && FuncName.empty())
1293 return make_error<CoverageMapError>(coveragemap_error::malformed,
1294 "function name is empty");
1295 return Error::success();
1296 }
1297
1298 template <llvm::endianness Endian>
1299 std::pair<const char *, const ThisT *>
1300 advanceByOne(const char *MappingBuf) const {
1301 return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
1302 }
1303
1304 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1305 llvm_unreachable("V1 function format does not contain a filenames ref");
1306 }
1307
1308 template <llvm::endianness Endian>
1309 StringRef getCoverageMapping(const char *MappingBuf) const {
1310 return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
1311 MappingBuf);
1312 }
1313};
1314
1317
1318#define COVMAP_V2
1319#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1321#undef COVMAP_V2
1323
1324 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1325 return accessors::getFuncHash<ThisT, Endian>(this);
1326 }
1327
1328 template <llvm::endianness Endian> uint64_t getDataSize() const {
1329 return accessors::getDataSize<ThisT, Endian>(this);
1330 }
1331
1332 template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
1333 return accessors::getFuncNameRef<ThisT, Endian>(this);
1334 }
1335
1336 template <llvm::endianness Endian>
1337 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1338 return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
1339 FuncName);
1340 }
1341
1342 template <llvm::endianness Endian>
1343 std::pair<const char *, const ThisT *>
1344 advanceByOne(const char *MappingBuf) const {
1345 return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
1346 }
1347
1348 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1349 llvm_unreachable("V2 function format does not contain a filenames ref");
1350 }
1351
1352 template <llvm::endianness Endian>
1353 StringRef getCoverageMapping(const char *MappingBuf) const {
1354 return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
1355 MappingBuf);
1356 }
1357};
1358
1361
1362#define COVMAP_V3
1363#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1365#undef COVMAP_V3
1367
1368 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1369 return accessors::getFuncHash<ThisT, Endian>(this);
1370 }
1371
1372 template <llvm::endianness Endian> uint64_t getDataSize() const {
1373 return accessors::getDataSize<ThisT, Endian>(this);
1374 }
1375
1376 template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
1377 return accessors::getFuncNameRef<ThisT, Endian>(this);
1378 }
1379
1380 template <llvm::endianness Endian>
1381 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1382 return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
1383 FuncName);
1384 }
1385
1386 /// Get the filename set reference.
1387 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1388 return support::endian::byte_swap<uint64_t, Endian>(FilenamesRef);
1389 }
1390
1391 /// Read the inline coverage mapping. Ignore the buffer parameter, it is for
1392 /// out-of-line coverage mapping data only.
1393 template <llvm::endianness Endian>
1394 StringRef getCoverageMapping(const char *) const {
1395 return StringRef(&CoverageMapping, getDataSize<Endian>());
1396 }
1397
1398 // Advance to the next inline coverage mapping and its associated function
1399 // record. Ignore the out-of-line coverage mapping buffer.
1400 template <llvm::endianness Endian>
1401 std::pair<const char *, const CovMapFunctionRecordV3 *>
1402 advanceByOne(const char *) const {
1403 assert(isAddrAligned(Align(8), this) && "Function record not aligned");
1404 const char *Next = ((const char *)this) + sizeof(CovMapFunctionRecordV3) -
1405 sizeof(char) + getDataSize<Endian>();
1406 // Each function record has an alignment of 8, so we need to adjust
1407 // alignment before reading the next record.
1408 Next += offsetToAlignedAddr(Next, Align(8));
1409 return {nullptr, reinterpret_cast<const CovMapFunctionRecordV3 *>(Next)};
1410 }
1411};
1412
1413// Per module coverage mapping data header, i.e. CoverageMapFileHeader
1414// documented above.
1416#define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
1418 template <llvm::endianness Endian> uint32_t getNRecords() const {
1419 return support::endian::byte_swap<uint32_t, Endian>(NRecords);
1420 }
1421
1422 template <llvm::endianness Endian> uint32_t getFilenamesSize() const {
1423 return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
1424 }
1425
1426 template <llvm::endianness Endian> uint32_t getCoverageSize() const {
1427 return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
1428 }
1429
1430 template <llvm::endianness Endian> uint32_t getVersion() const {
1431 return support::endian::byte_swap<uint32_t, Endian>(Version);
1432 }
1433};
1434
1436
1439 // Function's name reference from CovMapFuncRecord is changed from raw
1440 // name string pointer to MD5 to support name section compression. Name
1441 // section is also compressed.
1443 // A new interpretation of the columnEnd field is added in order to mark
1444 // regions as gap areas.
1446 // Function records are named, uniqued, and moved to a dedicated section.
1448 // Branch regions referring to two counters are added
1450 // Compilation directory is stored separately and combined with relative
1451 // filenames to produce an absolute file path.
1453 // Branch regions extended and Decision Regions added for MC/DC.
1455 // The current version is Version7.
1456 CurrentVersion = INSTR_PROF_COVMAP_VERSION
1458
1459// Correspond to "llvmcovm", in little-endian.
1460constexpr uint64_t TestingFormatMagic = 0x6d766f636d766c6c;
1461
1463 // The first version's number corresponds to the string "testdata" in
1464 // little-endian. This is for a historical reason.
1465 Version1 = 0x6174616474736574,
1466 // Version1 has a defect that it can't store multiple file records. Version2
1467 // fix this problem by adding a new field before the file records section.
1468 Version2 = 1,
1469 // The current testing format version is Version2.
1471};
1472
1473template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
1476};
1477
1478template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version3, IntPtrT> {
1481};
1482
1483template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version2, IntPtrT> {
1486};
1487
1488template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
1491};
1492
1493} // end namespace coverage
1494
1495/// Provide DenseMapInfo for CounterExpression
1496template<> struct DenseMapInfo<coverage::CounterExpression> {
1498 using namespace coverage;
1499
1500 return CounterExpression(CounterExpression::ExprKind::Subtract,
1501 Counter::getCounter(~0U),
1502 Counter::getCounter(~0U));
1503 }
1504
1506 using namespace coverage;
1507
1508 return CounterExpression(CounterExpression::ExprKind::Add,
1509 Counter::getCounter(~0U),
1510 Counter::getCounter(~0U));
1511 }
1512
1513 static unsigned getHashValue(const coverage::CounterExpression &V) {
1514 return static_cast<unsigned>(
1515 hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
1516 V.RHS.getKind(), V.RHS.getCounterID()));
1517 }
1518
1521 return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
1522 }
1523};
1524
1525} // end namespace llvm
1526
1527#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< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define LLVM_ABI
Definition: Compiler.h:213
#define LLVM_PACKED_END
Definition: Compiler.h:532
#define LLVM_PACKED_START
Definition: Compiler.h:531
DXIL Intrinsic Expansion
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
std::string Name
bool End
Definition: ELF_riscv.cpp:480
hexagon bit simplify
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
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:136
iterator begin() const
Definition: ArrayRef.h:135
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:142
ArrayRef< BitWord > getData() const
Definition: BitVector.h:691
void push_back(bool Val)
Definition: BitVector.h:466
size_type size() const
size - Returns the number of bits in this bitvector.
Definition: BitVector.h:159
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:177
iterator end()
Definition: DenseMap.h:87
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.
A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...
Definition: InstrProf.h:506
StringRef getFuncOrVarName(uint64_t ValMD5Hash) const
Return name of functions or global variables from the name's md5 hash value.
Definition: InstrProf.h:778
LLVM_ABI StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize) const
Return function's PGO name from the function name's symbol address in the object file.
size_t size() const
Definition: SmallVector.h:79
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:151
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.
A Counter mapping context is used to connect the counters, expressions and the obtained counter value...
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.
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.
ArrayRef< MCDCRecord > getMCDCRecords() const
MCDC Records that can be further processed.
CoverageData(bool Single, StringRef Filename)
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.
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
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
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.
Compute TestVector Indices "TVIdx" from the Conds graph.
static constexpr auto HardMaxTVs
Hard limit of test vectors.
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.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
constexpr size_t NameSize
Definition: XCOFF.h:30
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.
std::variant< std::monostate, DecisionParameters, BranchParameters > Parameters
The type of MC/DC-specific parameters.
Definition: MCDCTypes.h:57
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)
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
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
@ Offset
Definition: DWP.cpp:477
std::error_code make_error_code(BitcodeError E)
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
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
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:1973
auto make_second_range(ContainerTy &&c)
Given a container of pairs, return a range over the second elements.
Definition: STLExtras.h:1454
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:1886
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:595
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:856
#define N
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:54
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.
CounterMappingRegion(const mcdc::DecisionParameters &MCDCParams, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
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
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
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, BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc)
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_ABI void findIndependencePairs()
std::string getTestVectorString(unsigned TestVectorIndex)
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...
unsigned getNumConditions() const
std::array< BitVector, 2 > BoolVector
const CounterMappingRegion & getDecisionRegion() const
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.