aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/ProfileData/Coverage/CoverageMapping.cpp')
-rw-r--r--llvm/lib/ProfileData/Coverage/CoverageMapping.cpp107
1 files changed, 54 insertions, 53 deletions
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index aa361af..6d6678e 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -246,6 +246,40 @@ Expected<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
return LastPoppedValue;
}
+// Find an independence pair for each condition:
+// - The condition is true in one test and false in the other.
+// - The decision outcome is true one test and false in the other.
+// - All other conditions' values must be equal or marked as "don't care".
+void MCDCRecord::findIndependencePairs() {
+ if (IndependencePairs)
+ return;
+
+ IndependencePairs.emplace();
+
+ unsigned NumTVs = TV.size();
+ // Will be replaced to shorter expr.
+ unsigned TVTrueIdx = std::distance(
+ TV.begin(),
+ std::find_if(TV.begin(), TV.end(),
+ [&](auto I) { return (I.second == MCDCRecord::MCDC_True); })
+
+ );
+ for (unsigned I = TVTrueIdx; I < NumTVs; ++I) {
+ const auto &[A, ACond] = TV[I];
+ assert(ACond == MCDCRecord::MCDC_True);
+ for (unsigned J = 0; J < TVTrueIdx; ++J) {
+ const auto &[B, BCond] = TV[J];
+ assert(BCond == MCDCRecord::MCDC_False);
+ // If the two vectors differ in exactly one condition, ignoring DontCare
+ // conditions, we have found an independence pair.
+ auto AB = A.getDifferences(B);
+ if (AB.count() == 1)
+ IndependencePairs->insert(
+ {AB.find_first(), std::make_pair(J + 1, I + 1)});
+ }
+ }
+}
+
mcdc::TVIdxBuilder::TVIdxBuilder(const SmallVectorImpl<ConditionIDs> &NextIDs,
int Offset)
: Indices(NextIDs.size()) {
@@ -400,9 +434,6 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
/// ExecutedTestVectorBitmap.
MCDCRecord::TestVectors &ExecVectors;
- /// Number of False items in ExecVectors
- unsigned NumExecVectorsF;
-
#ifndef NDEBUG
DenseSet<unsigned> TVIdxs;
#endif
@@ -417,8 +448,9 @@ public:
: NextIDsBuilder(Branches), TVIdxBuilder(this->NextIDs), Bitmap(Bitmap),
Region(Region), DecisionParams(Region.getDecisionParams()),
Branches(Branches), NumConditions(DecisionParams.NumConditions),
- Folded(NumConditions, false), IndependencePairs(NumConditions),
- ExecVectors(ExecVectorsByCond[false]), IsVersion11(IsVersion11) {}
+ Folded{{BitVector(NumConditions), BitVector(NumConditions)}},
+ IndependencePairs(NumConditions), ExecVectors(ExecVectorsByCond[false]),
+ IsVersion11(IsVersion11) {}
private:
// Walk the binary decision diagram and try assigning both false and true to
@@ -471,34 +503,11 @@ private:
// Fill ExecVectors order by False items and True items.
// ExecVectors is the alias of ExecVectorsByCond[false], so
// Append ExecVectorsByCond[true] on it.
- NumExecVectorsF = ExecVectors.size();
auto &ExecVectorsT = ExecVectorsByCond[true];
ExecVectors.append(std::make_move_iterator(ExecVectorsT.begin()),
std::make_move_iterator(ExecVectorsT.end()));
}
- // Find an independence pair for each condition:
- // - The condition is true in one test and false in the other.
- // - The decision outcome is true one test and false in the other.
- // - All other conditions' values must be equal or marked as "don't care".
- void findIndependencePairs() {
- unsigned NumTVs = ExecVectors.size();
- for (unsigned I = NumExecVectorsF; I < NumTVs; ++I) {
- const auto &[A, ACond] = ExecVectors[I];
- assert(ACond == MCDCRecord::MCDC_True);
- for (unsigned J = 0; J < NumExecVectorsF; ++J) {
- const auto &[B, BCond] = ExecVectors[J];
- assert(BCond == MCDCRecord::MCDC_False);
- // If the two vectors differ in exactly one condition, ignoring DontCare
- // conditions, we have found an independence pair.
- auto AB = A.getDifferences(B);
- if (AB.count() == 1)
- IndependencePairs.insert(
- {AB.find_first(), std::make_pair(J + 1, I + 1)});
- }
- }
- }
-
public:
/// Process the MC/DC Record in order to produce a result for a boolean
/// expression. This process includes tracking the conditions that comprise
@@ -510,7 +519,6 @@ public:
/// location is also tracked, as well as whether it is constant folded (in
/// which case it is excuded from the metric).
MCDCRecord processMCDCRecord() {
- unsigned I = 0;
MCDCRecord::CondIDMap PosToID;
MCDCRecord::LineColPairMap CondLoc;
@@ -524,23 +532,19 @@ public:
// visualize where the condition is.
// - Record whether the condition is constant folded so that we exclude it
// from being measured.
- for (const auto *B : Branches) {
+ for (auto [I, B] : enumerate(Branches)) {
const auto &BranchParams = B->getBranchParams();
PosToID[I] = BranchParams.ID;
CondLoc[I] = B->startLoc();
- Folded[I++] = (B->Count.isZero() || B->FalseCount.isZero());
+ Folded[false][I] = B->FalseCount.isZero();
+ Folded[true][I] = B->Count.isZero();
}
// Using Profile Bitmap from runtime, mark the executed test vectors.
findExecutedTestVectors();
- // Compare executed test vectors against each other to find an independence
- // pairs for each condition. This processing takes the most time.
- findIndependencePairs();
-
// Record Test vectors, executed vectors, and independence pairs.
- return MCDCRecord(Region, std::move(ExecVectors),
- std::move(IndependencePairs), std::move(Folded),
+ return MCDCRecord(Region, std::move(ExecVectors), std::move(Folded),
std::move(PosToID), std::move(CondLoc));
}
};
@@ -830,7 +834,6 @@ Error CoverageMapping::loadFunctionRecord(
else
OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
- bool SingleByteCoverage = ProfileReader.hasSingleByteCoverage();
CounterMappingContext Ctx(Record.Expressions);
std::vector<uint64_t> Counts;
@@ -896,10 +899,7 @@ Error CoverageMapping::loadFunctionRecord(
consumeError(std::move(E));
return Error::success();
}
- Function.pushRegion(
- Region, (SingleByteCoverage && *ExecutionCount ? 1 : *ExecutionCount),
- (SingleByteCoverage && *AltExecutionCount ? 1 : *AltExecutionCount),
- SingleByteCoverage);
+ Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount);
// Record ExpansionRegion.
if (Region.Kind == CounterMappingRegion::ExpansionRegion) {
@@ -961,6 +961,9 @@ Error CoverageMapping::loadFunctionRecord(
Error CoverageMapping::loadFromReaders(
ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage) {
+ assert(!Coverage.SingleByteCoverage ||
+ *Coverage.SingleByteCoverage == ProfileReader.hasSingleByteCoverage());
+ Coverage.SingleByteCoverage = ProfileReader.hasSingleByteCoverage();
for (const auto &CoverageReader : CoverageReaders) {
for (auto RecordOrErr : *CoverageReader) {
if (Error E = RecordOrErr.takeError())
@@ -1321,14 +1324,8 @@ class SegmentBuilder {
// value for that area.
// We add counts of the regions of the same kind as the active region
// to handle the both situations.
- if (I->Kind == Active->Kind) {
- assert(I->HasSingleByteCoverage == Active->HasSingleByteCoverage &&
- "Regions are generated in different coverage modes");
- if (I->HasSingleByteCoverage)
- Active->ExecutionCount = Active->ExecutionCount || I->ExecutionCount;
- else
- Active->ExecutionCount += I->ExecutionCount;
- }
+ if (I->Kind == Active->Kind)
+ Active->ExecutionCount += I->ExecutionCount;
}
return Regions.drop_back(std::distance(++Active, End));
}
@@ -1421,7 +1418,8 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) {
}
CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
- CoverageData FileCoverage(Filename);
+ assert(SingleByteCoverage);
+ CoverageData FileCoverage(*SingleByteCoverage, Filename);
std::vector<CountedRegion> Regions;
// Look up the function records in the given file. Due to hash collisions on
@@ -1485,7 +1483,9 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const {
if (!MainFileID)
return CoverageData();
- CoverageData FunctionCoverage(Function.Filenames[*MainFileID]);
+ assert(SingleByteCoverage);
+ CoverageData FunctionCoverage(*SingleByteCoverage,
+ Function.Filenames[*MainFileID]);
std::vector<CountedRegion> Regions;
for (const auto &CR : Function.CountedRegions)
if (CR.FileID == *MainFileID) {
@@ -1512,8 +1512,9 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const {
CoverageData CoverageMapping::getCoverageForExpansion(
const ExpansionRecord &Expansion) const {
+ assert(SingleByteCoverage);
CoverageData ExpansionCoverage(
- Expansion.Function.Filenames[Expansion.FileID]);
+ *SingleByteCoverage, Expansion.Function.Filenames[Expansion.FileID]);
std::vector<CountedRegion> Regions;
for (const auto &CR : Expansion.Function.CountedRegions)
if (CR.FileID == Expansion.FileID) {