Skip to content

Commit f42bb83

Browse files
committed
Merge branches 'users/chapuni/cov/merge/mcdcfold' and 'users/chapuni/cov/merge/mov_ind' into users/chapuni/cov/merge/mcdcsort-base
3 parents 3d9f968 + 36b4aaf + 978070d commit f42bb83

File tree

2 files changed

+61
-50
lines changed

2 files changed

+61
-50
lines changed

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

Lines changed: 20 additions & 13 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>
@@ -442,7 +443,7 @@ struct MCDCRecord {
442443
};
443444

444445
using TestVectors = llvm::SmallVector<std::pair<TestVector, CondState>>;
445-
using BoolVector = llvm::SmallVector<bool>;
446+
using BoolVector = std::array<BitVector, 2>;
446447
using TVRowPair = std::pair<unsigned, unsigned>;
447448
using TVPairMap = llvm::DenseMap<unsigned, TVRowPair>;
448449
using CondIDMap = llvm::DenseMap<unsigned, unsigned>;
@@ -451,26 +452,31 @@ 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 {
470474
return Region.getDecisionParams().NumConditions;
471475
}
472476
unsigned getNumTestVectors() const { return TV.size(); }
473-
bool isCondFolded(unsigned Condition) const { return Folded[Condition]; }
477+
bool isCondFolded(unsigned Condition) const {
478+
return Folded[false][Condition] || Folded[true][Condition];
479+
}
474480

475481
/// Return the evaluation of a condition (indicated by Condition) in an
476482
/// executed test vector (indicated by TestVectorIndex), which will be True,
@@ -494,10 +500,10 @@ struct MCDCRecord {
494500
/// TestVectors requires a translation from a ordinal position to actual
495501
/// condition ID. This is done via PosToID[].
496502
bool isConditionIndependencePairCovered(unsigned Condition) const {
503+
assert(IndependencePairs);
497504
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");
505+
assert(It != PosToID.end() && "Condition ID without an Ordinal mapping");
506+
return IndependencePairs->contains(It->second);
501507
}
502508

503509
/// Return the Independence Pair that covers the given condition. Because
@@ -507,7 +513,8 @@ struct MCDCRecord {
507513
/// via PosToID[].
508514
TVRowPair getConditionIndependencePair(unsigned Condition) {
509515
assert(isConditionIndependencePairCovered(Condition));
510-
return IndependencePairs[PosToID[Condition]];
516+
assert(IndependencePairs);
517+
return (*IndependencePairs)[PosToID[Condition]];
511518
}
512519

513520
float getPercentCovered() const {

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 41 additions & 37 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
@@ -392,8 +423,9 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
392423
: NextIDsBuilder(Branches), TVIdxBuilder(this->NextIDs), Bitmap(Bitmap),
393424
Region(Region), DecisionParams(Region.getDecisionParams()),
394425
Branches(Branches), NumConditions(DecisionParams.NumConditions),
395-
Folded(NumConditions, false), IndependencePairs(NumConditions),
396-
ExecVectors(ExecVectorsByCond[false]), IsVersion11(IsVersion11) {}
426+
Folded{{BitVector(NumConditions), BitVector(NumConditions)}},
427+
IndependencePairs(NumConditions), ExecVectors(ExecVectorsByCond[false]),
428+
IsVersion11(IsVersion11) {}
397429

398430
private:
399431
// Walk the binary decision diagram and try assigning both false and true to
@@ -446,34 +478,11 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
446478
// Fill ExecVectors order by False items and True items.
447479
// ExecVectors is the alias of ExecVectorsByCond[false], so
448480
// Append ExecVectorsByCond[true] on it.
449-
NumExecVectorsF = ExecVectors.size();
450481
auto &ExecVectorsT = ExecVectorsByCond[true];
451482
ExecVectors.append(std::make_move_iterator(ExecVectorsT.begin()),
452483
std::make_move_iterator(ExecVectorsT.end()));
453484
}
454485

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-
477486
public:
478487
/// Process the MC/DC Record in order to produce a result for a boolean
479488
/// expression. This process includes tracking the conditions that comprise
@@ -485,7 +494,6 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
485494
/// location is also tracked, as well as whether it is constant folded (in
486495
/// which case it is excuded from the metric).
487496
MCDCRecord processMCDCRecord() {
488-
unsigned I = 0;
489497
MCDCRecord::CondIDMap PosToID;
490498
MCDCRecord::LineColPairMap CondLoc;
491499

@@ -499,23 +507,19 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
499507
// visualize where the condition is.
500508
// - Record whether the condition is constant folded so that we exclude it
501509
// from being measured.
502-
for (const auto *B : Branches) {
510+
for (auto [I, B] : enumerate(Branches)) {
503511
const auto &BranchParams = B->getBranchParams();
504512
PosToID[I] = BranchParams.ID;
505513
CondLoc[I] = B->startLoc();
506-
Folded[I++] = (B->Count.isZero() || B->FalseCount.isZero());
514+
Folded[false][I] = B->FalseCount.isZero();
515+
Folded[true][I] = B->Count.isZero();
507516
}
508517

509518
// Using Profile Bitmap from runtime, mark the executed test vectors.
510519
findExecutedTestVectors();
511520

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-
516521
// Record Test vectors, executed vectors, and independence pairs.
517-
return MCDCRecord(Region, std::move(ExecVectors),
518-
std::move(IndependencePairs), std::move(Folded),
522+
return MCDCRecord(Region, std::move(ExecVectors), std::move(Folded),
519523
std::move(PosToID), std::move(CondLoc));
520524
}
521525
};

0 commit comments

Comments
 (0)