Skip to content

Commit 0ed61db

Browse files
authored
[MC/DC] Refactor: Isolate the final result out of TestVector (#82282)
To reduce conditional judges in the loop in `findIndependencePairs()`, I have tried a couple of tweaks. * Isolate the final result in `TestVectors` `using TestVectors = llvm::SmallVector<std::pair<TestVector, CondState>>;` The final result was just piggybacked on `TestVector`, so it has been isolated. * Filter out and sort `ExecVectors` by the final result It will cost more in constructing `ExecVectors`, but it can reduce at least one conditional judgement in the loop.
1 parent c19a819 commit 0ed61db

File tree

2 files changed

+28
-15
lines changed

2 files changed

+28
-15
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ struct MCDCRecord {
385385
enum CondState { MCDC_DontCare = -1, MCDC_False = 0, MCDC_True = 1 };
386386

387387
using TestVector = llvm::SmallVector<CondState>;
388-
using TestVectors = llvm::SmallVector<TestVector>;
388+
using TestVectors = llvm::SmallVector<std::pair<TestVector, CondState>>;
389389
using BoolVector = llvm::SmallVector<bool>;
390390
using TVRowPair = std::pair<unsigned, unsigned>;
391391
using TVPairMap = llvm::DenseMap<unsigned, TVRowPair>;
@@ -426,13 +426,13 @@ struct MCDCRecord {
426426
/// accessing conditions in the TestVectors requires a translation from a
427427
/// ordinal position to actual condition ID. This is done via PosToID[].
428428
CondState getTVCondition(unsigned TestVectorIndex, unsigned Condition) {
429-
return TV[TestVectorIndex][PosToID[Condition]];
429+
return TV[TestVectorIndex].first[PosToID[Condition]];
430430
}
431431

432432
/// Return the Result evaluation for an executed test vector.
433433
/// See MCDCRecordProcessor::RecordTestVector().
434434
CondState getTVResult(unsigned TestVectorIndex) {
435-
return TV[TestVectorIndex][getNumConditions()];
435+
return TV[TestVectorIndex].second;
436436
}
437437

438438
/// Determine whether a given condition (indicated by Condition) is covered

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -370,9 +370,16 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
370370
/// Mapping of calculated MC/DC Independence Pairs for each condition.
371371
MCDCRecord::TVPairMap IndependencePairs;
372372

373+
/// Storage for ExecVectors
374+
/// ExecVectors is the alias of its 0th element.
375+
std::array<MCDCRecord::TestVectors, 2> ExecVectorsByCond;
376+
373377
/// Actual executed Test Vectors for the boolean expression, based on
374378
/// ExecutedTestVectorBitmap.
375-
MCDCRecord::TestVectors ExecVectors;
379+
MCDCRecord::TestVectors &ExecVectors;
380+
381+
/// Number of False items in ExecVectors
382+
unsigned NumExecVectorsF;
376383

377384
#ifndef NDEBUG
378385
DenseSet<unsigned> TVIdxs;
@@ -385,7 +392,8 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
385392
: NextIDsBuilder(Branches), TVIdxBuilder(this->NextIDs), Bitmap(Bitmap),
386393
Region(Region), DecisionParams(Region.getDecisionParams()),
387394
Branches(Branches), NumConditions(DecisionParams.NumConditions),
388-
Folded(NumConditions, false), IndependencePairs(NumConditions) {}
395+
Folded(NumConditions, false), IndependencePairs(NumConditions),
396+
ExecVectors(ExecVectorsByCond[false]) {}
389397

390398
private:
391399
// Walk the binary decision diagram and try assigning both false and true to
@@ -415,11 +423,9 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
415423
continue;
416424

417425
// Copy the completed test vector to the vector of testvectors.
418-
ExecVectors.push_back(TV);
419-
420426
// The final value (T,F) is equal to the last non-dontcare state on the
421427
// path (in a short-circuiting system).
422-
ExecVectors.back().push_back(MCDCCond);
428+
ExecVectorsByCond[MCDCCond].push_back({TV, MCDCCond});
423429
}
424430

425431
// Reset back to DontCare.
@@ -437,6 +443,14 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
437443
buildTestVector(TV, 0, 0, 0);
438444
assert(TVIdxs.size() == unsigned(NumTestVectors) &&
439445
"TVIdxs wasn't fulfilled");
446+
447+
// Fill ExecVectors order by False items and True items.
448+
// ExecVectors is the alias of ExecVectorsByCond[false], so
449+
// Append ExecVectorsByCond[true] on it.
450+
NumExecVectorsF = ExecVectors.size();
451+
auto &ExecVectorsT = ExecVectorsByCond[true];
452+
ExecVectors.append(std::make_move_iterator(ExecVectorsT.begin()),
453+
std::make_move_iterator(ExecVectorsT.end()));
440454
}
441455

442456
// Find an independence pair for each condition:
@@ -445,13 +459,12 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder {
445459
// - All other conditions' values must be equal or marked as "don't care".
446460
void findIndependencePairs() {
447461
unsigned NumTVs = ExecVectors.size();
448-
for (unsigned I = 1; I < NumTVs; ++I) {
449-
const MCDCRecord::TestVector &A = ExecVectors[I];
450-
for (unsigned J = 0; J < I; ++J) {
451-
const MCDCRecord::TestVector &B = ExecVectors[J];
452-
// Enumerate two execution vectors whose outcomes are different.
453-
if (A[NumConditions] == B[NumConditions])
454-
continue;
462+
for (unsigned I = NumExecVectorsF; I < NumTVs; ++I) {
463+
const auto &[A, ACond] = ExecVectors[I];
464+
assert(ACond == MCDCRecord::MCDC_True);
465+
for (unsigned J = 0; J < NumExecVectorsF; ++J) {
466+
const auto &[B, BCond] = ExecVectors[J];
467+
assert(BCond == MCDCRecord::MCDC_False);
455468
unsigned Flip = NumConditions, Idx;
456469
for (Idx = 0; Idx < NumConditions; ++Idx) {
457470
MCDCRecord::CondState ACond = A[Idx], BCond = B[Idx];

0 commit comments

Comments
 (0)