14
14
#include " llvm/ProfileData/Coverage/CoverageMapping.h"
15
15
#include " llvm/ADT/ArrayRef.h"
16
16
#include " llvm/ADT/DenseMap.h"
17
+ #include " llvm/ADT/STLExtras.h"
17
18
#include " llvm/ADT/SmallBitVector.h"
18
19
#include " llvm/ADT/SmallVector.h"
19
20
#include " llvm/ADT/StringExtras.h"
@@ -582,6 +583,72 @@ static unsigned getMaxBitmapSize(const CounterMappingContext &Ctx,
582
583
return MaxBitmapID + (SizeInBits / CHAR_BIT);
583
584
}
584
585
586
+ struct DecisionRow {
587
+ const CounterMappingRegion *DecisionRegion;
588
+ LineColPair DecisionStartLoc;
589
+ LineColPair DecisionEndLoc;
590
+
591
+ SmallVector<const CounterMappingRegion *, 6 > Branches;
592
+ DenseSet<CounterMappingRegion::MCDCConditionID> IDs;
593
+ SmallVector<const CounterMappingRegion *> Expansions;
594
+
595
+ DecisionRow (const CounterMappingRegion &Decision)
596
+ : DecisionRegion(&Decision), DecisionStartLoc(Decision.startLoc()),
597
+ DecisionEndLoc (Decision.endLoc()) {}
598
+
599
+ bool insert (const CounterMappingRegion &Branch) {
600
+ auto ID = Branch.MCDCParams .ID ;
601
+ if (ID == 1 )
602
+ Branches.insert (Branches.begin (), &Branch);
603
+ else
604
+ Branches.push_back (&Branch);
605
+ IDs.insert (ID);
606
+ return (Branches.size () == DecisionRegion->MCDCParams .NumConditions );
607
+ }
608
+
609
+ enum class UpdateResult {
610
+ NotFound = 0 ,
611
+ Updated,
612
+ Committed,
613
+ };
614
+
615
+ UpdateResult updateBranch (const CounterMappingRegion &Branch) {
616
+ if (IDs.contains (Branch.MCDCParams .ID ))
617
+ return UpdateResult::NotFound;
618
+
619
+ if (Branch.FileID == DecisionRegion->FileID &&
620
+ Branch.startLoc () >= DecisionStartLoc &&
621
+ Branch.endLoc () <= DecisionEndLoc)
622
+ return (insert (Branch) ? UpdateResult::Committed : UpdateResult::Updated);
623
+
624
+ for (const auto *R : Expansions) {
625
+ if (Branch.FileID == R->ExpandedFileID )
626
+ return (insert (Branch) ? UpdateResult::Committed
627
+ : UpdateResult::Updated);
628
+ }
629
+
630
+ return UpdateResult::NotFound;
631
+ }
632
+
633
+ bool updateExpansion (const CounterMappingRegion &Expansion) {
634
+ if (Expansion.FileID == DecisionRegion->FileID &&
635
+ Expansion.startLoc () >= DecisionStartLoc &&
636
+ Expansion.endLoc () <= DecisionEndLoc) {
637
+ Expansions.push_back (&Expansion);
638
+ return true ;
639
+ }
640
+
641
+ for (const auto *R : Expansions) {
642
+ if (Expansion.FileID == R->ExpandedFileID ) {
643
+ Expansions.push_back (&Expansion);
644
+ return true ;
645
+ }
646
+ }
647
+
648
+ return false ;
649
+ }
650
+ };
651
+
585
652
Error CoverageMapping::loadFunctionRecord (
586
653
const CoverageMappingRecord &Record,
587
654
IndexedInstrProfReader &ProfileReader) {
@@ -638,18 +705,11 @@ Error CoverageMapping::loadFunctionRecord(
638
705
Record.MappingRegions [0 ].Count .isZero () && Counts[0 ] > 0 )
639
706
return Error::success ();
640
707
641
- unsigned NumConds = 0 ;
642
- const CounterMappingRegion *MCDCDecision;
643
- std::vector<const CounterMappingRegion *> MCDCBranches;
644
-
708
+ SmallVector<DecisionRow> Decisions;
645
709
FunctionRecord Function (OrigFuncName, Record.Filenames );
646
710
for (const auto &Region : Record.MappingRegions ) {
647
- // If an MCDCDecisionRegion is seen, track the BranchRegions that follow
648
- // it according to Region.NumConditions.
649
711
if (Region.Kind == CounterMappingRegion::MCDCDecisionRegion) {
650
- assert (NumConds == 0 );
651
- MCDCDecision = &Region;
652
- NumConds = Region.MCDCParams .NumConditions ;
712
+ Decisions.emplace_back (Region);
653
713
continue ;
654
714
}
655
715
Expected<int64_t > ExecutionCount = Ctx.evaluate (Region.Count );
@@ -664,23 +724,39 @@ Error CoverageMapping::loadFunctionRecord(
664
724
}
665
725
Function.pushRegion (Region, *ExecutionCount, *AltExecutionCount);
666
726
727
+ if (Region.Kind == CounterMappingRegion::ExpansionRegion) {
728
+ for (auto &Decision : reverse (Decisions)) {
729
+ if (Decision.updateExpansion (Region))
730
+ break ;
731
+ }
732
+ continue ;
733
+ }
734
+
735
+ if (Region.Kind != CounterMappingRegion::MCDCBranchRegion)
736
+ continue ;
737
+
667
738
// If a MCDCDecisionRegion was seen, store the BranchRegions that
668
739
// correspond to it in a vector, according to the number of conditions
669
740
// recorded for the region (tracked by NumConds).
670
- if (NumConds > 0 && Region. Kind == CounterMappingRegion::MCDCBranchRegion ) {
671
- MCDCBranches. push_back (&Region) ;
741
+ for ( int I = Decisions. size () - 1 ; I >= 0 ; --I ) {
742
+ auto &Decision = Decisions[I] ;
672
743
673
744
// As we move through all of the MCDCBranchRegions that follow the
674
745
// MCDCDecisionRegion, decrement NumConds to make sure we account for
675
746
// them all before we calculate the bitmap of executed test vectors.
676
- if (--NumConds == 0 ) {
747
+ switch (Decision.updateBranch (Region)) {
748
+ case DecisionRow::UpdateResult::NotFound:
749
+ continue ;
750
+ case DecisionRow::UpdateResult::Updated:
751
+ goto branch_found;
752
+ case DecisionRow::UpdateResult::Committed:
677
753
// Evaluating the test vector bitmap for the decision region entails
678
754
// calculating precisely what bits are pertinent to this region alone.
679
755
// This is calculated based on the recorded offset into the global
680
756
// profile bitmap; the length is calculated based on the recorded
681
757
// number of conditions.
682
758
Expected<BitVector> ExecutedTestVectorBitmap =
683
- Ctx.evaluateBitmap (MCDCDecision );
759
+ Ctx.evaluateBitmap (Decision. DecisionRegion );
684
760
if (auto E = ExecutedTestVectorBitmap.takeError ()) {
685
761
consumeError (std::move (E));
686
762
return Error::success ();
@@ -690,17 +766,23 @@ Error CoverageMapping::loadFunctionRecord(
690
766
// DecisionRegion, all of the information is now available to process.
691
767
// This is where the bulk of the MC/DC progressing takes place.
692
768
Expected<MCDCRecord> Record = Ctx.evaluateMCDCRegion (
693
- *MCDCDecision, *ExecutedTestVectorBitmap, MCDCBranches);
769
+ *Decision.DecisionRegion , *ExecutedTestVectorBitmap,
770
+ Decision.Branches );
694
771
if (auto E = Record.takeError ()) {
695
772
consumeError (std::move (E));
696
773
return Error::success ();
697
774
}
698
775
699
776
// Save the MC/DC Record so that it can be visualized later.
700
777
Function.pushMCDCRecord (*Record);
701
- MCDCBranches.clear ();
778
+
779
+ Decisions.erase (Decisions.begin () + I);
780
+ goto branch_found;
702
781
}
703
782
}
783
+ llvm_unreachable (" Branch not found in Decisions" );
784
+
785
+ branch_found:;
704
786
}
705
787
706
788
// Don't create records for (filenames, function) pairs we've already seen.
0 commit comments