Skip to content

Commit 1a1fcac

Browse files
authored
[MC/DC] Refactor: Introduce ConditionIDs as std::array<2> (#81221)
Its 0th element corresponds to `FalseID` and 1st to `TrueID`. CoverageMappingGen.cpp: `DecisionIDPair` is replaced with `ConditionIDs`
1 parent 8e24bc0 commit 1a1fcac

File tree

7 files changed

+56
-68
lines changed

7 files changed

+56
-68
lines changed

clang/lib/CodeGen/CoverageMappingGen.cpp

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,6 @@ struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder {
593593
/// creation.
594594
struct MCDCCoverageBuilder {
595595

596-
struct DecisionIDPair {
597-
mcdc::ConditionID TrueID = 0;
598-
mcdc::ConditionID FalseID = 0;
599-
};
600-
601596
/// The AST walk recursively visits nested logical-AND or logical-OR binary
602597
/// operator nodes and then visits their LHS and RHS children nodes. As this
603598
/// happens, the algorithm will assign IDs to each operator's LHS and RHS side
@@ -688,14 +683,14 @@ struct MCDCCoverageBuilder {
688683
private:
689684
CodeGenModule &CGM;
690685

691-
llvm::SmallVector<DecisionIDPair> DecisionStack;
686+
llvm::SmallVector<mcdc::ConditionIDs> DecisionStack;
692687
MCDC::State &MCDCState;
693688
llvm::DenseMap<const Stmt *, mcdc::ConditionID> &CondIDs;
694689
mcdc::ConditionID NextID = 1;
695690
bool NotMapped = false;
696691

697692
/// Represent a sentinel value of [0,0] for the bottom of DecisionStack.
698-
static constexpr DecisionIDPair DecisionStackSentinel{0, 0};
693+
static constexpr mcdc::ConditionIDs DecisionStackSentinel{0, 0};
699694

700695
/// Is this a logical-AND operation?
701696
bool isLAnd(const BinaryOperator *E) const {
@@ -732,7 +727,7 @@ struct MCDCCoverageBuilder {
732727
}
733728

734729
/// Return the LHS Decision ([0,0] if not set).
735-
const DecisionIDPair &back() const { return DecisionStack.back(); }
730+
const mcdc::ConditionIDs &back() const { return DecisionStack.back(); }
736731

737732
/// Push the binary operator statement to track the nest level and assign IDs
738733
/// to the operator's LHS and RHS. The RHS may be a larger subtree that is
@@ -750,7 +745,7 @@ struct MCDCCoverageBuilder {
750745
if (NotMapped)
751746
return;
752747

753-
const DecisionIDPair &ParentDecision = DecisionStack.back();
748+
const mcdc::ConditionIDs &ParentDecision = DecisionStack.back();
754749

755750
// If the operator itself has an assigned ID, this means it represents a
756751
// larger subtree. In this case, assign that ID to its LHS node. Its RHS
@@ -766,18 +761,18 @@ struct MCDCCoverageBuilder {
766761

767762
// Push the LHS decision IDs onto the DecisionStack.
768763
if (isLAnd(E))
769-
DecisionStack.push_back({RHSid, ParentDecision.FalseID});
764+
DecisionStack.push_back({ParentDecision[false], RHSid});
770765
else
771-
DecisionStack.push_back({ParentDecision.TrueID, RHSid});
766+
DecisionStack.push_back({RHSid, ParentDecision[true]});
772767
}
773768

774769
/// Pop and return the LHS Decision ([0,0] if not set).
775-
DecisionIDPair pop() {
770+
mcdc::ConditionIDs pop() {
776771
if (!CGM.getCodeGenOpts().MCDCCoverage || NotMapped)
777772
return DecisionStack.front();
778773

779774
assert(DecisionStack.size() > 1);
780-
DecisionIDPair D = DecisionStack.back();
775+
mcdc::ConditionIDs D = DecisionStack.back();
781776
DecisionStack.pop_back();
782777
return D;
783778
}
@@ -1026,15 +1021,12 @@ struct CounterCoverageMappingBuilder
10261021
return (Cond->EvaluateAsInt(Result, CVM.getCodeGenModule().getContext()));
10271022
}
10281023

1029-
using MCDCDecisionIDPair = MCDCCoverageBuilder::DecisionIDPair;
1030-
10311024
/// Create a Branch Region around an instrumentable condition for coverage
10321025
/// and add it to the function's SourceRegions. A branch region tracks a
10331026
/// "True" counter and a "False" counter for boolean expressions that
10341027
/// result in the generation of a branch.
1035-
void
1036-
createBranchRegion(const Expr *C, Counter TrueCnt, Counter FalseCnt,
1037-
const MCDCDecisionIDPair &IDPair = MCDCDecisionIDPair()) {
1028+
void createBranchRegion(const Expr *C, Counter TrueCnt, Counter FalseCnt,
1029+
const mcdc::ConditionIDs &Conds = {}) {
10381030
// Check for NULL conditions.
10391031
if (!C)
10401032
return;
@@ -1047,8 +1039,7 @@ struct CounterCoverageMappingBuilder
10471039
mcdc::Parameters BranchParams;
10481040
mcdc::ConditionID ID = MCDCBuilder.getCondID(C);
10491041
if (ID > 0)
1050-
BranchParams =
1051-
mcdc::BranchParameters{ID, IDPair.TrueID, IDPair.FalseID};
1042+
BranchParams = mcdc::BranchParameters{ID, Conds};
10521043

10531044
// If a condition can fold to true or false, the corresponding branch
10541045
// will be removed. Create a region with both counters hard-coded to
@@ -2134,8 +2125,8 @@ static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
21342125

21352126
if (const auto *BranchParams =
21362127
std::get_if<mcdc::BranchParameters>(&R.MCDCParams)) {
2137-
OS << " [" << BranchParams->ID << "," << BranchParams->TrueID;
2138-
OS << "," << BranchParams->FalseID << "] ";
2128+
OS << " [" << BranchParams->ID << "," << BranchParams->Conds[true];
2129+
OS << "," << BranchParams->Conds[false] << "] ";
21392130
}
21402131

21412132
if (R.Kind == CounterMappingRegion::ExpansionRegion)

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
#include <sstream>
3939
#include <string>
4040
#include <system_error>
41-
#include <tuple>
4241
#include <utility>
4342
#include <vector>
4443

llvm/include/llvm/ProfileData/Coverage/MCDCTypes.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@
1313
#ifndef LLVM_PROFILEDATA_COVERAGE_MCDCTYPES_H
1414
#define LLVM_PROFILEDATA_COVERAGE_MCDCTYPES_H
1515

16+
#include <array>
1617
#include <variant>
1718

1819
namespace llvm::coverage::mcdc {
1920

2021
/// The ID for MCDCBranch.
2122
using ConditionID = unsigned int;
23+
using ConditionIDs = std::array<ConditionID, 2>;
2224

2325
struct DecisionParameters {
2426
/// Byte Index of Bitmap Coverage Object for a Decision Region.
@@ -35,11 +37,12 @@ struct DecisionParameters {
3537
struct BranchParameters {
3638
/// IDs used to represent a branch region and other branch regions
3739
/// evaluated based on True and False branches.
38-
ConditionID ID, TrueID, FalseID;
40+
ConditionID ID;
41+
ConditionIDs Conds;
3942

4043
BranchParameters() = delete;
41-
BranchParameters(ConditionID ID, ConditionID TrueID, ConditionID FalseID)
42-
: ID(ID), TrueID(TrueID), FalseID(FalseID) {}
44+
BranchParameters(ConditionID ID, const ConditionIDs &Conds)
45+
: ID(ID), Conds(Conds) {}
4346
};
4447

4548
/// The type of MC/DC-specific parameters.

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ class MCDCRecordProcessor {
246246
unsigned BitmapIdx;
247247

248248
/// Mapping of a condition ID to its corresponding branch params.
249-
llvm::DenseMap<unsigned, const mcdc::BranchParameters *> BranchParamsMap;
249+
llvm::DenseMap<unsigned, mcdc::ConditionIDs> CondsMap;
250250

251251
/// Vector used to track whether a condition is constant folded.
252252
MCDCRecord::BoolVector Folded;
@@ -269,38 +269,34 @@ class MCDCRecordProcessor {
269269
Folded(NumConditions, false), IndependencePairs(NumConditions) {}
270270

271271
private:
272-
void recordTestVector(MCDCRecord::TestVector &TV, unsigned Index,
273-
MCDCRecord::CondState Result) {
274-
if (!Bitmap[BitmapIdx + Index])
275-
return;
276-
277-
// Copy the completed test vector to the vector of testvectors.
278-
ExecVectors.push_back(TV);
279-
280-
// The final value (T,F) is equal to the last non-dontcare state on the
281-
// path (in a short-circuiting system).
282-
ExecVectors.back().push_back(Result);
283-
}
284-
285272
// Walk the binary decision diagram and try assigning both false and true to
286273
// each node. When a terminal node (ID == 0) is reached, fill in the value in
287274
// the truth table.
288275
void buildTestVector(MCDCRecord::TestVector &TV, unsigned ID,
289276
unsigned Index) {
290-
auto [UnusedID, TrueID, FalseID] = *BranchParamsMap[ID];
277+
assert((Index & (1 << (ID - 1))) == 0);
278+
279+
for (auto MCDCCond : {MCDCRecord::MCDC_False, MCDCRecord::MCDC_True}) {
280+
static_assert(MCDCRecord::MCDC_False == 0);
281+
static_assert(MCDCRecord::MCDC_True == 1);
282+
Index |= MCDCCond << (ID - 1);
283+
TV[ID - 1] = MCDCCond;
284+
auto NextID = CondsMap[ID][MCDCCond];
285+
if (NextID > 0) {
286+
buildTestVector(TV, NextID, Index);
287+
continue;
288+
}
291289

292-
TV[ID - 1] = MCDCRecord::MCDC_False;
293-
if (FalseID > 0)
294-
buildTestVector(TV, FalseID, Index);
295-
else
296-
recordTestVector(TV, Index, MCDCRecord::MCDC_False);
290+
if (!Bitmap[BitmapIdx + Index])
291+
continue;
297292

298-
Index |= 1 << (ID - 1);
299-
TV[ID - 1] = MCDCRecord::MCDC_True;
300-
if (TrueID > 0)
301-
buildTestVector(TV, TrueID, Index);
302-
else
303-
recordTestVector(TV, Index, MCDCRecord::MCDC_True);
293+
// Copy the completed test vector to the vector of testvectors.
294+
ExecVectors.push_back(TV);
295+
296+
// The final value (T,F) is equal to the last non-dontcare state on the
297+
// path (in a short-circuiting system).
298+
ExecVectors.back().push_back(MCDCCond);
299+
}
304300

305301
// Reset back to DontCare.
306302
TV[ID - 1] = MCDCRecord::MCDC_DontCare;
@@ -374,7 +370,7 @@ class MCDCRecordProcessor {
374370
// from being measured.
375371
for (const auto *B : Branches) {
376372
const auto &BranchParams = B->getBranchParams();
377-
BranchParamsMap[BranchParams.ID] = &BranchParams;
373+
CondsMap[BranchParams.ID] = BranchParams.Conds;
378374
PosToID[I] = BranchParams.ID - 1;
379375
CondLoc[I] = B->startLoc();
380376
Folded[I++] = (B->Count.isZero() && B->FalseCount.isZero());

llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -313,9 +313,9 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
313313
return make_error<CoverageMapError>(
314314
coveragemap_error::malformed,
315315
"MCDCConditionID shouldn't be zero");
316-
Params = mcdc::BranchParameters{static_cast<unsigned>(ID),
317-
static_cast<unsigned>(TID),
318-
static_cast<unsigned>(FID)};
316+
Params = mcdc::BranchParameters{
317+
static_cast<unsigned>(ID),
318+
{static_cast<unsigned>(FID), static_cast<unsigned>(TID)}};
319319
break;
320320
case CounterMappingRegion::MCDCDecisionRegion:
321321
Kind = CounterMappingRegion::MCDCDecisionRegion;

llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@ void CoverageMappingWriter::write(raw_ostream &OS) {
257257
ParamsShouldBeNull = false;
258258
assert(BranchParams.ID > 0);
259259
encodeULEB128(static_cast<unsigned>(BranchParams.ID), OS);
260-
encodeULEB128(static_cast<unsigned>(BranchParams.TrueID), OS);
261-
encodeULEB128(static_cast<unsigned>(BranchParams.FalseID), OS);
260+
encodeULEB128(static_cast<unsigned>(BranchParams.Conds[true]), OS);
261+
encodeULEB128(static_cast<unsigned>(BranchParams.Conds[false]), OS);
262262
}
263263
break;
264264
case CounterMappingRegion::MCDCDecisionRegion:

llvm/unittests/ProfileData/CoverageMappingTest.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -200,14 +200,13 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
200200
mcdc::DecisionParameters{Mask, NC}, FileID, LS, CS, LE, CE));
201201
}
202202

203-
void addMCDCBranchCMR(Counter C1, Counter C2, unsigned ID, unsigned TrueID,
204-
unsigned FalseID, StringRef File, unsigned LS,
203+
void addMCDCBranchCMR(Counter C1, Counter C2, mcdc::ConditionID ID,
204+
mcdc::ConditionIDs Conds, StringRef File, unsigned LS,
205205
unsigned CS, unsigned LE, unsigned CE) {
206206
auto &Regions = InputFunctions.back().Regions;
207207
unsigned FileID = getFileIndexForFunction(File);
208208
Regions.push_back(CounterMappingRegion::makeBranchRegion(
209-
C1, C2, FileID, LS, CS, LE, CE,
210-
mcdc::BranchParameters{ID, TrueID, FalseID}));
209+
C1, C2, FileID, LS, CS, LE, CE, mcdc::BranchParameters{ID, Conds}));
211210
}
212211

213212
void addExpansionCMR(StringRef File, StringRef ExpandedFile, unsigned LS,
@@ -873,9 +872,9 @@ TEST_P(CoverageMappingTest, non_code_region_bitmask) {
873872
addCMR(Counter::getCounter(3), "file", 1, 1, 5, 5);
874873

875874
addMCDCDecisionCMR(0, 2, "file", 7, 1, 7, 6);
876-
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 1, 2, 0,
875+
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 1, {0, 2},
877876
"file", 7, 2, 7, 3);
878-
addMCDCBranchCMR(Counter::getCounter(2), Counter::getCounter(3), 2, 0, 0,
877+
addMCDCBranchCMR(Counter::getCounter(2), Counter::getCounter(3), 2, {0, 0},
879878
"file", 7, 4, 7, 5);
880879

881880
EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
@@ -901,11 +900,11 @@ TEST_P(CoverageMappingTest, decision_before_expansion) {
901900
addExpansionCMR("foo", "B", 4, 19, 4, 20);
902901
addCMR(Counter::getCounter(0), "A", 1, 14, 1, 17);
903902
addCMR(Counter::getCounter(0), "A", 1, 14, 1, 17);
904-
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 1, 2, 0, "A",
905-
1, 14, 1, 17);
903+
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 1, {0, 2},
904+
"A", 1, 14, 1, 17);
906905
addCMR(Counter::getCounter(1), "B", 1, 14, 1, 17);
907-
addMCDCBranchCMR(Counter::getCounter(1), Counter::getCounter(2), 2, 0, 0, "B",
908-
1, 14, 1, 17);
906+
addMCDCBranchCMR(Counter::getCounter(1), Counter::getCounter(2), 2, {0, 0},
907+
"B", 1, 14, 1, 17);
909908

910909
// InputFunctionCoverageData::Regions is rewritten after the write.
911910
auto InputRegions = InputFunctions.back().Regions;

0 commit comments

Comments
 (0)