Skip to content

Commit 9f97b0b

Browse files
committed
[Coverage] Rework Decision/Expansion/Branch (llvm#77871)
1 parent 3856fd2 commit 9f97b0b

File tree

1 file changed

+97
-15
lines changed

1 file changed

+97
-15
lines changed

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 97 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/ProfileData/Coverage/CoverageMapping.h"
1515
#include "llvm/ADT/ArrayRef.h"
1616
#include "llvm/ADT/DenseMap.h"
17+
#include "llvm/ADT/STLExtras.h"
1718
#include "llvm/ADT/SmallBitVector.h"
1819
#include "llvm/ADT/SmallVector.h"
1920
#include "llvm/ADT/StringExtras.h"
@@ -582,6 +583,72 @@ static unsigned getMaxBitmapSize(const CounterMappingContext &Ctx,
582583
return MaxBitmapID + (SizeInBits / CHAR_BIT);
583584
}
584585

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+
585652
Error CoverageMapping::loadFunctionRecord(
586653
const CoverageMappingRecord &Record,
587654
IndexedInstrProfReader &ProfileReader) {
@@ -638,18 +705,11 @@ Error CoverageMapping::loadFunctionRecord(
638705
Record.MappingRegions[0].Count.isZero() && Counts[0] > 0)
639706
return Error::success();
640707

641-
unsigned NumConds = 0;
642-
const CounterMappingRegion *MCDCDecision;
643-
std::vector<const CounterMappingRegion *> MCDCBranches;
644-
708+
SmallVector<DecisionRow> Decisions;
645709
FunctionRecord Function(OrigFuncName, Record.Filenames);
646710
for (const auto &Region : Record.MappingRegions) {
647-
// If an MCDCDecisionRegion is seen, track the BranchRegions that follow
648-
// it according to Region.NumConditions.
649711
if (Region.Kind == CounterMappingRegion::MCDCDecisionRegion) {
650-
assert(NumConds == 0);
651-
MCDCDecision = &Region;
652-
NumConds = Region.MCDCParams.NumConditions;
712+
Decisions.emplace_back(Region);
653713
continue;
654714
}
655715
Expected<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
@@ -664,23 +724,39 @@ Error CoverageMapping::loadFunctionRecord(
664724
}
665725
Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount);
666726

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+
667738
// If a MCDCDecisionRegion was seen, store the BranchRegions that
668739
// correspond to it in a vector, according to the number of conditions
669740
// 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];
672743

673744
// As we move through all of the MCDCBranchRegions that follow the
674745
// MCDCDecisionRegion, decrement NumConds to make sure we account for
675746
// 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:
677753
// Evaluating the test vector bitmap for the decision region entails
678754
// calculating precisely what bits are pertinent to this region alone.
679755
// This is calculated based on the recorded offset into the global
680756
// profile bitmap; the length is calculated based on the recorded
681757
// number of conditions.
682758
Expected<BitVector> ExecutedTestVectorBitmap =
683-
Ctx.evaluateBitmap(MCDCDecision);
759+
Ctx.evaluateBitmap(Decision.DecisionRegion);
684760
if (auto E = ExecutedTestVectorBitmap.takeError()) {
685761
consumeError(std::move(E));
686762
return Error::success();
@@ -690,17 +766,23 @@ Error CoverageMapping::loadFunctionRecord(
690766
// DecisionRegion, all of the information is now available to process.
691767
// This is where the bulk of the MC/DC progressing takes place.
692768
Expected<MCDCRecord> Record = Ctx.evaluateMCDCRegion(
693-
*MCDCDecision, *ExecutedTestVectorBitmap, MCDCBranches);
769+
*Decision.DecisionRegion, *ExecutedTestVectorBitmap,
770+
Decision.Branches);
694771
if (auto E = Record.takeError()) {
695772
consumeError(std::move(E));
696773
return Error::success();
697774
}
698775

699776
// Save the MC/DC Record so that it can be visualized later.
700777
Function.pushMCDCRecord(*Record);
701-
MCDCBranches.clear();
778+
779+
Decisions.erase(Decisions.begin() + I);
780+
goto branch_found;
702781
}
703782
}
783+
llvm_unreachable("Branch not found in Decisions");
784+
785+
branch_found:;
704786
}
705787

706788
// Don't create records for (filenames, function) pairs we've already seen.

0 commit comments

Comments
 (0)