xref: /llvm-project/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp (revision 0b62218110f0945c6957e549f9fc1a2f2f87a604)
1 //===- CoverageMapping.cpp - Code coverage mapping support ----------------===//
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 // This file contains support for clang's and llvm's instrumentation based
10 // code coverage.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
15 #include "llvm/ADT/ArrayRef.h"
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallBitVector.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/ADT/StringRef.h"
22 #include "llvm/Object/BuildID.h"
23 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h"
24 #include "llvm/ProfileData/InstrProfReader.h"
25 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/Errc.h"
27 #include "llvm/Support/Error.h"
28 #include "llvm/Support/ErrorHandling.h"
29 #include "llvm/Support/MemoryBuffer.h"
30 #include "llvm/Support/VirtualFileSystem.h"
31 #include "llvm/Support/raw_ostream.h"
32 #include <algorithm>
33 #include <cassert>
34 #include <cmath>
35 #include <cstdint>
36 #include <iterator>
37 #include <map>
38 #include <memory>
39 #include <optional>
40 #include <string>
41 #include <system_error>
42 #include <utility>
43 #include <vector>
44 
45 using namespace llvm;
46 using namespace coverage;
47 
48 #define DEBUG_TYPE "coverage-mapping"
49 
50 Counter CounterExpressionBuilder::get(const CounterExpression &E) {
51   auto It = ExpressionIndices.find(E);
52   if (It != ExpressionIndices.end())
53     return Counter::getExpression(It->second);
54   unsigned I = Expressions.size();
55   Expressions.push_back(E);
56   ExpressionIndices[E] = I;
57   return Counter::getExpression(I);
58 }
59 
60 void CounterExpressionBuilder::extractTerms(Counter C, int Factor,
61                                             SmallVectorImpl<Term> &Terms) {
62   switch (C.getKind()) {
63   case Counter::Zero:
64     break;
65   case Counter::CounterValueReference:
66     Terms.emplace_back(C.getCounterID(), Factor);
67     break;
68   case Counter::Expression:
69     const auto &E = Expressions[C.getExpressionID()];
70     extractTerms(E.LHS, Factor, Terms);
71     extractTerms(
72         E.RHS, E.Kind == CounterExpression::Subtract ? -Factor : Factor, Terms);
73     break;
74   }
75 }
76 
77 Counter CounterExpressionBuilder::simplify(Counter ExpressionTree) {
78   // Gather constant terms.
79   SmallVector<Term, 32> Terms;
80   extractTerms(ExpressionTree, +1, Terms);
81 
82   // If there are no terms, this is just a zero. The algorithm below assumes at
83   // least one term.
84   if (Terms.size() == 0)
85     return Counter::getZero();
86 
87   // Group the terms by counter ID.
88   llvm::sort(Terms, [](const Term &LHS, const Term &RHS) {
89     return LHS.CounterID < RHS.CounterID;
90   });
91 
92   // Combine terms by counter ID to eliminate counters that sum to zero.
93   auto Prev = Terms.begin();
94   for (auto I = Prev + 1, E = Terms.end(); I != E; ++I) {
95     if (I->CounterID == Prev->CounterID) {
96       Prev->Factor += I->Factor;
97       continue;
98     }
99     ++Prev;
100     *Prev = *I;
101   }
102   Terms.erase(++Prev, Terms.end());
103 
104   Counter C;
105   // Create additions. We do this before subtractions to avoid constructs like
106   // ((0 - X) + Y), as opposed to (Y - X).
107   for (auto T : Terms) {
108     if (T.Factor <= 0)
109       continue;
110     for (int I = 0; I < T.Factor; ++I)
111       if (C.isZero())
112         C = Counter::getCounter(T.CounterID);
113       else
114         C = get(CounterExpression(CounterExpression::Add, C,
115                                   Counter::getCounter(T.CounterID)));
116   }
117 
118   // Create subtractions.
119   for (auto T : Terms) {
120     if (T.Factor >= 0)
121       continue;
122     for (int I = 0; I < -T.Factor; ++I)
123       C = get(CounterExpression(CounterExpression::Subtract, C,
124                                 Counter::getCounter(T.CounterID)));
125   }
126   return C;
127 }
128 
129 Counter CounterExpressionBuilder::add(Counter LHS, Counter RHS, bool Simplify) {
130   auto Cnt = get(CounterExpression(CounterExpression::Add, LHS, RHS));
131   return Simplify ? simplify(Cnt) : Cnt;
132 }
133 
134 Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS,
135                                            bool Simplify) {
136   auto Cnt = get(CounterExpression(CounterExpression::Subtract, LHS, RHS));
137   return Simplify ? simplify(Cnt) : Cnt;
138 }
139 
140 void CounterMappingContext::dump(const Counter &C, raw_ostream &OS) const {
141   switch (C.getKind()) {
142   case Counter::Zero:
143     OS << '0';
144     return;
145   case Counter::CounterValueReference:
146     OS << '#' << C.getCounterID();
147     break;
148   case Counter::Expression: {
149     if (C.getExpressionID() >= Expressions.size())
150       return;
151     const auto &E = Expressions[C.getExpressionID()];
152     OS << '(';
153     dump(E.LHS, OS);
154     OS << (E.Kind == CounterExpression::Subtract ? " - " : " + ");
155     dump(E.RHS, OS);
156     OS << ')';
157     break;
158   }
159   }
160   if (CounterValues.empty())
161     return;
162   Expected<int64_t> Value = evaluate(C);
163   if (auto E = Value.takeError()) {
164     consumeError(std::move(E));
165     return;
166   }
167   OS << '[' << *Value << ']';
168 }
169 
170 Expected<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
171   struct StackElem {
172     Counter ICounter;
173     int64_t LHS = 0;
174     enum {
175       KNeverVisited = 0,
176       KVisitedOnce = 1,
177       KVisitedTwice = 2,
178     } VisitCount = KNeverVisited;
179   };
180 
181   std::stack<StackElem> CounterStack;
182   CounterStack.push({C});
183 
184   int64_t LastPoppedValue;
185 
186   while (!CounterStack.empty()) {
187     StackElem &Current = CounterStack.top();
188 
189     switch (Current.ICounter.getKind()) {
190     case Counter::Zero:
191       LastPoppedValue = 0;
192       CounterStack.pop();
193       break;
194     case Counter::CounterValueReference:
195       if (Current.ICounter.getCounterID() >= CounterValues.size())
196         return errorCodeToError(errc::argument_out_of_domain);
197       LastPoppedValue = CounterValues[Current.ICounter.getCounterID()];
198       CounterStack.pop();
199       break;
200     case Counter::Expression: {
201       if (Current.ICounter.getExpressionID() >= Expressions.size())
202         return errorCodeToError(errc::argument_out_of_domain);
203       const auto &E = Expressions[Current.ICounter.getExpressionID()];
204       if (Current.VisitCount == StackElem::KNeverVisited) {
205         CounterStack.push(StackElem{E.LHS});
206         Current.VisitCount = StackElem::KVisitedOnce;
207       } else if (Current.VisitCount == StackElem::KVisitedOnce) {
208         Current.LHS = LastPoppedValue;
209         CounterStack.push(StackElem{E.RHS});
210         Current.VisitCount = StackElem::KVisitedTwice;
211       } else {
212         int64_t LHS = Current.LHS;
213         int64_t RHS = LastPoppedValue;
214         LastPoppedValue =
215             E.Kind == CounterExpression::Subtract ? LHS - RHS : LHS + RHS;
216         CounterStack.pop();
217       }
218       break;
219     }
220     }
221   }
222 
223   return LastPoppedValue;
224 }
225 
226 namespace {
227 
228 class MCDCRecordProcessor {
229   /// A bitmap representing the executed test vectors for a boolean expression.
230   /// Each index of the bitmap corresponds to a possible test vector. An index
231   /// with a bit value of '1' indicates that the corresponding Test Vector
232   /// identified by that index was executed.
233   const BitVector &Bitmap;
234 
235   /// Decision Region to which the ExecutedTestVectorBitmap applies.
236   const CounterMappingRegion &Region;
237 
238   /// Array of branch regions corresponding each conditions in the boolean
239   /// expression.
240   ArrayRef<const CounterMappingRegion *> Branches;
241 
242   /// Total number of conditions in the boolean expression.
243   unsigned NumConditions;
244 
245   unsigned BitmapIdx;
246 
247   /// Mapping of a condition ID to its corresponding branch region.
248   llvm::DenseMap<unsigned, const CounterMappingRegion *> Map;
249 
250   /// Vector used to track whether a condition is constant folded.
251   MCDCRecord::BoolVector Folded;
252 
253   /// Mapping of calculated MC/DC Independence Pairs for each condition.
254   MCDCRecord::TVPairMap IndependencePairs;
255 
256   /// Total number of possible Test Vectors for the boolean expression.
257   MCDCRecord::TestVectors TestVectors;
258 
259   /// Actual executed Test Vectors for the boolean expression, based on
260   /// ExecutedTestVectorBitmap.
261   MCDCRecord::TestVectors ExecVectors;
262 
263 public:
264   MCDCRecordProcessor(const BitVector &Bitmap,
265                       const CounterMappingRegion &Region,
266                       ArrayRef<const CounterMappingRegion *> Branches)
267       : Bitmap(Bitmap), Region(Region), Branches(Branches),
268         NumConditions(Region.MCDCParams.NumConditions),
269         BitmapIdx(Region.MCDCParams.BitmapIdx * CHAR_BIT),
270         Folded(NumConditions, false), IndependencePairs(NumConditions),
271         TestVectors((size_t)1 << NumConditions) {}
272 
273 private:
274   void recordTestVector(MCDCRecord::TestVector &TV, unsigned Index,
275                         MCDCRecord::CondState Result) {
276     // Copy the completed test vector to the vector of testvectors.
277     TestVectors[Index] = TV;
278 
279     // The final value (T,F) is equal to the last non-dontcare state on the
280     // path (in a short-circuiting system).
281     TestVectors[Index].push_back(Result);
282   }
283 
284   // Walk the binary decision diagram and try assigning both false and true to
285   // each node. When a terminal node (ID == 0) is reached, fill in the value in
286   // the truth table.
287   void buildTestVector(MCDCRecord::TestVector &TV, unsigned ID,
288                        unsigned Index) {
289     const CounterMappingRegion *Branch = Map[ID];
290 
291     TV[ID - 1] = MCDCRecord::MCDC_False;
292     if (Branch->MCDCParams.FalseID > 0)
293       buildTestVector(TV, Branch->MCDCParams.FalseID, Index);
294     else
295       recordTestVector(TV, Index, MCDCRecord::MCDC_False);
296 
297     Index |= 1 << (ID - 1);
298     TV[ID - 1] = MCDCRecord::MCDC_True;
299     if (Branch->MCDCParams.TrueID > 0)
300       buildTestVector(TV, Branch->MCDCParams.TrueID, Index);
301     else
302       recordTestVector(TV, Index, MCDCRecord::MCDC_True);
303 
304     // Reset back to DontCare.
305     TV[ID - 1] = MCDCRecord::MCDC_DontCare;
306   }
307 
308   /// Walk the bits in the bitmap.  A bit set to '1' indicates that the test
309   /// vector at the corresponding index was executed during a test run.
310   void findExecutedTestVectors() {
311     for (unsigned Idx = 0; Idx < (1u << NumConditions); ++Idx) {
312       assert(BitmapIdx + Idx < Bitmap.size() && "Bitmap overrun");
313       if (Bitmap[BitmapIdx + Idx] == 0)
314         continue;
315       assert(!TestVectors[Idx].empty() && "Test Vector doesn't exist.");
316       ExecVectors.push_back(TestVectors[Idx]);
317     }
318   }
319 
320   // Find an independence pair for each condition:
321   // - The condition is true in one test and false in the other.
322   // - The decision outcome is true one test and false in the other.
323   // - All other conditions' values must be equal or marked as "don't care".
324   void findIndependencePairs() {
325     unsigned NumTVs = ExecVectors.size();
326     for (unsigned I = 1; I < NumTVs; ++I) {
327       const MCDCRecord::TestVector &A = ExecVectors[I];
328       for (unsigned J = 0; J < I; ++J) {
329         const MCDCRecord::TestVector &B = ExecVectors[J];
330         // Enumerate two execution vectors whose outcomes are different.
331         if (A[NumConditions] == B[NumConditions])
332           continue;
333         unsigned Flip = NumConditions, Idx;
334         for (Idx = 0; Idx < NumConditions; ++Idx) {
335           MCDCRecord::CondState ACond = A[Idx], BCond = B[Idx];
336           if (ACond == BCond || ACond == MCDCRecord::MCDC_DontCare ||
337               BCond == MCDCRecord::MCDC_DontCare)
338             continue;
339           if (Flip != NumConditions)
340             break;
341           Flip = Idx;
342         }
343         // If the two vectors differ in exactly one condition, ignoring DontCare
344         // conditions, we have found an independence pair.
345         if (Idx == NumConditions && Flip != NumConditions)
346           IndependencePairs.insert({Flip, std::make_pair(J + 1, I + 1)});
347       }
348     }
349   }
350 
351 public:
352   /// Process the MC/DC Record in order to produce a result for a boolean
353   /// expression. This process includes tracking the conditions that comprise
354   /// the decision region, calculating the list of all possible test vectors,
355   /// marking the executed test vectors, and then finding an Independence Pair
356   /// out of the executed test vectors for each condition in the boolean
357   /// expression. A condition is tracked to ensure that its ID can be mapped to
358   /// its ordinal position in the boolean expression. The condition's source
359   /// location is also tracked, as well as whether it is constant folded (in
360   /// which case it is excuded from the metric).
361   MCDCRecord processMCDCRecord() {
362     unsigned I = 0;
363     MCDCRecord::CondIDMap PosToID;
364     MCDCRecord::LineColPairMap CondLoc;
365 
366     // Walk the Record's BranchRegions (representing Conditions) in order to:
367     // - Hash the condition based on its corresponding ID. This will be used to
368     //   calculate the test vectors.
369     // - Keep a map of the condition's ordinal position (1, 2, 3, 4) to its
370     //   actual ID.  This will be used to visualize the conditions in the
371     //   correct order.
372     // - Keep track of the condition source location. This will be used to
373     //   visualize where the condition is.
374     // - Record whether the condition is constant folded so that we exclude it
375     //   from being measured.
376     for (const auto *B : Branches) {
377       Map[B->MCDCParams.ID] = B;
378       PosToID[I] = B->MCDCParams.ID - 1;
379       CondLoc[I] = B->startLoc();
380       Folded[I++] = (B->Count.isZero() && B->FalseCount.isZero());
381     }
382 
383     // Walk the binary decision diagram to enumerate all possible test vectors.
384     // We start at the root node (ID == 1) with all values being DontCare.
385     // `Index` encodes the bitmask of true values and is initially 0.
386     MCDCRecord::TestVector TV(NumConditions, MCDCRecord::MCDC_DontCare);
387     buildTestVector(TV, 1, 0);
388 
389     // Using Profile Bitmap from runtime, mark the executed test vectors.
390     findExecutedTestVectors();
391 
392     // Compare executed test vectors against each other to find an independence
393     // pairs for each condition.  This processing takes the most time.
394     findIndependencePairs();
395 
396     // Record Test vectors, executed vectors, and independence pairs.
397     MCDCRecord Res(Region, ExecVectors, IndependencePairs, Folded, PosToID,
398                    CondLoc);
399     return Res;
400   }
401 };
402 
403 } // namespace
404 
405 Expected<MCDCRecord> CounterMappingContext::evaluateMCDCRegion(
406     const CounterMappingRegion &Region,
407     ArrayRef<const CounterMappingRegion *> Branches) {
408 
409   MCDCRecordProcessor MCDCProcessor(Bitmap, Region, Branches);
410   return MCDCProcessor.processMCDCRecord();
411 }
412 
413 unsigned CounterMappingContext::getMaxCounterID(const Counter &C) const {
414   struct StackElem {
415     Counter ICounter;
416     int64_t LHS = 0;
417     enum {
418       KNeverVisited = 0,
419       KVisitedOnce = 1,
420       KVisitedTwice = 2,
421     } VisitCount = KNeverVisited;
422   };
423 
424   std::stack<StackElem> CounterStack;
425   CounterStack.push({C});
426 
427   int64_t LastPoppedValue;
428 
429   while (!CounterStack.empty()) {
430     StackElem &Current = CounterStack.top();
431 
432     switch (Current.ICounter.getKind()) {
433     case Counter::Zero:
434       LastPoppedValue = 0;
435       CounterStack.pop();
436       break;
437     case Counter::CounterValueReference:
438       LastPoppedValue = Current.ICounter.getCounterID();
439       CounterStack.pop();
440       break;
441     case Counter::Expression: {
442       if (Current.ICounter.getExpressionID() >= Expressions.size()) {
443         LastPoppedValue = 0;
444         CounterStack.pop();
445       } else {
446         const auto &E = Expressions[Current.ICounter.getExpressionID()];
447         if (Current.VisitCount == StackElem::KNeverVisited) {
448           CounterStack.push(StackElem{E.LHS});
449           Current.VisitCount = StackElem::KVisitedOnce;
450         } else if (Current.VisitCount == StackElem::KVisitedOnce) {
451           Current.LHS = LastPoppedValue;
452           CounterStack.push(StackElem{E.RHS});
453           Current.VisitCount = StackElem::KVisitedTwice;
454         } else {
455           int64_t LHS = Current.LHS;
456           int64_t RHS = LastPoppedValue;
457           LastPoppedValue = std::max(LHS, RHS);
458           CounterStack.pop();
459         }
460       }
461       break;
462     }
463     }
464   }
465 
466   return LastPoppedValue;
467 }
468 
469 void FunctionRecordIterator::skipOtherFiles() {
470   while (Current != Records.end() && !Filename.empty() &&
471          Filename != Current->Filenames[0])
472     ++Current;
473   if (Current == Records.end())
474     *this = FunctionRecordIterator();
475 }
476 
477 ArrayRef<unsigned> CoverageMapping::getImpreciseRecordIndicesForFilename(
478     StringRef Filename) const {
479   size_t FilenameHash = hash_value(Filename);
480   auto RecordIt = FilenameHash2RecordIndices.find(FilenameHash);
481   if (RecordIt == FilenameHash2RecordIndices.end())
482     return {};
483   return RecordIt->second;
484 }
485 
486 static unsigned getMaxCounterID(const CounterMappingContext &Ctx,
487                                 const CoverageMappingRecord &Record) {
488   unsigned MaxCounterID = 0;
489   for (const auto &Region : Record.MappingRegions) {
490     MaxCounterID = std::max(MaxCounterID, Ctx.getMaxCounterID(Region.Count));
491   }
492   return MaxCounterID;
493 }
494 
495 /// Returns the bit count
496 static unsigned getMaxBitmapSize(const CounterMappingContext &Ctx,
497                                  const CoverageMappingRecord &Record) {
498   unsigned MaxBitmapIdx = 0;
499   unsigned NumConditions = 0;
500   // Scan max(BitmapIdx).
501   // Note that `<=` is used insted of `<`, because `BitmapIdx == 0` is valid
502   // and `MaxBitmapIdx is `unsigned`. `BitmapIdx` is unique in the record.
503   for (const auto &Region : reverse(Record.MappingRegions)) {
504     if (Region.Kind == CounterMappingRegion::MCDCDecisionRegion &&
505         MaxBitmapIdx <= Region.MCDCParams.BitmapIdx) {
506       MaxBitmapIdx = Region.MCDCParams.BitmapIdx;
507       NumConditions = Region.MCDCParams.NumConditions;
508     }
509   }
510   unsigned SizeInBits = llvm::alignTo(uint64_t(1) << NumConditions, CHAR_BIT);
511   return MaxBitmapIdx * CHAR_BIT + SizeInBits;
512 }
513 
514 namespace {
515 
516 /// Collect Decisions, Branchs, and Expansions and associate them.
517 class MCDCDecisionRecorder {
518 private:
519   /// This holds the DecisionRegion and MCDCBranches under it.
520   /// Also traverses Expansion(s).
521   /// The Decision has the number of MCDCBranches and will complete
522   /// when it is filled with unique ConditionID of MCDCBranches.
523   struct DecisionRecord {
524     const CounterMappingRegion *DecisionRegion;
525 
526     /// They are reflected from DecisionRegion for convenience.
527     LineColPair DecisionStartLoc;
528     LineColPair DecisionEndLoc;
529 
530     /// This is passed to `MCDCRecordProcessor`, so this should be compatible
531     /// to`ArrayRef<const CounterMappingRegion *>`.
532     SmallVector<const CounterMappingRegion *> MCDCBranches;
533 
534     /// IDs that are stored in MCDCBranches
535     /// Complete when all IDs (1 to NumConditions) are met.
536     DenseSet<CounterMappingRegion::MCDCConditionID> ConditionIDs;
537 
538     /// Set of IDs of Expansion(s) that are relevant to DecisionRegion
539     /// and its children (via expansions).
540     /// FileID  pointed by ExpandedFileID is dedicated to the expansion, so
541     /// the location in the expansion doesn't matter.
542     DenseSet<unsigned> ExpandedFileIDs;
543 
544     DecisionRecord(const CounterMappingRegion &Decision)
545         : DecisionRegion(&Decision), DecisionStartLoc(Decision.startLoc()),
546           DecisionEndLoc(Decision.endLoc()) {
547       assert(Decision.Kind == CounterMappingRegion::MCDCDecisionRegion);
548     }
549 
550     /// Determine whether DecisionRecord dominates `R`.
551     bool dominates(const CounterMappingRegion &R) const {
552       // Determine whether `R` is included in `DecisionRegion`.
553       if (R.FileID == DecisionRegion->FileID &&
554           R.startLoc() >= DecisionStartLoc && R.endLoc() <= DecisionEndLoc)
555         return true;
556 
557       // Determine whether `R` is pointed by any of Expansions.
558       return ExpandedFileIDs.contains(R.FileID);
559     }
560 
561     enum Result {
562       NotProcessed = 0, /// Irrelevant to this Decision
563       Processed,        /// Added to this Decision
564       Completed,        /// Added and filled this Decision
565     };
566 
567     /// Add Branch into the Decision
568     /// \param Branch expects MCDCBranchRegion
569     /// \returns NotProcessed/Processed/Completed
570     Result addBranch(const CounterMappingRegion &Branch) {
571       assert(Branch.Kind == CounterMappingRegion::MCDCBranchRegion);
572 
573       auto ConditionID = Branch.MCDCParams.ID;
574       assert(ConditionID > 0 && "ConditionID should begin with 1");
575 
576       if (ConditionIDs.contains(ConditionID) ||
577           ConditionID > DecisionRegion->MCDCParams.NumConditions)
578         return NotProcessed;
579 
580       if (!this->dominates(Branch))
581         return NotProcessed;
582 
583       assert(MCDCBranches.size() < DecisionRegion->MCDCParams.NumConditions);
584 
585       // Put `ID=1` in front of `MCDCBranches` for convenience
586       // even if `MCDCBranches` is not topological.
587       if (ConditionID == 1)
588         MCDCBranches.insert(MCDCBranches.begin(), &Branch);
589       else
590         MCDCBranches.push_back(&Branch);
591 
592       // Mark `ID` as `assigned`.
593       ConditionIDs.insert(ConditionID);
594 
595       // `Completed` when `MCDCBranches` is full
596       return (MCDCBranches.size() == DecisionRegion->MCDCParams.NumConditions
597                   ? Completed
598                   : Processed);
599     }
600 
601     /// Record Expansion if it is relevant to this Decision.
602     /// Each `Expansion` may nest.
603     /// \returns true if recorded.
604     bool recordExpansion(const CounterMappingRegion &Expansion) {
605       if (!this->dominates(Expansion))
606         return false;
607 
608       ExpandedFileIDs.insert(Expansion.ExpandedFileID);
609       return true;
610     }
611   };
612 
613 private:
614   /// Decisions in progress
615   /// DecisionRecord is added for each MCDCDecisionRegion.
616   /// DecisionRecord is removed when Decision is completed.
617   SmallVector<DecisionRecord> Decisions;
618 
619 public:
620   ~MCDCDecisionRecorder() {
621     assert(Decisions.empty() && "All Decisions have not been resolved");
622   }
623 
624   /// Register Region and start recording.
625   void registerDecision(const CounterMappingRegion &Decision) {
626     Decisions.emplace_back(Decision);
627   }
628 
629   void recordExpansion(const CounterMappingRegion &Expansion) {
630     any_of(Decisions, [&Expansion](auto &Decision) {
631       return Decision.recordExpansion(Expansion);
632     });
633   }
634 
635   using DecisionAndBranches =
636       std::pair<const CounterMappingRegion *,             /// Decision
637                 SmallVector<const CounterMappingRegion *> /// Branches
638                 >;
639 
640   /// Add MCDCBranchRegion to DecisionRecord.
641   /// \param Branch to be processed
642   /// \returns DecisionsAndBranches if DecisionRecord completed.
643   ///     Or returns nullopt.
644   std::optional<DecisionAndBranches>
645   processBranch(const CounterMappingRegion &Branch) {
646     // Seek each Decision and apply Region to it.
647     for (auto DecisionIter = Decisions.begin(), DecisionEnd = Decisions.end();
648          DecisionIter != DecisionEnd; ++DecisionIter)
649       switch (DecisionIter->addBranch(Branch)) {
650       case DecisionRecord::NotProcessed:
651         continue;
652       case DecisionRecord::Processed:
653         return std::nullopt;
654       case DecisionRecord::Completed:
655         DecisionAndBranches Result =
656             std::make_pair(DecisionIter->DecisionRegion,
657                            std::move(DecisionIter->MCDCBranches));
658         Decisions.erase(DecisionIter); // No longer used.
659         return Result;
660       }
661 
662     llvm_unreachable("Branch not found in Decisions");
663   }
664 };
665 
666 } // namespace
667 
668 Error CoverageMapping::loadFunctionRecord(
669     const CoverageMappingRecord &Record,
670     IndexedInstrProfReader &ProfileReader) {
671   StringRef OrigFuncName = Record.FunctionName;
672   if (OrigFuncName.empty())
673     return make_error<CoverageMapError>(coveragemap_error::malformed,
674                                         "record function name is empty");
675 
676   if (Record.Filenames.empty())
677     OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName);
678   else
679     OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
680 
681   CounterMappingContext Ctx(Record.Expressions);
682 
683   std::vector<uint64_t> Counts;
684   if (Error E = ProfileReader.getFunctionCounts(Record.FunctionName,
685                                                 Record.FunctionHash, Counts)) {
686     instrprof_error IPE = std::get<0>(InstrProfError::take(std::move(E)));
687     if (IPE == instrprof_error::hash_mismatch) {
688       FuncHashMismatches.emplace_back(std::string(Record.FunctionName),
689                                       Record.FunctionHash);
690       return Error::success();
691     }
692     if (IPE != instrprof_error::unknown_function)
693       return make_error<InstrProfError>(IPE);
694     Counts.assign(getMaxCounterID(Ctx, Record) + 1, 0);
695   }
696   Ctx.setCounts(Counts);
697 
698   BitVector Bitmap;
699   if (Error E = ProfileReader.getFunctionBitmap(Record.FunctionName,
700                                                 Record.FunctionHash, Bitmap)) {
701     instrprof_error IPE = std::get<0>(InstrProfError::take(std::move(E)));
702     if (IPE == instrprof_error::hash_mismatch) {
703       FuncHashMismatches.emplace_back(std::string(Record.FunctionName),
704                                       Record.FunctionHash);
705       return Error::success();
706     }
707     if (IPE != instrprof_error::unknown_function)
708       return make_error<InstrProfError>(IPE);
709     Bitmap = BitVector(getMaxBitmapSize(Ctx, Record));
710   }
711   Ctx.setBitmap(std::move(Bitmap));
712 
713   assert(!Record.MappingRegions.empty() && "Function has no regions");
714 
715   // This coverage record is a zero region for a function that's unused in
716   // some TU, but used in a different TU. Ignore it. The coverage maps from the
717   // the other TU will either be loaded (providing full region counts) or they
718   // won't (in which case we don't unintuitively report functions as uncovered
719   // when they have non-zero counts in the profile).
720   if (Record.MappingRegions.size() == 1 &&
721       Record.MappingRegions[0].Count.isZero() && Counts[0] > 0)
722     return Error::success();
723 
724   MCDCDecisionRecorder MCDCDecisions;
725   FunctionRecord Function(OrigFuncName, Record.Filenames);
726   for (const auto &Region : Record.MappingRegions) {
727     // MCDCDecisionRegion should be handled first since it overlaps with
728     // others inside.
729     if (Region.Kind == CounterMappingRegion::MCDCDecisionRegion) {
730       MCDCDecisions.registerDecision(Region);
731       continue;
732     }
733     Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
734     if (auto E = ExecutionCount.takeError()) {
735       consumeError(std::move(E));
736       return Error::success();
737     }
738     Expected<int64_t> AltExecutionCount = Ctx.evaluate(Region.FalseCount);
739     if (auto E = AltExecutionCount.takeError()) {
740       consumeError(std::move(E));
741       return Error::success();
742     }
743     Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount);
744 
745     // Record ExpansionRegion.
746     if (Region.Kind == CounterMappingRegion::ExpansionRegion) {
747       MCDCDecisions.recordExpansion(Region);
748       continue;
749     }
750 
751     // Do nothing unless MCDCBranchRegion.
752     if (Region.Kind != CounterMappingRegion::MCDCBranchRegion)
753       continue;
754 
755     auto Result = MCDCDecisions.processBranch(Region);
756     if (!Result) // Any Decision doesn't complete.
757       continue;
758 
759     auto MCDCDecision = Result->first;
760     auto &MCDCBranches = Result->second;
761 
762     // Since the bitmap identifies the executed test vectors for an MC/DC
763     // DecisionRegion, all of the information is now available to process.
764     // This is where the bulk of the MC/DC progressing takes place.
765     Expected<MCDCRecord> Record =
766         Ctx.evaluateMCDCRegion(*MCDCDecision, MCDCBranches);
767     if (auto E = Record.takeError()) {
768       consumeError(std::move(E));
769       return Error::success();
770     }
771 
772     // Save the MC/DC Record so that it can be visualized later.
773     Function.pushMCDCRecord(*Record);
774   }
775 
776   // Don't create records for (filenames, function) pairs we've already seen.
777   auto FilenamesHash = hash_combine_range(Record.Filenames.begin(),
778                                           Record.Filenames.end());
779   if (!RecordProvenance[FilenamesHash].insert(hash_value(OrigFuncName)).second)
780     return Error::success();
781 
782   Functions.push_back(std::move(Function));
783 
784   // Performance optimization: keep track of the indices of the function records
785   // which correspond to each filename. This can be used to substantially speed
786   // up queries for coverage info in a file.
787   unsigned RecordIndex = Functions.size() - 1;
788   for (StringRef Filename : Record.Filenames) {
789     auto &RecordIndices = FilenameHash2RecordIndices[hash_value(Filename)];
790     // Note that there may be duplicates in the filename set for a function
791     // record, because of e.g. macro expansions in the function in which both
792     // the macro and the function are defined in the same file.
793     if (RecordIndices.empty() || RecordIndices.back() != RecordIndex)
794       RecordIndices.push_back(RecordIndex);
795   }
796 
797   return Error::success();
798 }
799 
800 // This function is for memory optimization by shortening the lifetimes
801 // of CoverageMappingReader instances.
802 Error CoverageMapping::loadFromReaders(
803     ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
804     IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage) {
805   for (const auto &CoverageReader : CoverageReaders) {
806     for (auto RecordOrErr : *CoverageReader) {
807       if (Error E = RecordOrErr.takeError())
808         return E;
809       const auto &Record = *RecordOrErr;
810       if (Error E = Coverage.loadFunctionRecord(Record, ProfileReader))
811         return E;
812     }
813   }
814   return Error::success();
815 }
816 
817 Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
818     ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
819     IndexedInstrProfReader &ProfileReader) {
820   auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
821   if (Error E = loadFromReaders(CoverageReaders, ProfileReader, *Coverage))
822     return std::move(E);
823   return std::move(Coverage);
824 }
825 
826 // If E is a no_data_found error, returns success. Otherwise returns E.
827 static Error handleMaybeNoDataFoundError(Error E) {
828   return handleErrors(
829       std::move(E), [](const CoverageMapError &CME) {
830         if (CME.get() == coveragemap_error::no_data_found)
831           return static_cast<Error>(Error::success());
832         return make_error<CoverageMapError>(CME.get(), CME.getMessage());
833       });
834 }
835 
836 Error CoverageMapping::loadFromFile(
837     StringRef Filename, StringRef Arch, StringRef CompilationDir,
838     IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage,
839     bool &DataFound, SmallVectorImpl<object::BuildID> *FoundBinaryIDs) {
840   auto CovMappingBufOrErr = MemoryBuffer::getFileOrSTDIN(
841       Filename, /*IsText=*/false, /*RequiresNullTerminator=*/false);
842   if (std::error_code EC = CovMappingBufOrErr.getError())
843     return createFileError(Filename, errorCodeToError(EC));
844   MemoryBufferRef CovMappingBufRef =
845       CovMappingBufOrErr.get()->getMemBufferRef();
846   SmallVector<std::unique_ptr<MemoryBuffer>, 4> Buffers;
847 
848   SmallVector<object::BuildIDRef> BinaryIDs;
849   auto CoverageReadersOrErr = BinaryCoverageReader::create(
850       CovMappingBufRef, Arch, Buffers, CompilationDir,
851       FoundBinaryIDs ? &BinaryIDs : nullptr);
852   if (Error E = CoverageReadersOrErr.takeError()) {
853     E = handleMaybeNoDataFoundError(std::move(E));
854     if (E)
855       return createFileError(Filename, std::move(E));
856     return E;
857   }
858 
859   SmallVector<std::unique_ptr<CoverageMappingReader>, 4> Readers;
860   for (auto &Reader : CoverageReadersOrErr.get())
861     Readers.push_back(std::move(Reader));
862   if (FoundBinaryIDs && !Readers.empty()) {
863     llvm::append_range(*FoundBinaryIDs,
864                        llvm::map_range(BinaryIDs, [](object::BuildIDRef BID) {
865                          return object::BuildID(BID);
866                        }));
867   }
868   DataFound |= !Readers.empty();
869   if (Error E = loadFromReaders(Readers, ProfileReader, Coverage))
870     return createFileError(Filename, std::move(E));
871   return Error::success();
872 }
873 
874 Expected<std::unique_ptr<CoverageMapping>> CoverageMapping::load(
875     ArrayRef<StringRef> ObjectFilenames, StringRef ProfileFilename,
876     vfs::FileSystem &FS, ArrayRef<StringRef> Arches, StringRef CompilationDir,
877     const object::BuildIDFetcher *BIDFetcher, bool CheckBinaryIDs) {
878   auto ProfileReaderOrErr = IndexedInstrProfReader::create(ProfileFilename, FS);
879   if (Error E = ProfileReaderOrErr.takeError())
880     return createFileError(ProfileFilename, std::move(E));
881   auto ProfileReader = std::move(ProfileReaderOrErr.get());
882   auto Coverage = std::unique_ptr<CoverageMapping>(new CoverageMapping());
883   bool DataFound = false;
884 
885   auto GetArch = [&](size_t Idx) {
886     if (Arches.empty())
887       return StringRef();
888     if (Arches.size() == 1)
889       return Arches.front();
890     return Arches[Idx];
891   };
892 
893   SmallVector<object::BuildID> FoundBinaryIDs;
894   for (const auto &File : llvm::enumerate(ObjectFilenames)) {
895     if (Error E =
896             loadFromFile(File.value(), GetArch(File.index()), CompilationDir,
897                          *ProfileReader, *Coverage, DataFound, &FoundBinaryIDs))
898       return std::move(E);
899   }
900 
901   if (BIDFetcher) {
902     std::vector<object::BuildID> ProfileBinaryIDs;
903     if (Error E = ProfileReader->readBinaryIds(ProfileBinaryIDs))
904       return createFileError(ProfileFilename, std::move(E));
905 
906     SmallVector<object::BuildIDRef> BinaryIDsToFetch;
907     if (!ProfileBinaryIDs.empty()) {
908       const auto &Compare = [](object::BuildIDRef A, object::BuildIDRef B) {
909         return std::lexicographical_compare(A.begin(), A.end(), B.begin(),
910                                             B.end());
911       };
912       llvm::sort(FoundBinaryIDs, Compare);
913       std::set_difference(
914           ProfileBinaryIDs.begin(), ProfileBinaryIDs.end(),
915           FoundBinaryIDs.begin(), FoundBinaryIDs.end(),
916           std::inserter(BinaryIDsToFetch, BinaryIDsToFetch.end()), Compare);
917     }
918 
919     for (object::BuildIDRef BinaryID : BinaryIDsToFetch) {
920       std::optional<std::string> PathOpt = BIDFetcher->fetch(BinaryID);
921       if (PathOpt) {
922         std::string Path = std::move(*PathOpt);
923         StringRef Arch = Arches.size() == 1 ? Arches.front() : StringRef();
924         if (Error E = loadFromFile(Path, Arch, CompilationDir, *ProfileReader,
925                                   *Coverage, DataFound))
926           return std::move(E);
927       } else if (CheckBinaryIDs) {
928         return createFileError(
929             ProfileFilename,
930             createStringError(errc::no_such_file_or_directory,
931                               "Missing binary ID: " +
932                                   llvm::toHex(BinaryID, /*LowerCase=*/true)));
933       }
934     }
935   }
936 
937   if (!DataFound)
938     return createFileError(
939         join(ObjectFilenames.begin(), ObjectFilenames.end(), ", "),
940         make_error<CoverageMapError>(coveragemap_error::no_data_found));
941   return std::move(Coverage);
942 }
943 
944 namespace {
945 
946 /// Distributes functions into instantiation sets.
947 ///
948 /// An instantiation set is a collection of functions that have the same source
949 /// code, ie, template functions specializations.
950 class FunctionInstantiationSetCollector {
951   using MapT = std::map<LineColPair, std::vector<const FunctionRecord *>>;
952   MapT InstantiatedFunctions;
953 
954 public:
955   void insert(const FunctionRecord &Function, unsigned FileID) {
956     auto I = Function.CountedRegions.begin(), E = Function.CountedRegions.end();
957     while (I != E && I->FileID != FileID)
958       ++I;
959     assert(I != E && "function does not cover the given file");
960     auto &Functions = InstantiatedFunctions[I->startLoc()];
961     Functions.push_back(&Function);
962   }
963 
964   MapT::iterator begin() { return InstantiatedFunctions.begin(); }
965   MapT::iterator end() { return InstantiatedFunctions.end(); }
966 };
967 
968 class SegmentBuilder {
969   std::vector<CoverageSegment> &Segments;
970   SmallVector<const CountedRegion *, 8> ActiveRegions;
971 
972   SegmentBuilder(std::vector<CoverageSegment> &Segments) : Segments(Segments) {}
973 
974   /// Emit a segment with the count from \p Region starting at \p StartLoc.
975   //
976   /// \p IsRegionEntry: The segment is at the start of a new non-gap region.
977   /// \p EmitSkippedRegion: The segment must be emitted as a skipped region.
978   void startSegment(const CountedRegion &Region, LineColPair StartLoc,
979                     bool IsRegionEntry, bool EmitSkippedRegion = false) {
980     bool HasCount = !EmitSkippedRegion &&
981                     (Region.Kind != CounterMappingRegion::SkippedRegion);
982 
983     // If the new segment wouldn't affect coverage rendering, skip it.
984     if (!Segments.empty() && !IsRegionEntry && !EmitSkippedRegion) {
985       const auto &Last = Segments.back();
986       if (Last.HasCount == HasCount && Last.Count == Region.ExecutionCount &&
987           !Last.IsRegionEntry)
988         return;
989     }
990 
991     if (HasCount)
992       Segments.emplace_back(StartLoc.first, StartLoc.second,
993                             Region.ExecutionCount, IsRegionEntry,
994                             Region.Kind == CounterMappingRegion::GapRegion);
995     else
996       Segments.emplace_back(StartLoc.first, StartLoc.second, IsRegionEntry);
997 
998     LLVM_DEBUG({
999       const auto &Last = Segments.back();
1000       dbgs() << "Segment at " << Last.Line << ":" << Last.Col
1001              << " (count = " << Last.Count << ")"
1002              << (Last.IsRegionEntry ? ", RegionEntry" : "")
1003              << (!Last.HasCount ? ", Skipped" : "")
1004              << (Last.IsGapRegion ? ", Gap" : "") << "\n";
1005     });
1006   }
1007 
1008   /// Emit segments for active regions which end before \p Loc.
1009   ///
1010   /// \p Loc: The start location of the next region. If std::nullopt, all active
1011   /// regions are completed.
1012   /// \p FirstCompletedRegion: Index of the first completed region.
1013   void completeRegionsUntil(std::optional<LineColPair> Loc,
1014                             unsigned FirstCompletedRegion) {
1015     // Sort the completed regions by end location. This makes it simple to
1016     // emit closing segments in sorted order.
1017     auto CompletedRegionsIt = ActiveRegions.begin() + FirstCompletedRegion;
1018     std::stable_sort(CompletedRegionsIt, ActiveRegions.end(),
1019                       [](const CountedRegion *L, const CountedRegion *R) {
1020                         return L->endLoc() < R->endLoc();
1021                       });
1022 
1023     // Emit segments for all completed regions.
1024     for (unsigned I = FirstCompletedRegion + 1, E = ActiveRegions.size(); I < E;
1025          ++I) {
1026       const auto *CompletedRegion = ActiveRegions[I];
1027       assert((!Loc || CompletedRegion->endLoc() <= *Loc) &&
1028              "Completed region ends after start of new region");
1029 
1030       const auto *PrevCompletedRegion = ActiveRegions[I - 1];
1031       auto CompletedSegmentLoc = PrevCompletedRegion->endLoc();
1032 
1033       // Don't emit any more segments if they start where the new region begins.
1034       if (Loc && CompletedSegmentLoc == *Loc)
1035         break;
1036 
1037       // Don't emit a segment if the next completed region ends at the same
1038       // location as this one.
1039       if (CompletedSegmentLoc == CompletedRegion->endLoc())
1040         continue;
1041 
1042       // Use the count from the last completed region which ends at this loc.
1043       for (unsigned J = I + 1; J < E; ++J)
1044         if (CompletedRegion->endLoc() == ActiveRegions[J]->endLoc())
1045           CompletedRegion = ActiveRegions[J];
1046 
1047       startSegment(*CompletedRegion, CompletedSegmentLoc, false);
1048     }
1049 
1050     auto Last = ActiveRegions.back();
1051     if (FirstCompletedRegion && Last->endLoc() != *Loc) {
1052       // If there's a gap after the end of the last completed region and the
1053       // start of the new region, use the last active region to fill the gap.
1054       startSegment(*ActiveRegions[FirstCompletedRegion - 1], Last->endLoc(),
1055                    false);
1056     } else if (!FirstCompletedRegion && (!Loc || *Loc != Last->endLoc())) {
1057       // Emit a skipped segment if there are no more active regions. This
1058       // ensures that gaps between functions are marked correctly.
1059       startSegment(*Last, Last->endLoc(), false, true);
1060     }
1061 
1062     // Pop the completed regions.
1063     ActiveRegions.erase(CompletedRegionsIt, ActiveRegions.end());
1064   }
1065 
1066   void buildSegmentsImpl(ArrayRef<CountedRegion> Regions) {
1067     for (const auto &CR : enumerate(Regions)) {
1068       auto CurStartLoc = CR.value().startLoc();
1069 
1070       // Active regions which end before the current region need to be popped.
1071       auto CompletedRegions =
1072           std::stable_partition(ActiveRegions.begin(), ActiveRegions.end(),
1073                                 [&](const CountedRegion *Region) {
1074                                   return !(Region->endLoc() <= CurStartLoc);
1075                                 });
1076       if (CompletedRegions != ActiveRegions.end()) {
1077         unsigned FirstCompletedRegion =
1078             std::distance(ActiveRegions.begin(), CompletedRegions);
1079         completeRegionsUntil(CurStartLoc, FirstCompletedRegion);
1080       }
1081 
1082       bool GapRegion = CR.value().Kind == CounterMappingRegion::GapRegion;
1083 
1084       // Try to emit a segment for the current region.
1085       if (CurStartLoc == CR.value().endLoc()) {
1086         // Avoid making zero-length regions active. If it's the last region,
1087         // emit a skipped segment. Otherwise use its predecessor's count.
1088         const bool Skipped =
1089             (CR.index() + 1) == Regions.size() ||
1090             CR.value().Kind == CounterMappingRegion::SkippedRegion;
1091         startSegment(ActiveRegions.empty() ? CR.value() : *ActiveRegions.back(),
1092                      CurStartLoc, !GapRegion, Skipped);
1093         // If it is skipped segment, create a segment with last pushed
1094         // regions's count at CurStartLoc.
1095         if (Skipped && !ActiveRegions.empty())
1096           startSegment(*ActiveRegions.back(), CurStartLoc, false);
1097         continue;
1098       }
1099       if (CR.index() + 1 == Regions.size() ||
1100           CurStartLoc != Regions[CR.index() + 1].startLoc()) {
1101         // Emit a segment if the next region doesn't start at the same location
1102         // as this one.
1103         startSegment(CR.value(), CurStartLoc, !GapRegion);
1104       }
1105 
1106       // This region is active (i.e not completed).
1107       ActiveRegions.push_back(&CR.value());
1108     }
1109 
1110     // Complete any remaining active regions.
1111     if (!ActiveRegions.empty())
1112       completeRegionsUntil(std::nullopt, 0);
1113   }
1114 
1115   /// Sort a nested sequence of regions from a single file.
1116   static void sortNestedRegions(MutableArrayRef<CountedRegion> Regions) {
1117     llvm::sort(Regions, [](const CountedRegion &LHS, const CountedRegion &RHS) {
1118       if (LHS.startLoc() != RHS.startLoc())
1119         return LHS.startLoc() < RHS.startLoc();
1120       if (LHS.endLoc() != RHS.endLoc())
1121         // When LHS completely contains RHS, we sort LHS first.
1122         return RHS.endLoc() < LHS.endLoc();
1123       // If LHS and RHS cover the same area, we need to sort them according
1124       // to their kinds so that the most suitable region will become "active"
1125       // in combineRegions(). Because we accumulate counter values only from
1126       // regions of the same kind as the first region of the area, prefer
1127       // CodeRegion to ExpansionRegion and ExpansionRegion to SkippedRegion.
1128       static_assert(CounterMappingRegion::CodeRegion <
1129                             CounterMappingRegion::ExpansionRegion &&
1130                         CounterMappingRegion::ExpansionRegion <
1131                             CounterMappingRegion::SkippedRegion,
1132                     "Unexpected order of region kind values");
1133       return LHS.Kind < RHS.Kind;
1134     });
1135   }
1136 
1137   /// Combine counts of regions which cover the same area.
1138   static ArrayRef<CountedRegion>
1139   combineRegions(MutableArrayRef<CountedRegion> Regions) {
1140     if (Regions.empty())
1141       return Regions;
1142     auto Active = Regions.begin();
1143     auto End = Regions.end();
1144     for (auto I = Regions.begin() + 1; I != End; ++I) {
1145       if (Active->startLoc() != I->startLoc() ||
1146           Active->endLoc() != I->endLoc()) {
1147         // Shift to the next region.
1148         ++Active;
1149         if (Active != I)
1150           *Active = *I;
1151         continue;
1152       }
1153       // Merge duplicate region.
1154       // If CodeRegions and ExpansionRegions cover the same area, it's probably
1155       // a macro which is fully expanded to another macro. In that case, we need
1156       // to accumulate counts only from CodeRegions, or else the area will be
1157       // counted twice.
1158       // On the other hand, a macro may have a nested macro in its body. If the
1159       // outer macro is used several times, the ExpansionRegion for the nested
1160       // macro will also be added several times. These ExpansionRegions cover
1161       // the same source locations and have to be combined to reach the correct
1162       // value for that area.
1163       // We add counts of the regions of the same kind as the active region
1164       // to handle the both situations.
1165       if (I->Kind == Active->Kind)
1166         Active->ExecutionCount += I->ExecutionCount;
1167     }
1168     return Regions.drop_back(std::distance(++Active, End));
1169   }
1170 
1171 public:
1172   /// Build a sorted list of CoverageSegments from a list of Regions.
1173   static std::vector<CoverageSegment>
1174   buildSegments(MutableArrayRef<CountedRegion> Regions) {
1175     std::vector<CoverageSegment> Segments;
1176     SegmentBuilder Builder(Segments);
1177 
1178     sortNestedRegions(Regions);
1179     ArrayRef<CountedRegion> CombinedRegions = combineRegions(Regions);
1180 
1181     LLVM_DEBUG({
1182       dbgs() << "Combined regions:\n";
1183       for (const auto &CR : CombinedRegions)
1184         dbgs() << "  " << CR.LineStart << ":" << CR.ColumnStart << " -> "
1185                << CR.LineEnd << ":" << CR.ColumnEnd
1186                << " (count=" << CR.ExecutionCount << ")\n";
1187     });
1188 
1189     Builder.buildSegmentsImpl(CombinedRegions);
1190 
1191 #ifndef NDEBUG
1192     for (unsigned I = 1, E = Segments.size(); I < E; ++I) {
1193       const auto &L = Segments[I - 1];
1194       const auto &R = Segments[I];
1195       if (!(L.Line < R.Line) && !(L.Line == R.Line && L.Col < R.Col)) {
1196         if (L.Line == R.Line && L.Col == R.Col && !L.HasCount)
1197           continue;
1198         LLVM_DEBUG(dbgs() << " ! Segment " << L.Line << ":" << L.Col
1199                           << " followed by " << R.Line << ":" << R.Col << "\n");
1200         assert(false && "Coverage segments not unique or sorted");
1201       }
1202     }
1203 #endif
1204 
1205     return Segments;
1206   }
1207 };
1208 
1209 } // end anonymous namespace
1210 
1211 std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const {
1212   std::vector<StringRef> Filenames;
1213   for (const auto &Function : getCoveredFunctions())
1214     llvm::append_range(Filenames, Function.Filenames);
1215   llvm::sort(Filenames);
1216   auto Last = std::unique(Filenames.begin(), Filenames.end());
1217   Filenames.erase(Last, Filenames.end());
1218   return Filenames;
1219 }
1220 
1221 static SmallBitVector gatherFileIDs(StringRef SourceFile,
1222                                     const FunctionRecord &Function) {
1223   SmallBitVector FilenameEquivalence(Function.Filenames.size(), false);
1224   for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I)
1225     if (SourceFile == Function.Filenames[I])
1226       FilenameEquivalence[I] = true;
1227   return FilenameEquivalence;
1228 }
1229 
1230 /// Return the ID of the file where the definition of the function is located.
1231 static std::optional<unsigned>
1232 findMainViewFileID(const FunctionRecord &Function) {
1233   SmallBitVector IsNotExpandedFile(Function.Filenames.size(), true);
1234   for (const auto &CR : Function.CountedRegions)
1235     if (CR.Kind == CounterMappingRegion::ExpansionRegion)
1236       IsNotExpandedFile[CR.ExpandedFileID] = false;
1237   int I = IsNotExpandedFile.find_first();
1238   if (I == -1)
1239     return std::nullopt;
1240   return I;
1241 }
1242 
1243 /// Check if SourceFile is the file that contains the definition of
1244 /// the Function. Return the ID of the file in that case or std::nullopt
1245 /// otherwise.
1246 static std::optional<unsigned>
1247 findMainViewFileID(StringRef SourceFile, const FunctionRecord &Function) {
1248   std::optional<unsigned> I = findMainViewFileID(Function);
1249   if (I && SourceFile == Function.Filenames[*I])
1250     return I;
1251   return std::nullopt;
1252 }
1253 
1254 static bool isExpansion(const CountedRegion &R, unsigned FileID) {
1255   return R.Kind == CounterMappingRegion::ExpansionRegion && R.FileID == FileID;
1256 }
1257 
1258 CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
1259   CoverageData FileCoverage(Filename);
1260   std::vector<CountedRegion> Regions;
1261 
1262   // Look up the function records in the given file. Due to hash collisions on
1263   // the filename, we may get back some records that are not in the file.
1264   ArrayRef<unsigned> RecordIndices =
1265       getImpreciseRecordIndicesForFilename(Filename);
1266   for (unsigned RecordIndex : RecordIndices) {
1267     const FunctionRecord &Function = Functions[RecordIndex];
1268     auto MainFileID = findMainViewFileID(Filename, Function);
1269     auto FileIDs = gatherFileIDs(Filename, Function);
1270     for (const auto &CR : Function.CountedRegions)
1271       if (FileIDs.test(CR.FileID)) {
1272         Regions.push_back(CR);
1273         if (MainFileID && isExpansion(CR, *MainFileID))
1274           FileCoverage.Expansions.emplace_back(CR, Function);
1275       }
1276     // Capture branch regions specific to the function (excluding expansions).
1277     for (const auto &CR : Function.CountedBranchRegions)
1278       if (FileIDs.test(CR.FileID) && (CR.FileID == CR.ExpandedFileID))
1279         FileCoverage.BranchRegions.push_back(CR);
1280     // Capture MCDC records specific to the function.
1281     for (const auto &MR : Function.MCDCRecords)
1282       if (FileIDs.test(MR.getDecisionRegion().FileID))
1283         FileCoverage.MCDCRecords.push_back(MR);
1284   }
1285 
1286   LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n");
1287   FileCoverage.Segments = SegmentBuilder::buildSegments(Regions);
1288 
1289   return FileCoverage;
1290 }
1291 
1292 std::vector<InstantiationGroup>
1293 CoverageMapping::getInstantiationGroups(StringRef Filename) const {
1294   FunctionInstantiationSetCollector InstantiationSetCollector;
1295   // Look up the function records in the given file. Due to hash collisions on
1296   // the filename, we may get back some records that are not in the file.
1297   ArrayRef<unsigned> RecordIndices =
1298       getImpreciseRecordIndicesForFilename(Filename);
1299   for (unsigned RecordIndex : RecordIndices) {
1300     const FunctionRecord &Function = Functions[RecordIndex];
1301     auto MainFileID = findMainViewFileID(Filename, Function);
1302     if (!MainFileID)
1303       continue;
1304     InstantiationSetCollector.insert(Function, *MainFileID);
1305   }
1306 
1307   std::vector<InstantiationGroup> Result;
1308   for (auto &InstantiationSet : InstantiationSetCollector) {
1309     InstantiationGroup IG{InstantiationSet.first.first,
1310                           InstantiationSet.first.second,
1311                           std::move(InstantiationSet.second)};
1312     Result.emplace_back(std::move(IG));
1313   }
1314   return Result;
1315 }
1316 
1317 CoverageData
1318 CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const {
1319   auto MainFileID = findMainViewFileID(Function);
1320   if (!MainFileID)
1321     return CoverageData();
1322 
1323   CoverageData FunctionCoverage(Function.Filenames[*MainFileID]);
1324   std::vector<CountedRegion> Regions;
1325   for (const auto &CR : Function.CountedRegions)
1326     if (CR.FileID == *MainFileID) {
1327       Regions.push_back(CR);
1328       if (isExpansion(CR, *MainFileID))
1329         FunctionCoverage.Expansions.emplace_back(CR, Function);
1330     }
1331   // Capture branch regions specific to the function (excluding expansions).
1332   for (const auto &CR : Function.CountedBranchRegions)
1333     if (CR.FileID == *MainFileID)
1334       FunctionCoverage.BranchRegions.push_back(CR);
1335 
1336   // Capture MCDC records specific to the function.
1337   for (const auto &MR : Function.MCDCRecords)
1338     if (MR.getDecisionRegion().FileID == *MainFileID)
1339       FunctionCoverage.MCDCRecords.push_back(MR);
1340 
1341   LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name
1342                     << "\n");
1343   FunctionCoverage.Segments = SegmentBuilder::buildSegments(Regions);
1344 
1345   return FunctionCoverage;
1346 }
1347 
1348 CoverageData CoverageMapping::getCoverageForExpansion(
1349     const ExpansionRecord &Expansion) const {
1350   CoverageData ExpansionCoverage(
1351       Expansion.Function.Filenames[Expansion.FileID]);
1352   std::vector<CountedRegion> Regions;
1353   for (const auto &CR : Expansion.Function.CountedRegions)
1354     if (CR.FileID == Expansion.FileID) {
1355       Regions.push_back(CR);
1356       if (isExpansion(CR, Expansion.FileID))
1357         ExpansionCoverage.Expansions.emplace_back(CR, Expansion.Function);
1358     }
1359   for (const auto &CR : Expansion.Function.CountedBranchRegions)
1360     // Capture branch regions that only pertain to the corresponding expansion.
1361     if (CR.FileID == Expansion.FileID)
1362       ExpansionCoverage.BranchRegions.push_back(CR);
1363 
1364   LLVM_DEBUG(dbgs() << "Emitting segments for expansion of file "
1365                     << Expansion.FileID << "\n");
1366   ExpansionCoverage.Segments = SegmentBuilder::buildSegments(Regions);
1367 
1368   return ExpansionCoverage;
1369 }
1370 
1371 LineCoverageStats::LineCoverageStats(
1372     ArrayRef<const CoverageSegment *> LineSegments,
1373     const CoverageSegment *WrappedSegment, unsigned Line)
1374     : ExecutionCount(0), HasMultipleRegions(false), Mapped(false), Line(Line),
1375       LineSegments(LineSegments), WrappedSegment(WrappedSegment) {
1376   // Find the minimum number of regions which start in this line.
1377   unsigned MinRegionCount = 0;
1378   auto isStartOfRegion = [](const CoverageSegment *S) {
1379     return !S->IsGapRegion && S->HasCount && S->IsRegionEntry;
1380   };
1381   for (unsigned I = 0; I < LineSegments.size() && MinRegionCount < 2; ++I)
1382     if (isStartOfRegion(LineSegments[I]))
1383       ++MinRegionCount;
1384 
1385   bool StartOfSkippedRegion = !LineSegments.empty() &&
1386                               !LineSegments.front()->HasCount &&
1387                               LineSegments.front()->IsRegionEntry;
1388 
1389   HasMultipleRegions = MinRegionCount > 1;
1390   Mapped =
1391       !StartOfSkippedRegion &&
1392       ((WrappedSegment && WrappedSegment->HasCount) || (MinRegionCount > 0));
1393 
1394   // if there is any starting segment at this line with a counter, it must be
1395   // mapped
1396   Mapped |= std::any_of(
1397       LineSegments.begin(), LineSegments.end(),
1398       [](const auto *Seq) { return Seq->IsRegionEntry && Seq->HasCount; });
1399 
1400   if (!Mapped) {
1401     return;
1402   }
1403 
1404   // Pick the max count from the non-gap, region entry segments and the
1405   // wrapped count.
1406   if (WrappedSegment)
1407     ExecutionCount = WrappedSegment->Count;
1408   if (!MinRegionCount)
1409     return;
1410   for (const auto *LS : LineSegments)
1411     if (isStartOfRegion(LS))
1412       ExecutionCount = std::max(ExecutionCount, LS->Count);
1413 }
1414 
1415 LineCoverageIterator &LineCoverageIterator::operator++() {
1416   if (Next == CD.end()) {
1417     Stats = LineCoverageStats();
1418     Ended = true;
1419     return *this;
1420   }
1421   if (Segments.size())
1422     WrappedSegment = Segments.back();
1423   Segments.clear();
1424   while (Next != CD.end() && Next->Line == Line)
1425     Segments.push_back(&*Next++);
1426   Stats = LineCoverageStats(Segments, WrappedSegment, Line);
1427   ++Line;
1428   return *this;
1429 }
1430 
1431 static std::string getCoverageMapErrString(coveragemap_error Err,
1432                                            const std::string &ErrMsg = "") {
1433   std::string Msg;
1434   raw_string_ostream OS(Msg);
1435 
1436   switch (Err) {
1437   case coveragemap_error::success:
1438     OS << "success";
1439     break;
1440   case coveragemap_error::eof:
1441     OS << "end of File";
1442     break;
1443   case coveragemap_error::no_data_found:
1444     OS << "no coverage data found";
1445     break;
1446   case coveragemap_error::unsupported_version:
1447     OS << "unsupported coverage format version";
1448     break;
1449   case coveragemap_error::truncated:
1450     OS << "truncated coverage data";
1451     break;
1452   case coveragemap_error::malformed:
1453     OS << "malformed coverage data";
1454     break;
1455   case coveragemap_error::decompression_failed:
1456     OS << "failed to decompress coverage data (zlib)";
1457     break;
1458   case coveragemap_error::invalid_or_missing_arch_specifier:
1459     OS << "`-arch` specifier is invalid or missing for universal binary";
1460     break;
1461   }
1462 
1463   // If optional error message is not empty, append it to the message.
1464   if (!ErrMsg.empty())
1465     OS << ": " << ErrMsg;
1466 
1467   return Msg;
1468 }
1469 
1470 namespace {
1471 
1472 // FIXME: This class is only here to support the transition to llvm::Error. It
1473 // will be removed once this transition is complete. Clients should prefer to
1474 // deal with the Error value directly, rather than converting to error_code.
1475 class CoverageMappingErrorCategoryType : public std::error_category {
1476   const char *name() const noexcept override { return "llvm.coveragemap"; }
1477   std::string message(int IE) const override {
1478     return getCoverageMapErrString(static_cast<coveragemap_error>(IE));
1479   }
1480 };
1481 
1482 } // end anonymous namespace
1483 
1484 std::string CoverageMapError::message() const {
1485   return getCoverageMapErrString(Err, Msg);
1486 }
1487 
1488 const std::error_category &llvm::coverage::coveragemap_category() {
1489   static CoverageMappingErrorCategoryType ErrorCategory;
1490   return ErrorCategory;
1491 }
1492 
1493 char CoverageMapError::ID = 0;
1494