@@ -580,6 +580,27 @@ static unsigned getMaxBitmapSize(const CounterMappingContext &Ctx,
580
580
return MaxBitmapID + (SizeInBits / CHAR_BIT);
581
581
}
582
582
583
+ static void
584
+ addMCDCBranches (unsigned FileID, const unsigned NumConds,
585
+ std::vector<CounterMappingRegion> &MCDCBranches,
586
+ const ArrayRef<CounterMappingRegion>::iterator &Begin,
587
+ const ArrayRef<CounterMappingRegion>::iterator &End) {
588
+ // Use the given iterator to scan to the end of the list of regions.
589
+ for (auto It = Begin; It != End; ++It)
590
+ if (It->FileID == FileID && MCDCBranches.size () < NumConds) {
591
+ if (It->Kind == CounterMappingRegion::MCDCBranchRegion)
592
+ // Gather BranchRegions associated within the given FileID until the
593
+ // NumConds limit is reached.
594
+ MCDCBranches.push_back (*It);
595
+ else if (It->Kind == CounterMappingRegion::ExpansionRegion) {
596
+ // If an ExpansionRegion is encountered, recur to check that any
597
+ // BranchRegions associated with the ExpansionRegion are included.
598
+ assert (It->ExpandedFileID > It->FileID );
599
+ addMCDCBranches (It->ExpandedFileID , NumConds, MCDCBranches, It, End);
600
+ }
601
+ }
602
+ }
603
+
583
604
Error CoverageMapping::loadFunctionRecord (
584
605
const CoverageMappingRecord &Record,
585
606
IndexedInstrProfReader &ProfileReader) {
@@ -636,20 +657,56 @@ Error CoverageMapping::loadFunctionRecord(
636
657
Record.MappingRegions [0 ].Count .isZero () && Counts[0 ] > 0 )
637
658
return Error::success ();
638
659
639
- unsigned NumConds = 0 ;
640
- const CounterMappingRegion *MCDCDecision;
641
- std::vector<CounterMappingRegion> MCDCBranches;
642
-
643
660
FunctionRecord Function (OrigFuncName, Record.Filenames );
644
- for (const auto &Region : Record.MappingRegions ) {
661
+
662
+ const auto &RegionsBegin = Record.MappingRegions .begin ();
663
+ const auto &RegionsEnd = Record.MappingRegions .end ();
664
+ for (auto It = RegionsBegin; It != RegionsEnd; ++It) {
665
+ const auto &Region = *It;
666
+
645
667
// If an MCDCDecisionRegion is seen, track the BranchRegions that follow
646
668
// it according to Region.NumConditions.
647
669
if (Region.Kind == CounterMappingRegion::MCDCDecisionRegion) {
648
- assert (NumConds == 0 );
649
- MCDCDecision = &Region;
650
- NumConds = Region.MCDCParams .NumConditions ;
670
+ std::vector<CounterMappingRegion> MCDCBranches;
671
+ const unsigned NumConds = Region.MCDCParams .NumConditions ;
672
+
673
+ // If a MCDCDecisionRegion was seen, use the current iterator to scan
674
+ // ahead to store the BranchRegions that correspond to it in a vector,
675
+ // according to the number of conditions recorded for the region (tracked
676
+ // by NumConds). Note that BranchRegions may be part of ExpansionRegions,
677
+ // which need to be followed recursively.
678
+ addMCDCBranches (It->FileID , NumConds, MCDCBranches, It, RegionsEnd);
679
+
680
+ // All of the corresponding BranchRegions ought to be accounted for.
681
+ assert (MCDCBranches.size () == NumConds);
682
+
683
+ // Evaluating the test vector bitmap for the decision region entails
684
+ // calculating precisely what bits are pertinent to this region alone.
685
+ // This is calculated based on the recorded offset into the global
686
+ // profile bitmap; the length is calculated based on the recorded
687
+ // number of conditions.
688
+ Expected<BitVector> ExecutedTestVectorBitmap =
689
+ Ctx.evaluateBitmap (&Region);
690
+ if (auto E = ExecutedTestVectorBitmap.takeError ()) {
691
+ consumeError (std::move (E));
692
+ return Error::success ();
693
+ }
694
+
695
+ // Since the bitmap identifies the executed test vectors for an MC/DC
696
+ // DecisionRegion, all of the information is now available to process.
697
+ // This is where the bulk of the MC/DC progressing takes place.
698
+ Expected<MCDCRecord> Record = Ctx.evaluateMCDCRegion (
699
+ Region, *ExecutedTestVectorBitmap, MCDCBranches);
700
+ if (auto E = Record.takeError ()) {
701
+ consumeError (std::move (E));
702
+ return Error::success ();
703
+ }
704
+
705
+ // Save the MC/DC Record so that it can be visualized later.
706
+ Function.pushMCDCRecord (*Record);
651
707
continue ;
652
708
}
709
+
653
710
Expected<int64_t > ExecutionCount = Ctx.evaluate (Region.Count );
654
711
if (auto E = ExecutionCount.takeError ()) {
655
712
consumeError (std::move (E));
@@ -661,44 +718,6 @@ Error CoverageMapping::loadFunctionRecord(
661
718
return Error::success ();
662
719
}
663
720
Function.pushRegion (Region, *ExecutionCount, *AltExecutionCount);
664
-
665
- // If a MCDCDecisionRegion was seen, store the BranchRegions that
666
- // correspond to it in a vector, according to the number of conditions
667
- // recorded for the region (tracked by NumConds).
668
- if (NumConds > 0 && Region.Kind == CounterMappingRegion::MCDCBranchRegion) {
669
- MCDCBranches.push_back (Region);
670
-
671
- // As we move through all of the MCDCBranchRegions that follow the
672
- // MCDCDecisionRegion, decrement NumConds to make sure we account for
673
- // them all before we calculate the bitmap of executed test vectors.
674
- if (--NumConds == 0 ) {
675
- // Evaluating the test vector bitmap for the decision region entails
676
- // calculating precisely what bits are pertinent to this region alone.
677
- // This is calculated based on the recorded offset into the global
678
- // profile bitmap; the length is calculated based on the recorded
679
- // number of conditions.
680
- Expected<BitVector> ExecutedTestVectorBitmap =
681
- Ctx.evaluateBitmap (MCDCDecision);
682
- if (auto E = ExecutedTestVectorBitmap.takeError ()) {
683
- consumeError (std::move (E));
684
- return Error::success ();
685
- }
686
-
687
- // Since the bitmap identifies the executed test vectors for an MC/DC
688
- // DecisionRegion, all of the information is now available to process.
689
- // This is where the bulk of the MC/DC progressing takes place.
690
- Expected<MCDCRecord> Record = Ctx.evaluateMCDCRegion (
691
- *MCDCDecision, *ExecutedTestVectorBitmap, MCDCBranches);
692
- if (auto E = Record.takeError ()) {
693
- consumeError (std::move (E));
694
- return Error::success ();
695
- }
696
-
697
- // Save the MC/DC Record so that it can be visualized later.
698
- Function.pushMCDCRecord (*Record);
699
- MCDCBranches.clear ();
700
- }
701
- }
702
721
}
703
722
704
723
// Don't create records for (filenames, function) pairs we've already seen.
0 commit comments