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