LLVM 20.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 <cassert>
35#include <cstdint>
36#include <iterator>
37#include <map>
38#include <memory>
39#include <optional>
40#include <sstream>
41#include <string>
42#include <system_error>
43#include <utility>
44#include <vector>
45
46namespace llvm {
47
48class IndexedInstrProfReader;
49
50namespace object {
51class BuildIDFetcher;
52} // namespace object
53
54namespace vfs {
55class FileSystem;
56} // namespace vfs
57
58namespace coverage {
59
62
64 success = 0,
65 eof,
72};
73
74const std::error_category &coveragemap_category();
75
76inline std::error_code make_error_code(coveragemap_error E) {
77 return std::error_code(static_cast<int>(E), coveragemap_category());
78}
79
80class CoverageMapError : public ErrorInfo<CoverageMapError> {
81public:
83 : Err(Err), Msg(ErrStr.str()) {
84 assert(Err != coveragemap_error::success && "Not an error");
85 }
86
87 std::string message() const override;
88
89 void log(raw_ostream &OS) const override { OS << message(); }
90
91 std::error_code convertToErrorCode() const override {
92 return make_error_code(Err);
93 }
94
95 coveragemap_error get() const { return Err; }
96 const std::string &getMessage() const { return Msg; }
97
98 static char ID;
99
100private:
102 std::string Msg;
103};
104
105/// A Counter is an abstract value that describes how to compute the
106/// execution count for a region of code using the collected profile count data.
107struct Counter {
108 /// The CounterExpression kind (Add or Subtract) is encoded in bit 0 next to
109 /// the CounterKind. This means CounterKind has to leave bit 0 free.
111 static const unsigned EncodingTagBits = 2;
112 static const unsigned EncodingTagMask = 0x3;
114 EncodingTagBits + 1;
115
116private:
117 CounterKind Kind = Zero;
118 unsigned ID = 0;
119
120 Counter(CounterKind Kind, unsigned ID) : Kind(Kind), ID(ID) {}
121
122public:
123 Counter() = default;
124
125 CounterKind getKind() const { return Kind; }
126
127 bool isZero() const { return Kind == Zero; }
128
129 bool isExpression() const { return Kind == Expression; }
130
131 unsigned getCounterID() const { return ID; }
132
133 unsigned getExpressionID() const { return ID; }
134
135 friend bool operator==(const Counter &LHS, const Counter &RHS) {
136 return LHS.Kind == RHS.Kind && LHS.ID == RHS.ID;
137 }
138
139 friend bool operator!=(const Counter &LHS, const Counter &RHS) {
140 return !(LHS == RHS);
141 }
142
143 friend bool operator<(const Counter &LHS, const Counter &RHS) {
144 return std::tie(LHS.Kind, LHS.ID) < std::tie(RHS.Kind, RHS.ID);
145 }
146
147 /// Return the counter that represents the number zero.
148 static Counter getZero() { return Counter(); }
149
150 /// Return the counter that corresponds to a specific profile counter.
151 static Counter getCounter(unsigned CounterId) {
152 return Counter(CounterValueReference, CounterId);
153 }
154
155 /// Return the counter that corresponds to a specific addition counter
156 /// expression.
157 static Counter getExpression(unsigned ExpressionId) {
158 return Counter(Expression, ExpressionId);
159 }
160};
161
162/// A Counter expression is a value that represents an arithmetic operation
163/// with two counters.
168
170 : Kind(Kind), LHS(LHS), RHS(RHS) {}
171};
172
173/// A Counter expression builder is used to construct the counter expressions.
174/// It avoids unnecessary duplication and simplifies algebraic expressions.
176 /// A list of all the counter expressions
177 std::vector<CounterExpression> Expressions;
178
179 /// A lookup table for the index of a given expression.
181
182 /// Return the counter which corresponds to the given expression.
183 ///
184 /// If the given expression is already stored in the builder, a counter
185 /// that references that expression is returned. Otherwise, the given
186 /// expression is added to the builder's collection of expressions.
187 Counter get(const CounterExpression &E);
188
189 /// Represents a term in a counter expression tree.
190 struct Term {
191 unsigned CounterID;
192 int Factor;
193
194 Term(unsigned CounterID, int Factor)
195 : CounterID(CounterID), Factor(Factor) {}
196 };
197
198 /// Gather the terms of the expression tree for processing.
199 ///
200 /// This collects each addition and subtraction referenced by the counter into
201 /// a sequence that can be sorted and combined to build a simplified counter
202 /// expression.
203 void extractTerms(Counter C, int Sign, SmallVectorImpl<Term> &Terms);
204
205 /// Simplifies the given expression tree
206 /// by getting rid of algebraically redundant operations.
207 Counter simplify(Counter ExpressionTree);
208
209public:
210 ArrayRef<CounterExpression> getExpressions() const { return Expressions; }
211
212 /// Return a counter that represents the expression that adds LHS and RHS.
213 Counter add(Counter LHS, Counter RHS, bool Simplify = true);
214
215 /// Return a counter that represents the expression that subtracts RHS from
216 /// LHS.
217 Counter subtract(Counter LHS, Counter RHS, bool Simplify = true);
218
219 /// K to V map. K will be Counter in most cases. V may be Counter or
220 /// Expression.
221 using SubstMap = std::map<Counter, Counter>;
222
223 /// \return A counter equivalent to \C, with each term in its
224 /// expression replaced with term from \p Map.
225 Counter subst(Counter C, const SubstMap &Map);
226};
227
228using LineColPair = std::pair<unsigned, unsigned>;
229
230/// A Counter mapping region associates a source range with a specific counter.
233 /// A CodeRegion associates some code with a counter
235
236 /// An ExpansionRegion represents a file expansion region that associates
237 /// a source range with the expansion of a virtual source file, such as
238 /// for a macro instantiation or #include file.
240
241 /// A SkippedRegion represents a source range with code that was skipped
242 /// by a preprocessor or similar means.
244
245 /// A GapRegion is like a CodeRegion, but its count is only set as the
246 /// line execution count when its the only region in the line.
248
249 /// A BranchRegion represents leaf-level boolean expressions and is
250 /// associated with two counters, each representing the number of times the
251 /// expression evaluates to true or false.
253
254 /// A DecisionRegion represents a top-level boolean expression and is
255 /// associated with a variable length bitmap index and condition number.
257
258 /// A Branch Region can be extended to include IDs to facilitate MC/DC.
260 };
261
262 /// Primary Counter that is also used for Branch Regions (TrueCount).
264
265 /// Secondary Counter used for Branch Regions (FalseCount).
267
268 /// Parameters used for Modified Condition/Decision Coverage
270
271 const auto &getDecisionParams() const {
272 return mcdc::getParams<const mcdc::DecisionParameters>(MCDCParams);
273 }
274
275 const auto &getBranchParams() const {
276 return mcdc::getParams<const mcdc::BranchParameters>(MCDCParams);
277 }
278
279 unsigned FileID = 0;
280 unsigned ExpandedFileID = 0;
282
284
285 bool isBranch() const {
286 return (Kind == BranchRegion || Kind == MCDCBranchRegion);
287 }
288
290 unsigned LineStart, unsigned ColumnStart,
291 unsigned LineEnd, unsigned ColumnEnd, RegionKind Kind)
295
297 unsigned ExpandedFileID, unsigned LineStart,
298 unsigned ColumnStart, unsigned LineEnd,
299 unsigned ColumnEnd, RegionKind Kind,
300 const mcdc::Parameters &MCDCParams = std::monostate())
304 Kind(Kind) {}
305
307 unsigned FileID, unsigned LineStart,
308 unsigned ColumnStart, unsigned LineEnd,
309 unsigned ColumnEnd, RegionKind Kind)
312 Kind(Kind) {}
313
316 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
319 }
320
322 makeExpansion(unsigned FileID, unsigned ExpandedFileID, unsigned LineStart,
323 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
327 }
328
330 makeSkipped(unsigned FileID, unsigned LineStart, unsigned ColumnStart,
331 unsigned LineEnd, unsigned ColumnEnd) {
334 }
335
338 unsigned ColumnStart, unsigned LineEnd, unsigned ColumnEnd) {
340 LineEnd, (1U << 31) | ColumnEnd, GapRegion);
341 }
342
345 unsigned LineStart, unsigned ColumnStart, unsigned LineEnd,
346 unsigned ColumnEnd,
347 const mcdc::Parameters &MCDCParams = std::monostate()) {
350 ColumnEnd,
351 (std::get_if<mcdc::BranchParameters>(&MCDCParams) ? MCDCBranchRegion
352 : BranchRegion),
353 MCDCParams);
354 }
355
358 unsigned FileID, unsigned LineStart, unsigned ColumnStart,
359 unsigned LineEnd, unsigned ColumnEnd) {
362 }
363
364 inline LineColPair startLoc() const {
366 }
367
368 inline LineColPair endLoc() const { return LineColPair(LineEnd, ColumnEnd); }
369};
370
371/// Associates a source range with an execution count.
377
381
387};
388
389/// MCDC Record grouping all information together.
391 /// CondState represents the evaluation of a condition in an executed test
392 /// vector, which can be True or False. A DontCare is used to mask an
393 /// unevaluatable condition resulting from short-circuit behavior of logical
394 /// operators in languages like C/C++. When comparing the evaluation of a
395 /// condition across executed test vectors, comparisons against a DontCare
396 /// are effectively ignored.
398
399 /// Emulate SmallVector<CondState> with a pair of BitVector.
400 ///
401 /// True False DontCare (Impossible)
402 /// Values: True False False True
403 /// Visited: True True False False
405 BitVector Values; /// True/False (False when DontCare)
406 BitVector Visited; /// ~DontCare
407
408 public:
409 /// Default values are filled with DontCare.
410 TestVector(unsigned N) : Values(N), Visited(N) {}
411
412 /// Emulate RHS SmallVector::operator[]
413 CondState operator[](int I) const {
414 return (Visited[I] ? (Values[I] ? MCDC_True : MCDC_False)
415 : MCDC_DontCare);
416 }
417
418 /// Equivalent to buildTestVector's Index.
419 auto getIndex() const { return Values.getData()[0]; }
420
421 /// Set the condition \p Val at position \p I.
422 /// This emulates LHS SmallVector::operator[].
423 void set(int I, CondState Val) {
424 Visited[I] = (Val != MCDC_DontCare);
425 Values[I] = (Val == MCDC_True);
426 }
427
428 /// Emulate SmallVector::push_back.
430 Visited.push_back(Val != MCDC_DontCare);
431 Values.push_back(Val == MCDC_True);
432 assert(Values.size() == Visited.size());
433 }
434
435 /// For each element:
436 /// - False if either is DontCare
437 /// - False if both have the same value
438 /// - True if both have the opposite value
439 /// ((A.Values ^ B.Values) & A.Visited & B.Visited)
440 /// Dedicated to findIndependencePairs().
441 auto getDifferences(const TestVector &B) const {
442 const auto &A = *this;
443 BitVector AB = A.Values;
444 AB ^= B.Values;
445 AB &= A.Visited;
446 AB &= B.Visited;
447 return AB;
448 }
449 };
450
452 using BoolVector = std::array<BitVector, 2>;
453 using TVRowPair = std::pair<unsigned, unsigned>;
457
458private:
460 TestVectors TV;
461 std::optional<TVPairMap> IndependencePairs;
462 BoolVector Folded;
463 CondIDMap PosToID;
464 LineColPairMap CondLoc;
465
466public:
468 BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc)
469 : Region(Region), TV(std::move(TV)), Folded(std::move(Folded)),
470 PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) {
472 }
473
474 // Compare executed test vectors against each other to find an independence
475 // pairs for each condition. This processing takes the most time.
477
479 unsigned getNumConditions() const {
480 return Region.getDecisionParams().NumConditions;
481 }
482 unsigned getNumTestVectors() const { return TV.size(); }
483 bool isCondFolded(unsigned Condition) const {
484 return Folded[false][Condition] || Folded[true][Condition];
485 }
486
487 /// Return the evaluation of a condition (indicated by Condition) in an
488 /// executed test vector (indicated by TestVectorIndex), which will be True,
489 /// False, or DontCare if the condition is unevaluatable. Because condition
490 /// IDs are not associated based on their position in the expression,
491 /// accessing conditions in the TestVectors requires a translation from a
492 /// ordinal position to actual condition ID. This is done via PosToID[].
493 CondState getTVCondition(unsigned TestVectorIndex, unsigned Condition) {
494 return TV[TestVectorIndex].first[PosToID[Condition]];
495 }
496
497 /// Return the Result evaluation for an executed test vector.
498 /// See MCDCRecordProcessor::RecordTestVector().
499 CondState getTVResult(unsigned TestVectorIndex) {
500 return TV[TestVectorIndex].second;
501 }
502
503 /// Determine whether a given condition (indicated by Condition) is covered
504 /// by an Independence Pair. Because condition IDs are not associated based
505 /// on their position in the expression, accessing conditions in the
506 /// TestVectors requires a translation from a ordinal position to actual
507 /// condition ID. This is done via PosToID[].
508 bool isConditionIndependencePairCovered(unsigned Condition) const {
509 assert(IndependencePairs);
510 auto It = PosToID.find(Condition);
511 assert(It != PosToID.end() && "Condition ID without an Ordinal mapping");
512 return IndependencePairs->contains(It->second);
513 }
514
515 /// Return the Independence Pair that covers the given condition. Because
516 /// condition IDs are not associated based on their position in the
517 /// expression, accessing conditions in the TestVectors requires a
518 /// translation from a ordinal position to actual condition ID. This is done
519 /// via PosToID[].
522 assert(IndependencePairs);
523 return (*IndependencePairs)[PosToID[Condition]];
524 }
525
526 float getPercentCovered() const {
527 unsigned Folded = 0;
528 unsigned Covered = 0;
529 for (unsigned C = 0; C < getNumConditions(); C++) {
530 if (isCondFolded(C))
531 Folded++;
533 Covered++;
534 }
535
536 unsigned Total = getNumConditions() - Folded;
537 if (Total == 0)
538 return 0.0;
539 return (static_cast<double>(Covered) / static_cast<double>(Total)) * 100.0;
540 }
541
542 std::string getConditionHeaderString(unsigned Condition) {
543 std::ostringstream OS;
544 OS << "Condition C" << Condition + 1 << " --> (";
545 OS << CondLoc[Condition].first << ":" << CondLoc[Condition].second;
546 OS << ")\n";
547 return OS.str();
548 }
549
550 std::string getTestVectorHeaderString() const {
551 std::ostringstream OS;
552 if (getNumTestVectors() == 0) {
553 OS << "None.\n";
554 return OS.str();
555 }
556 const auto NumConditions = getNumConditions();
557 for (unsigned I = 0; I < NumConditions; I++) {
558 OS << "C" << I + 1;
559 if (I != NumConditions - 1)
560 OS << ", ";
561 }
562 OS << " Result\n";
563 return OS.str();
564 }
565
566 std::string getTestVectorString(unsigned TestVectorIndex) {
567 assert(TestVectorIndex < getNumTestVectors() &&
568 "TestVector index out of bounds!");
569 std::ostringstream OS;
570 const auto NumConditions = getNumConditions();
571 // Add individual condition values to the string.
572 OS << " " << TestVectorIndex + 1 << " { ";
573 for (unsigned Condition = 0; Condition < NumConditions; Condition++) {
574 if (isCondFolded(Condition))
575 OS << "C";
576 else {
577 switch (getTVCondition(TestVectorIndex, Condition)) {
579 OS << "-";
580 break;
582 OS << "T";
583 break;
585 OS << "F";
586 break;
587 }
588 }
589 if (Condition != NumConditions - 1)
590 OS << ", ";
591 }
592
593 // Add result value to the string.
594 OS << " = ";
595 if (getTVResult(TestVectorIndex) == MCDC_True)
596 OS << "T";
597 else
598 OS << "F";
599 OS << " }\n";
600
601 return OS.str();
602 }
603
604 std::string getConditionCoverageString(unsigned Condition) {
605 assert(Condition < getNumConditions() &&
606 "Condition index is out of bounds!");
607 std::ostringstream OS;
608
609 OS << " C" << Condition + 1 << "-Pair: ";
610 if (isCondFolded(Condition)) {
611 OS << "constant folded\n";
612 } else if (isConditionIndependencePairCovered(Condition)) {
613 TVRowPair rows = getConditionIndependencePair(Condition);
614 OS << "covered: (" << rows.first << ",";
615 OS << rows.second << ")\n";
616 } else
617 OS << "not covered\n";
618
619 return OS.str();
620 }
621};
622
623namespace mcdc {
624/// Compute TestVector Indices "TVIdx" from the Conds graph.
625///
626/// Clang CodeGen handles the bitmap index based on TVIdx.
627/// llvm-cov reconstructs conditions from TVIdx.
628///
629/// For each leaf "The final decision",
630/// - TVIdx should be unique.
631/// - TVIdx has the Width.
632/// - The width represents the number of possible paths.
633/// - The minimum width is 1 "deterministic".
634/// - The order of leaves are sorted by Width DESC. It expects
635/// latter TVIdx(s) (with Width=1) could be pruned and altered to
636/// other simple branch conditions.
637///
639public:
640 struct MCDCNode {
641 int InCount = 0; /// Reference count; temporary use
642 int Width; /// Number of accumulated paths (>= 1)
644 };
645
646#ifndef NDEBUG
647 /// This is no longer needed after the assignment.
648 /// It may be used in assert() for reconfirmation.
650#endif
651
652 /// Output: Index for TestVectors bitmap (These are not CondIDs)
654
655 /// Output: The number of test vectors.
656 /// Error with HardMaxTVs if the number has exploded.
658
659 /// Hard limit of test vectors
660 static constexpr auto HardMaxTVs =
661 std::numeric_limits<decltype(NumTestVectors)>::max();
662
663public:
664 /// Calculate and assign Indices
665 /// \param NextIDs The list of {FalseID, TrueID} indexed by ID
666 /// The first element [0] should be the root node.
667 /// \param Offset Offset of index to final decisions.
668 TVIdxBuilder(const SmallVectorImpl<ConditionIDs> &NextIDs, int Offset = 0);
669};
670} // namespace mcdc
671
672/// A Counter mapping context is used to connect the counters, expressions
673/// and the obtained counter values.
675 ArrayRef<CounterExpression> Expressions;
676 ArrayRef<uint64_t> CounterValues;
677 BitVector Bitmap;
678
679public:
681 ArrayRef<uint64_t> CounterValues = {})
682 : Expressions(Expressions), CounterValues(CounterValues) {}
683
684 void setCounts(ArrayRef<uint64_t> Counts) { CounterValues = Counts; }
685 void setBitmap(BitVector &&Bitmap_) { Bitmap = std::move(Bitmap_); }
686
687 void dump(const Counter &C, raw_ostream &OS) const;
688 void dump(const Counter &C) const { dump(C, dbgs()); }
689
690 /// Return the number of times that a region of code associated with this
691 /// counter was executed.
692 Expected<int64_t> evaluate(const Counter &C) const;
693
694 /// Return an MCDC record that indicates executed test vectors and condition
695 /// pairs.
699 bool IsVersion11);
700
701 unsigned getMaxCounterID(const Counter &C) const;
702};
703
704/// Code coverage information for a single function.
706 /// Raw function name.
707 std::string Name;
708 /// Mapping from FileID (i.e. vector index) to filename. Used to support
709 /// macro expansions within a function in which the macro and function are
710 /// defined in separate files.
711 ///
712 /// TODO: Uniquing filenames across all function records may be a performance
713 /// optimization.
714 std::vector<std::string> Filenames;
715 /// Regions in the function along with their counts.
716 std::vector<CountedRegion> CountedRegions;
717 /// Branch Regions in the function along with their counts.
718 std::vector<CountedRegion> CountedBranchRegions;
719 /// MCDC Records record a DecisionRegion and associated BranchRegions.
720 std::vector<MCDCRecord> MCDCRecords;
721 /// The number of times this function was executed.
723
725 : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
726
729
731 MCDCRecords.push_back(std::move(Record));
732 }
733
735 uint64_t FalseCount) {
736 if (Region.isBranch()) {
737 CountedBranchRegions.emplace_back(Region, Count, FalseCount);
738 // If either counter is hard-coded to zero, then this region represents a
739 // constant-folded branch.
740 CountedBranchRegions.back().TrueFolded = Region.Count.isZero();
741 CountedBranchRegions.back().FalseFolded = Region.FalseCount.isZero();
742 return;
743 }
744 if (CountedRegions.empty())
745 ExecutionCount = Count;
746 CountedRegions.emplace_back(Region, Count, FalseCount);
747 }
748};
749
750/// Iterator over Functions, optionally filtered to a single file.
752 : public iterator_facade_base<FunctionRecordIterator,
753 std::forward_iterator_tag, FunctionRecord> {
756 StringRef Filename;
757
758 /// Skip records whose primary file is not \c Filename.
759 void skipOtherFiles();
760
761public:
763 StringRef Filename = "")
764 : Records(Records_), Current(Records.begin()), Filename(Filename) {
765 skipOtherFiles();
766 }
767
768 FunctionRecordIterator() : Current(Records.begin()) {}
769
771 return Current == RHS.Current && Filename == RHS.Filename;
772 }
773
774 const FunctionRecord &operator*() const { return *Current; }
775
777 assert(Current != Records.end() && "incremented past end");
778 ++Current;
779 skipOtherFiles();
780 return *this;
781 }
782};
783
784/// Coverage information for a macro expansion or #included file.
785///
786/// When covered code has pieces that can be expanded for more detail, such as a
787/// preprocessor macro use and its definition, these are represented as
788/// expansions whose coverage can be looked up independently.
790 /// The abstract file this expansion covers.
791 unsigned FileID;
792 /// The region that expands to this record.
794 /// Coverage for the expansion.
796
799 : FileID(Region.ExpandedFileID), Region(Region), Function(Function) {}
800};
801
802/// The execution count information starting at a point in a file.
803///
804/// A sequence of CoverageSegments gives execution counts for a file in format
805/// that's simple to iterate through for processing.
807 /// The line where this segment begins.
808 unsigned Line;
809 /// The column where this segment begins.
810 unsigned Col;
811 /// The execution count, or zero if no count was recorded.
813 /// When false, the segment was uninstrumented or skipped.
815 /// Whether this enters a new region or returns to a previous count.
817 /// Whether this enters a gap region.
819
820 CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
821 : Line(Line), Col(Col), Count(0), HasCount(false),
823
824 CoverageSegment(unsigned Line, unsigned Col, uint64_t Count,
825 bool IsRegionEntry, bool IsGapRegion = false,
826 bool IsBranchRegion = false)
829
830 friend bool operator==(const CoverageSegment &L, const CoverageSegment &R) {
831 return std::tie(L.Line, L.Col, L.Count, L.HasCount, L.IsRegionEntry,
832 L.IsGapRegion) == std::tie(R.Line, R.Col, R.Count,
833 R.HasCount, R.IsRegionEntry,
834 R.IsGapRegion);
835 }
836};
837
838/// An instantiation group contains a \c FunctionRecord list, such that each
839/// record corresponds to a distinct instantiation of the same function.
840///
841/// Note that it's possible for a function to have more than one instantiation
842/// (consider C++ template specializations or static inline functions).
844 friend class CoverageMapping;
845
846 unsigned Line;
847 unsigned Col;
848 std::vector<const FunctionRecord *> Instantiations;
849
850 InstantiationGroup(unsigned Line, unsigned Col,
851 std::vector<const FunctionRecord *> Instantiations)
852 : Line(Line), Col(Col), Instantiations(std::move(Instantiations)) {}
853
854public:
857
858 /// Get the number of instantiations in this group.
859 size_t size() const { return Instantiations.size(); }
860
861 /// Get the line where the common function was defined.
862 unsigned getLine() const { return Line; }
863
864 /// Get the column where the common function was defined.
865 unsigned getColumn() const { return Col; }
866
867 /// Check if the instantiations in this group have a common mangled name.
868 bool hasName() const {
869 for (unsigned I = 1, E = Instantiations.size(); I < E; ++I)
870 if (Instantiations[I]->Name != Instantiations[0]->Name)
871 return false;
872 return true;
873 }
874
875 /// Get the common mangled name for instantiations in this group.
877 assert(hasName() && "Instantiations don't have a shared name");
878 return Instantiations[0]->Name;
879 }
880
881 /// Get the total execution count of all instantiations in this group.
883 uint64_t Count = 0;
884 for (const FunctionRecord *F : Instantiations)
885 Count += F->ExecutionCount;
886 return Count;
887 }
888
889 /// Get the instantiations in this group.
891 return Instantiations;
892 }
893};
894
895/// Coverage information to be processed or displayed.
896///
897/// This represents the coverage of an entire file, expansion, or function. It
898/// provides a sequence of CoverageSegments to iterate through, as well as the
899/// list of expansions that can be further processed.
901 friend class CoverageMapping;
902
903 std::string Filename;
904 std::vector<CoverageSegment> Segments;
905 std::vector<ExpansionRecord> Expansions;
906 std::vector<CountedRegion> BranchRegions;
907 std::vector<MCDCRecord> MCDCRecords;
908
909 bool SingleByteCoverage = false;
910
911public:
912 CoverageData() = default;
913
914 CoverageData(bool Single, StringRef Filename)
915 : Filename(Filename), SingleByteCoverage(Single) {}
916
917 /// Get the name of the file this data covers.
918 StringRef getFilename() const { return Filename; }
919
921
922 /// Get an iterator over the coverage segments for this object. The segments
923 /// are guaranteed to be uniqued and sorted by location.
924 std::vector<CoverageSegment>::const_iterator begin() const {
925 return Segments.begin();
926 }
927
928 std::vector<CoverageSegment>::const_iterator end() const {
929 return Segments.end();
930 }
931
932 bool empty() const { return Segments.empty(); }
933
934 /// Expansions that can be further processed.
935 ArrayRef<ExpansionRecord> getExpansions() const { return Expansions; }
936
937 /// Branches that can be further processed.
938 ArrayRef<CountedRegion> getBranches() const { return BranchRegions; }
939
940 /// MCDC Records that can be further processed.
941 ArrayRef<MCDCRecord> getMCDCRecords() const { return MCDCRecords; }
942};
943
944/// The mapping of profile information to coverage data.
945///
946/// This is the main interface to get coverage information, using a profile to
947/// fill out execution counts.
949 DenseMap<size_t, DenseSet<size_t>> RecordProvenance;
950 std::vector<FunctionRecord> Functions;
951 DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices;
952 std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
953
954 std::optional<bool> SingleByteCoverage;
955
956 CoverageMapping() = default;
957
958 // Load coverage records from readers.
959 static Error loadFromReaders(
960 ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
961 IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage);
962
963 // Load coverage records from file.
964 static Error
965 loadFromFile(StringRef Filename, StringRef Arch, StringRef CompilationDir,
966 IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
967 bool &DataFound,
968 SmallVectorImpl<object::BuildID> *FoundBinaryIDs = nullptr);
969
970 /// Add a function record corresponding to \p Record.
971 Error loadFunctionRecord(const CoverageMappingRecord &Record,
972 IndexedInstrProfReader &ProfileReader);
973
974 /// Look up the indices for function records which are at least partially
975 /// defined in the specified file. This is guaranteed to return a superset of
976 /// such records: extra records not in the file may be included if there is
977 /// a hash collision on the filename. Clients must be robust to collisions.
979 getImpreciseRecordIndicesForFilename(StringRef Filename) const;
980
981public:
984
985 /// Load the coverage mapping using the given readers.
987 load(ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
988 IndexedInstrProfReader &ProfileReader);
989
990 /// Load the coverage mapping from the given object files and profile. If
991 /// \p Arches is non-empty, it must specify an architecture for each object.
992 /// Ignores non-instrumented object files unless all are not instrumented.
994 load(ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
995 vfs::FileSystem &FS, ArrayRef<StringRef> Arches = {},
996 StringRef CompilationDir = "",
997 const object::BuildIDFetcher *BIDFetcher = nullptr,
998 bool CheckBinaryIDs = false);
999
1000 /// The number of functions that couldn't have their profiles mapped.
1001 ///
1002 /// This is a count of functions whose profile is out of date or otherwise
1003 /// can't be associated with any coverage information.
1004 unsigned getMismatchedCount() const { return FuncHashMismatches.size(); }
1005
1006 /// A hash mismatch occurs when a profile record for a symbol does not have
1007 /// the same hash as a coverage mapping record for the same symbol. This
1008 /// returns a list of hash mismatches, where each mismatch is a pair of the
1009 /// symbol name and its coverage mapping hash.
1011 return FuncHashMismatches;
1012 }
1013
1014 /// Returns a lexicographically sorted, unique list of files that are
1015 /// covered.
1016 std::vector<StringRef> getUniqueSourceFiles() const;
1017
1018 /// Get the coverage for a particular file.
1019 ///
1020 /// The given filename must be the name as recorded in the coverage
1021 /// information. That is, only names returned from getUniqueSourceFiles will
1022 /// yield a result.
1024
1025 /// Get the coverage for a particular function.
1027
1028 /// Get the coverage for an expansion within a coverage set.
1030
1031 /// Gets all of the functions covered by this profile.
1033 return make_range(FunctionRecordIterator(Functions),
1035 }
1036
1037 /// Gets all of the functions in a particular file.
1040 return make_range(FunctionRecordIterator(Functions, Filename),
1042 }
1043
1044 /// Get the list of function instantiation groups in a particular file.
1045 ///
1046 /// Every instantiation group in a program is attributed to exactly one file:
1047 /// the file in which the definition for the common function begins.
1048 std::vector<InstantiationGroup>
1049 getInstantiationGroups(StringRef Filename) const;
1050};
1051
1052/// Coverage statistics for a single line.
1054 uint64_t ExecutionCount;
1055 bool HasMultipleRegions;
1056 bool Mapped;
1057 unsigned Line;
1059 const CoverageSegment *WrappedSegment;
1060
1062 LineCoverageStats() = default;
1063
1064public:
1066 const CoverageSegment *WrappedSegment, unsigned Line);
1067
1068 uint64_t getExecutionCount() const { return ExecutionCount; }
1069
1070 bool hasMultipleRegions() const { return HasMultipleRegions; }
1071
1072 bool isMapped() const { return Mapped; }
1073
1074 unsigned getLine() const { return Line; }
1075
1077 return LineSegments;
1078 }
1079
1080 const CoverageSegment *getWrappedSegment() const { return WrappedSegment; }
1081};
1082
1083/// An iterator over the \c LineCoverageStats objects for lines described by
1084/// a \c CoverageData instance.
1086 : public iterator_facade_base<LineCoverageIterator,
1087 std::forward_iterator_tag,
1088 const LineCoverageStats> {
1089public:
1091 : LineCoverageIterator(CD, CD.begin()->Line) {}
1092
1093 LineCoverageIterator(const CoverageData &CD, unsigned Line)
1094 : CD(CD), WrappedSegment(nullptr), Next(CD.begin()), Ended(false),
1095 Line(Line) {
1096 this->operator++();
1097 }
1098
1099 bool operator==(const LineCoverageIterator &R) const {
1100 return &CD == &R.CD && Next == R.Next && Ended == R.Ended;
1101 }
1102
1103 const LineCoverageStats &operator*() const { return Stats; }
1104
1106
1108 auto EndIt = *this;
1109 EndIt.Next = CD.end();
1110 EndIt.Ended = true;
1111 return EndIt;
1112 }
1113
1114private:
1115 const CoverageData &CD;
1116 const CoverageSegment *WrappedSegment;
1117 std::vector<CoverageSegment>::const_iterator Next;
1118 bool Ended;
1119 unsigned Line;
1121 LineCoverageStats Stats;
1122};
1123
1124/// Get a \c LineCoverageIterator range for the lines described by \p CD.
1127 auto Begin = LineCoverageIterator(CD);
1128 auto End = Begin.getEnd();
1129 return make_range(Begin, End);
1130}
1131
1132// Coverage mappping data (V2) has the following layout:
1133// IPSK_covmap:
1134// [CoverageMapFileHeader]
1135// [ArrayStart]
1136// [CovMapFunctionRecordV2]
1137// [CovMapFunctionRecordV2]
1138// ...
1139// [ArrayEnd]
1140// [Encoded Filenames and Region Mapping Data]
1141//
1142// Coverage mappping data (V3) has the following layout:
1143// IPSK_covmap:
1144// [CoverageMapFileHeader]
1145// [Encoded Filenames]
1146// IPSK_covfun:
1147// [ArrayStart]
1148// odr_name_1: [CovMapFunctionRecordV3]
1149// odr_name_2: [CovMapFunctionRecordV3]
1150// ...
1151// [ArrayEnd]
1152//
1153// Both versions of the coverage mapping format encode the same information,
1154// but the V3 format does so more compactly by taking advantage of linkonce_odr
1155// semantics (it allows exactly 1 function record per name reference).
1156
1157/// This namespace defines accessors shared by different versions of coverage
1158/// mapping records.
1159namespace accessors {
1160
1161/// Return the structural hash associated with the function.
1162template <class FuncRecordTy, llvm::endianness Endian>
1163uint64_t getFuncHash(const FuncRecordTy *Record) {
1164 return support::endian::byte_swap<uint64_t, Endian>(Record->FuncHash);
1165}
1166
1167/// Return the coverage map data size for the function.
1168template <class FuncRecordTy, llvm::endianness Endian>
1169uint64_t getDataSize(const FuncRecordTy *Record) {
1170 return support::endian::byte_swap<uint32_t, Endian>(Record->DataSize);
1171}
1172
1173/// Return the function lookup key. The value is considered opaque.
1174template <class FuncRecordTy, llvm::endianness Endian>
1175uint64_t getFuncNameRef(const FuncRecordTy *Record) {
1176 return support::endian::byte_swap<uint64_t, Endian>(Record->NameRef);
1177}
1178
1179/// Return the PGO name of the function. Used for formats in which the name is
1180/// a hash.
1181template <class FuncRecordTy, llvm::endianness Endian>
1182Error getFuncNameViaRef(const FuncRecordTy *Record,
1183 InstrProfSymtab &ProfileNames, StringRef &FuncName) {
1184 uint64_t NameRef = getFuncNameRef<FuncRecordTy, Endian>(Record);
1185 FuncName = ProfileNames.getFuncOrVarName(NameRef);
1186 return Error::success();
1187}
1188
1189/// Read coverage mapping out-of-line, from \p MappingBuf. This is used when the
1190/// coverage mapping is attached to the file header, instead of to the function
1191/// record.
1192template <class FuncRecordTy, llvm::endianness Endian>
1194 const char *MappingBuf) {
1195 return {MappingBuf, size_t(getDataSize<FuncRecordTy, Endian>(Record))};
1196}
1197
1198/// Advance to the next out-of-line coverage mapping and its associated
1199/// function record.
1200template <class FuncRecordTy, llvm::endianness Endian>
1201std::pair<const char *, const FuncRecordTy *>
1202advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf) {
1203 return {MappingBuf + getDataSize<FuncRecordTy, Endian>(Record), Record + 1};
1204}
1205
1206} // end namespace accessors
1207
1209template <class IntPtrT>
1212
1213#define COVMAP_V1
1214#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1216#undef COVMAP_V1
1218
1219 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1220 return accessors::getFuncHash<ThisT, Endian>(this);
1221 }
1222
1223 template <llvm::endianness Endian> uint64_t getDataSize() const {
1224 return accessors::getDataSize<ThisT, Endian>(this);
1225 }
1226
1227 /// Return function lookup key. The value is consider opaque.
1228 template <llvm::endianness Endian> IntPtrT getFuncNameRef() const {
1229 return support::endian::byte_swap<IntPtrT, Endian>(NamePtr);
1230 }
1231
1232 /// Return the PGO name of the function.
1233 template <llvm::endianness Endian>
1234 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1235 IntPtrT NameRef = getFuncNameRef<Endian>();
1236 uint32_t NameS = support::endian::byte_swap<uint32_t, Endian>(NameSize);
1237 FuncName = ProfileNames.getFuncName(NameRef, NameS);
1238 if (NameS && FuncName.empty())
1239 return make_error<CoverageMapError>(coveragemap_error::malformed,
1240 "function name is empty");
1241 return Error::success();
1242 }
1243
1244 template <llvm::endianness Endian>
1245 std::pair<const char *, const ThisT *>
1246 advanceByOne(const char *MappingBuf) const {
1247 return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
1248 }
1249
1250 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1251 llvm_unreachable("V1 function format does not contain a filenames ref");
1252 }
1253
1254 template <llvm::endianness Endian>
1255 StringRef getCoverageMapping(const char *MappingBuf) const {
1256 return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
1257 MappingBuf);
1258 }
1259};
1260
1263
1264#define COVMAP_V2
1265#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1267#undef COVMAP_V2
1269
1270 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1271 return accessors::getFuncHash<ThisT, Endian>(this);
1272 }
1273
1274 template <llvm::endianness Endian> uint64_t getDataSize() const {
1275 return accessors::getDataSize<ThisT, Endian>(this);
1276 }
1277
1278 template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
1279 return accessors::getFuncNameRef<ThisT, Endian>(this);
1280 }
1281
1282 template <llvm::endianness Endian>
1283 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1284 return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
1285 FuncName);
1286 }
1287
1288 template <llvm::endianness Endian>
1289 std::pair<const char *, const ThisT *>
1290 advanceByOne(const char *MappingBuf) const {
1291 return accessors::advanceByOneOutOfLine<ThisT, Endian>(this, MappingBuf);
1292 }
1293
1294 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1295 llvm_unreachable("V2 function format does not contain a filenames ref");
1296 }
1297
1298 template <llvm::endianness Endian>
1299 StringRef getCoverageMapping(const char *MappingBuf) const {
1300 return accessors::getCoverageMappingOutOfLine<ThisT, Endian>(this,
1301 MappingBuf);
1302 }
1303};
1304
1307
1308#define COVMAP_V3
1309#define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Type Name;
1311#undef COVMAP_V3
1313
1314 template <llvm::endianness Endian> uint64_t getFuncHash() const {
1315 return accessors::getFuncHash<ThisT, Endian>(this);
1316 }
1317
1318 template <llvm::endianness Endian> uint64_t getDataSize() const {
1319 return accessors::getDataSize<ThisT, Endian>(this);
1320 }
1321
1322 template <llvm::endianness Endian> uint64_t getFuncNameRef() const {
1323 return accessors::getFuncNameRef<ThisT, Endian>(this);
1324 }
1325
1326 template <llvm::endianness Endian>
1327 Error getFuncName(InstrProfSymtab &ProfileNames, StringRef &FuncName) const {
1328 return accessors::getFuncNameViaRef<ThisT, Endian>(this, ProfileNames,
1329 FuncName);
1330 }
1331
1332 /// Get the filename set reference.
1333 template <llvm::endianness Endian> uint64_t getFilenamesRef() const {
1334 return support::endian::byte_swap<uint64_t, Endian>(FilenamesRef);
1335 }
1336
1337 /// Read the inline coverage mapping. Ignore the buffer parameter, it is for
1338 /// out-of-line coverage mapping data only.
1339 template <llvm::endianness Endian>
1340 StringRef getCoverageMapping(const char *) const {
1341 return StringRef(&CoverageMapping, getDataSize<Endian>());
1342 }
1343
1344 // Advance to the next inline coverage mapping and its associated function
1345 // record. Ignore the out-of-line coverage mapping buffer.
1346 template <llvm::endianness Endian>
1347 std::pair<const char *, const CovMapFunctionRecordV3 *>
1348 advanceByOne(const char *) const {
1349 assert(isAddrAligned(Align(8), this) && "Function record not aligned");
1350 const char *Next = ((const char *)this) + sizeof(CovMapFunctionRecordV3) -
1351 sizeof(char) + getDataSize<Endian>();
1352 // Each function record has an alignment of 8, so we need to adjust
1353 // alignment before reading the next record.
1354 Next += offsetToAlignedAddr(Next, Align(8));
1355 return {nullptr, reinterpret_cast<const CovMapFunctionRecordV3 *>(Next)};
1356 }
1357};
1358
1359// Per module coverage mapping data header, i.e. CoverageMapFileHeader
1360// documented above.
1362#define COVMAP_HEADER(Type, LLVMType, Name, Init) Type Name;
1364 template <llvm::endianness Endian> uint32_t getNRecords() const {
1365 return support::endian::byte_swap<uint32_t, Endian>(NRecords);
1366 }
1367
1368 template <llvm::endianness Endian> uint32_t getFilenamesSize() const {
1369 return support::endian::byte_swap<uint32_t, Endian>(FilenamesSize);
1370 }
1371
1372 template <llvm::endianness Endian> uint32_t getCoverageSize() const {
1373 return support::endian::byte_swap<uint32_t, Endian>(CoverageSize);
1374 }
1375
1376 template <llvm::endianness Endian> uint32_t getVersion() const {
1377 return support::endian::byte_swap<uint32_t, Endian>(Version);
1378 }
1379};
1380
1382
1385 // Function's name reference from CovMapFuncRecord is changed from raw
1386 // name string pointer to MD5 to support name section compression. Name
1387 // section is also compressed.
1389 // A new interpretation of the columnEnd field is added in order to mark
1390 // regions as gap areas.
1392 // Function records are named, uniqued, and moved to a dedicated section.
1394 // Branch regions referring to two counters are added
1396 // Compilation directory is stored separately and combined with relative
1397 // filenames to produce an absolute file path.
1399 // Branch regions extended and Decision Regions added for MC/DC.
1401 // The current version is Version7.
1402 CurrentVersion = INSTR_PROF_COVMAP_VERSION
1404
1405// Correspond to "llvmcovm", in little-endian.
1406constexpr uint64_t TestingFormatMagic = 0x6d766f636d766c6c;
1407
1409 // The first version's number corresponds to the string "testdata" in
1410 // little-endian. This is for a historical reason.
1411 Version1 = 0x6174616474736574,
1412 // Version1 has a defect that it can't store multiple file records. Version2
1413 // fix this problem by adding a new field before the file records section.
1414 Version2 = 1,
1415 // The current testing format version is Version2.
1417};
1418
1419template <int CovMapVersion, class IntPtrT> struct CovMapTraits {
1422};
1423
1424template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version3, IntPtrT> {
1427};
1428
1429template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version2, IntPtrT> {
1432};
1433
1434template <class IntPtrT> struct CovMapTraits<CovMapVersion::Version1, IntPtrT> {
1437};
1438
1439} // end namespace coverage
1440
1441/// Provide DenseMapInfo for CounterExpression
1442template<> struct DenseMapInfo<coverage::CounterExpression> {
1444 using namespace coverage;
1445
1446 return CounterExpression(CounterExpression::ExprKind::Subtract,
1447 Counter::getCounter(~0U),
1448 Counter::getCounter(~0U));
1449 }
1450
1452 using namespace coverage;
1453
1454 return CounterExpression(CounterExpression::ExprKind::Add,
1455 Counter::getCounter(~0U),
1456 Counter::getCounter(~0U));
1457 }
1458
1459 static unsigned getHashValue(const coverage::CounterExpression &V) {
1460 return static_cast<unsigned>(
1461 hash_combine(V.Kind, V.LHS.getKind(), V.LHS.getCounterID(),
1462 V.RHS.getKind(), V.RHS.getCounterID()));
1463 }
1464
1467 return LHS.Kind == RHS.Kind && LHS.LHS == RHS.LHS && LHS.RHS == RHS.RHS;
1468 }
1469};
1470
1471} // end namespace llvm
1472
1473#endif // LLVM_PROFILEDATA_COVERAGE_COVERAGEMAPPING_H
AMDGPU Mark last scratch load
basic Basic Alias true
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_PACKED_END
Definition: Compiler.h:516
#define LLVM_PACKED_START
Definition: Compiler.h:515
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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
Value * RHS
Value * LHS
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
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:156
iterator end()
Definition: DenseMap.h:84
Base class for user error types.
Definition: Error.h:355
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:337
Tagged union holding either a T or a Error.
Definition: Error.h:481
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:460
StringRef getFuncOrVarName(uint64_t ValMD5Hash)
Return name of functions or global variables from the name's md5 hash value.
Definition: InstrProf.h:720
StringRef getFuncName(uint64_t FuncNameAddress, size_t NameSize)
Return function's PGO name from the function name's symbol address in the object file.
size_t size() const
Definition: SmallVector.h:78
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:573
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:51
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
A Counter expression builder is used to construct the counter expressions.
ArrayRef< CounterExpression > getExpressions() const
Counter subtract(Counter LHS, Counter RHS, bool Simplify=true)
Return a counter that represents the expression that subtracts RHS from LHS.
Counter add(Counter LHS, Counter RHS, bool Simplify=true)
Return a counter that represents the expression that adds LHS and RHS.
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...
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
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_)
unsigned getMaxCounterID(const Counter &C) const
CounterMappingContext(ArrayRef< CounterExpression > Expressions, ArrayRef< uint64_t > CounterValues={})
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)
std::string message() const override
Return the error message as a string.
CoverageMapError(coveragemap_error Err, const Twine &ErrStr=Twine())
void log(raw_ostream &OS) const override
Print an error message to an output stream.
coveragemap_error get() const
std::error_code convertToErrorCode() const override
Convert this error to a std::error_code.
const std::string & getMessage() const
The mapping of profile information to coverage data.
unsigned getMismatchedCount() const
The number of functions that couldn't have their profiles mapped.
std::vector< StringRef > getUniqueSourceFiles() const
Returns a lexicographically sorted, unique list of files that are covered.
CoverageData getCoverageForExpansion(const ExpansionRecord &Expansion) const
Get the coverage for an expansion within a coverage set.
ArrayRef< std::pair< std::string, uint64_t > > getHashMismatches() const
A hash mismatch occurs when a profile record for a symbol does not have the same hash as a coverage m...
iterator_range< FunctionRecordIterator > getCoveredFunctions(StringRef Filename) const
Gets all of the functions in a particular file.
iterator_range< FunctionRecordIterator > getCoveredFunctions() const
Gets all of the functions covered by this profile.
CoverageData getCoverageForFunction(const FunctionRecord &Function) const
Get the coverage for a particular function.
CoverageMapping(const CoverageMapping &)=delete
std::vector< InstantiationGroup > getInstantiationGroups(StringRef Filename) const
Get the list of function instantiation groups in a particular file.
CoverageData getCoverageForFile(StringRef Filename) const
Get the coverage for a particular file.
CoverageMapping & operator=(const CoverageMapping &)=delete
Iterator over Functions, optionally filtered to a single file.
FunctionRecordIterator & operator++()
bool operator==(const FunctionRecordIterator &RHS) const
const FunctionRecord & operator*() const
FunctionRecordIterator(ArrayRef< FunctionRecord > Records_, StringRef Filename="")
An instantiation group contains a FunctionRecord list, such that each record corresponds to a distinc...
InstantiationGroup(const InstantiationGroup &)=delete
unsigned getLine() const
Get the line where the common function was defined.
unsigned getColumn() const
Get the column where the common function was defined.
bool hasName() const
Check if the instantiations in this group have a common mangled name.
size_t size() const
Get the number of instantiations in this group.
ArrayRef< const FunctionRecord * > getInstantiations() const
Get the instantiations in this group.
uint64_t getTotalExecutionCount() const
Get the total execution count of all instantiations in this group.
InstantiationGroup(InstantiationGroup &&)=default
StringRef getName() const
Get the common mangled name for instantiations in this group.
An iterator over the LineCoverageStats objects for lines described by a CoverageData instance.
LineCoverageIterator(const CoverageData &CD)
const LineCoverageStats & operator*() const
bool operator==(const LineCoverageIterator &R) const
LineCoverageIterator getEnd() const
LineCoverageIterator(const CoverageData &CD, unsigned Line)
Coverage statistics for a single line.
const CoverageSegment * getWrappedSegment() const
ArrayRef< const CoverageSegment * > getLineSegments() const
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:39
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
The virtual file system interface.
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
constexpr size_t NameSize
Definition: XCOFF.h:29
uint64_t getFuncNameRef(const FuncRecordTy *Record)
Return the function lookup key. The value is considered opaque.
StringRef getCoverageMappingOutOfLine(const FuncRecordTy *Record, const char *MappingBuf)
Read coverage mapping out-of-line, from MappingBuf.
uint64_t getDataSize(const FuncRecordTy *Record)
Return the coverage map data size for the function.
Error getFuncNameViaRef(const FuncRecordTy *Record, InstrProfSymtab &ProfileNames, StringRef &FuncName)
Return the PGO name of the function.
std::pair< const char *, const FuncRecordTy * > advanceByOneOutOfLine(const FuncRecordTy *Record, const char *MappingBuf)
Advance to the next out-of-line coverage mapping and its associated function record.
uint64_t getFuncHash(const FuncRecordTy *Record)
Return the structural hash associated with the function.
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:25
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:480
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
uint64_t offsetToAlignedAddr(const void *Addr, Align Alignment)
Returns the necessary adjustment for aligning Addr to Alignment bytes, rounding up.
Definition: Alignment.h:203
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1873
hash_code hash_combine(const Ts &...args)
Combine values into a single hash_code.
Definition: Hashing.h:590
bool isAddrAligned(Align Lhs, const void *Addr)
Checks that Addr is a multiple of the alignment.
Definition: Alignment.h:150
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:858
#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:52
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::string getConditionHeaderString(unsigned Condition)
unsigned getNumTestVectors() const
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.