[llvm] [Coverage] MCDC: Move `findIndependencePairs` into `MCDCRecord` (PR #121188)
NAKAMURA Takumi via llvm-commits
llvm-commits at lists.llvm.org
Fri Dec 27 00:32:30 PST 2024
https://github.com/chapuni created https://github.com/llvm/llvm-project/pull/121188
None
>From 978070d6aca594a49dc2ef0558e1e28e883ac1b0 Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi <geek4civic at gmail.com>
Date: Fri, 27 Dec 2024 15:34:16 +0900
Subject: [PATCH] [Coverage] MCDC: Move `findIndependencePairs` into
`MCDCRecord`
---
.../ProfileData/Coverage/CoverageMapping.h | 27 +++++---
.../ProfileData/Coverage/CoverageMapping.cpp | 67 ++++++++++---------
2 files changed, 51 insertions(+), 43 deletions(-)
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index 42da188fef34ee..4f28f5da6cf81f 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -35,6 +35,7 @@
#include <cstdint>
#include <iterator>
#include <memory>
+#include <optional>
#include <sstream>
#include <string>
#include <system_error>
@@ -451,19 +452,22 @@ struct MCDCRecord {
private:
CounterMappingRegion Region;
TestVectors TV;
- TVPairMap IndependencePairs;
+ std::optional<TVPairMap> IndependencePairs;
BoolVector Folded;
CondIDMap PosToID;
LineColPairMap CondLoc;
public:
MCDCRecord(const CounterMappingRegion &Region, TestVectors &&TV,
- TVPairMap &&IndependencePairs, BoolVector &&Folded,
- CondIDMap &&PosToID, LineColPairMap &&CondLoc)
- : Region(Region), TV(std::move(TV)),
- IndependencePairs(std::move(IndependencePairs)),
- Folded(std::move(Folded)), PosToID(std::move(PosToID)),
- CondLoc(std::move(CondLoc)){};
+ BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc)
+ : Region(Region), TV(std::move(TV)), Folded(std::move(Folded)),
+ PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) {
+ findIndependencePairs();
+ }
+
+ // Compare executed test vectors against each other to find an independence
+ // pairs for each condition. This processing takes the most time.
+ void findIndependencePairs();
const CounterMappingRegion &getDecisionRegion() const { return Region; }
unsigned getNumConditions() const {
@@ -494,10 +498,10 @@ struct MCDCRecord {
/// TestVectors requires a translation from a ordinal position to actual
/// condition ID. This is done via PosToID[].
bool isConditionIndependencePairCovered(unsigned Condition) const {
+ assert(IndependencePairs);
auto It = PosToID.find(Condition);
- if (It != PosToID.end())
- return IndependencePairs.contains(It->second);
- llvm_unreachable("Condition ID without an Ordinal mapping");
+ assert(It != PosToID.end() && "Condition ID without an Ordinal mapping");
+ return IndependencePairs->contains(It->second);
}
/// Return the Independence Pair that covers the given condition. Because
@@ -507,7 +511,8 @@ struct MCDCRecord {
/// via PosToID[].
TVRowPair getConditionIndependencePair(unsigned Condition) {
assert(isConditionIndependencePairCovered(Condition));
- return IndependencePairs[PosToID[Condition]];
+ assert(IndependencePairs);
+ return (*IndependencePairs)[PosToID[Condition]];
}
float getPercentCovered() const {
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 87d8bb1bbb79c7..2c7a77bac09328 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -221,6 +221,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()) {
@@ -375,9 +409,6 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
/// ExecutedTestVectorBitmap.
MCDCRecord::TestVectors &ExecVectors;
- /// Number of False items in ExecVectors
- unsigned NumExecVectorsF;
-
#ifndef NDEBUG
DenseSet<unsigned> TVIdxs;
#endif
@@ -446,34 +477,11 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
// 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
@@ -509,13 +517,8 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
// 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));
}
};
More information about the llvm-commits
mailing list