Skip to content

Commit 978070d

Browse files
committed
[Coverage] MCDC: Move findIndependencePairs into MCDCRecord
1 parent 3d9f968 commit 978070d

File tree

2 files changed

+51
-43
lines changed

2 files changed

+51
-43
lines changed

llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include <cstdint>
3636
#include <iterator>
3737
#include <memory>
38+
#include <optional>
3839
#include <sstream>
3940
#include <string>
4041
#include <system_error>
@@ -451,19 +452,22 @@ struct MCDCRecord {
451452
private:
452453
CounterMappingRegion Region;
453454
TestVectors TV;
454-
TVPairMap IndependencePairs;
455+
std::optional<TVPairMap> IndependencePairs;
455456
BoolVector Folded;
456457
CondIDMap PosToID;
457458
LineColPairMap CondLoc;
458459

459460
public:
460461
MCDCRecord(const CounterMappingRegion &Region, TestVectors &&TV,
461-
TVPairMap &&IndependencePairs, BoolVector &&Folded,
462-
CondIDMap &&PosToID, LineColPairMap &&CondLoc)
463-
: Region(Region), TV(std::move(TV)),
464-
IndependencePairs(std::move(IndependencePairs)),
465-
Folded(std::move(Folded)), PosToID(std::move(PosToID)),
466-
CondLoc(std::move(CondLoc)){};
462+
BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc)
463+
: Region(Region), TV(std::move(TV)), Folded(std::move(Folded)),
464+
PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) {
465+
findIndependencePairs();
466+
}
467+
468+
// Compare executed test vectors against each other to find an independence
469+
// pairs for each condition. This processing takes the most time.
470+
void findIndependencePairs();
467471

468472
const CounterMappingRegion &getDecisionRegion() const { return Region; }
469473
unsigned getNumConditions() const {
@@ -494,10 +498,10 @@ struct MCDCRecord {
494498
/// TestVectors requires a translation from a ordinal position to actual
495499
/// condition ID. This is done via PosToID[].
496500
bool isConditionIndependencePairCovered(unsigned Condition) const {
501+
assert(IndependencePairs);
497502
auto It = PosToID.find(Condition);
498-
if (It != PosToID.end())
499-
return IndependencePairs.contains(It->second);
500-
llvm_unreachable("Condition ID without an Ordinal mapping");
503+
assert(It != PosToID.end() && "Condition ID without an Ordinal mapping");
504+
return IndependencePairs->contains(It->second);
501505
}
502506

503507
/// Return the Independence Pair that covers the given condition. Because
@@ -507,7 +511,8 @@ struct MCDCRecord {
507511
/// via PosToID[].
508512
TVRowPair getConditionIndependencePair(unsigned Condition) {
509513
assert(isConditionIndependencePairCovered(Condition));
510-
return IndependencePairs[PosToID[Condition]];
514+
assert(IndependencePairs);
515+
return (*IndependencePairs)[PosToID[Condition]];
511516
}
512517

513518
float getPercentCovered() const {

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,40 @@ Expected<int64_t> CounterMappingContext::evaluate(const Counter &C) const {
221221
return LastPoppedValue;
222222
}
223223

224+
// Find an independence pair for each condition:
225+
// - The condition is true in one test and false in the other.
226+
// - The decision outcome is true one test and false in the other.
227+
// - All other conditions' values must be equal or marked as "don't care".
228+
void MCDCRecord::findIndependencePairs() {
229+
if (IndependencePairs)
230+
return;
231+
232+
IndependencePairs.emplace();
233+
234+
unsigned NumTVs = TV.size();
235+
// Will be replaced to shorter expr.
236+
unsigned TVTrueIdx = std::distance(
237+
TV.begin(),
238+
std::find_if(TV.begin(), TV.end(),
239+
[&](auto I) { return (I.second == MCDCRecord::MCDC_True); })
240+
241+
);
242+
for (unsigned I = TVTrueIdx; I < NumTVs; ++I) {
243+
const auto &[A, ACond] = TV[I];
244+
assert(ACond == MCDCRecord::MCDC_True);
245+
for (unsigned J = 0; J < TVTrueIdx; ++J) {
246+
const auto &[B, BCond] = TV[J];
247+
assert(BCond == MCDCRecord::MCDC_False);
248+
// If the two vectors differ in exactly one condition, ignoring DontCare
249+
// conditions, we have found an independence pair.
250+
auto AB = A.getDifferences(B);
251+
if (AB.count() == 1)
252+
IndependencePairs->insert(
253+
{AB.find_first(), std::make_pair(J + 1, I + 1)});
254+
}
255+
}
256+
}
257+
224258
mcdc::TVIdxBuilder::TVIdxBuilder(const SmallVectorImpl<ConditionIDs> &NextIDs,
225259
int Offset)
226260
: Indices(NextIDs.size()) {
@@ -375,9 +409,6 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
375409
/// ExecutedTestVectorBitmap.
376410
MCDCRecord::TestVectors &ExecVectors;
377411

378-
/// Number of False items in ExecVectors
379-
unsigned NumExecVectorsF;
380-
381412
#ifndef NDEBUG
382413
DenseSet<unsigned> TVIdxs;
383414
#endif
@@ -446,34 +477,11 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
446477
// Fill ExecVectors order by False items and True items.
447478
// ExecVectors is the alias of ExecVectorsByCond[false], so
448479
// Append ExecVectorsByCond[true] on it.
449-
NumExecVectorsF = ExecVectors.size();
450480
auto &ExecVectorsT = ExecVectorsByCond[true];
451481
ExecVectors.append(std::make_move_iterator(ExecVectorsT.begin()),
452482
std::make_move_iterator(ExecVectorsT.end()));
453483
}
454484

455-
// Find an independence pair for each condition:
456-
// - The condition is true in one test and false in the other.
457-
// - The decision outcome is true one test and false in the other.
458-
// - All other conditions' values must be equal or marked as "don't care".
459-
void findIndependencePairs() {
460-
unsigned NumTVs = ExecVectors.size();
461-
for (unsigned I = NumExecVectorsF; I < NumTVs; ++I) {
462-
const auto &[A, ACond] = ExecVectors[I];
463-
assert(ACond == MCDCRecord::MCDC_True);
464-
for (unsigned J = 0; J < NumExecVectorsF; ++J) {
465-
const auto &[B, BCond] = ExecVectors[J];
466-
assert(BCond == MCDCRecord::MCDC_False);
467-
// If the two vectors differ in exactly one condition, ignoring DontCare
468-
// conditions, we have found an independence pair.
469-
auto AB = A.getDifferences(B);
470-
if (AB.count() == 1)
471-
IndependencePairs.insert(
472-
{AB.find_first(), std::make_pair(J + 1, I + 1)});
473-
}
474-
}
475-
}
476-
477485
public:
478486
/// Process the MC/DC Record in order to produce a result for a boolean
479487
/// expression. This process includes tracking the conditions that comprise
@@ -509,13 +517,8 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
509517
// Using Profile Bitmap from runtime, mark the executed test vectors.
510518
findExecutedTestVectors();
511519

512-
// Compare executed test vectors against each other to find an independence
513-
// pairs for each condition. This processing takes the most time.
514-
findIndependencePairs();
515-
516520
// Record Test vectors, executed vectors, and independence pairs.
517-
return MCDCRecord(Region, std::move(ExecVectors),
518-
std::move(IndependencePairs), std::move(Folded),
521+
return MCDCRecord(Region, std::move(ExecVectors), std::move(Folded),
519522
std::move(PosToID), std::move(CondLoc));
520523
}
521524
};

0 commit comments

Comments
 (0)