Skip to content

Commit ab76e48

Browse files
authored
[MC/DC] Refactor: Let MCDCConditionID int16_t with zero-origin (#81257)
Also, Let `NumConditions` `uint16_t`. It is smarter to handle the ID as signed. Narrowing to `int16_t` will reduce costs of handling byvalue. (See also #81221 and #81227) External behavior doesn't change. They below handle values as internal values plus 1. * `-dump-coverage-mapping` * `CoverageMappingReader.cpp` * `CoverageMappingWriter.cpp`
1 parent 36adfec commit ab76e48

File tree

8 files changed

+61
-50
lines changed

8 files changed

+61
-50
lines changed

clang/lib/CodeGen/CodeGenPGO.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ void CodeGenPGO::emitCounterRegionMapping(const Decl *D) {
10311031

10321032
std::string CoverageMapping;
10331033
llvm::raw_string_ostream OS(CoverageMapping);
1034-
RegionMCDCState->CondIDMap.clear();
1034+
RegionCondIDMap.reset(new llvm::DenseMap<const Stmt *, int16_t>);
10351035
CoverageMappingGen MappingGen(
10361036
*CGM.getCoverageMapping(), CGM.getContext().getSourceManager(),
10371037
CGM.getLangOpts(), RegionCounterMap.get(), RegionMCDCState.get());
@@ -1195,8 +1195,8 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
11951195
return;
11961196

11971197
// Extract the ID of the condition we are setting in the bitmap.
1198-
unsigned CondID = ExprMCDCConditionIDMapIterator->second;
1199-
assert(CondID > 0 && "Condition has no ID!");
1198+
auto CondID = ExprMCDCConditionIDMapIterator->second;
1199+
assert(CondID >= 0 && "Condition has no ID!");
12001200

12011201
auto *I8PtrTy = llvm::PointerType::getUnqual(CGM.getLLVMContext());
12021202

@@ -1205,7 +1205,7 @@ void CodeGenPGO::emitMCDCCondBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
12051205
// the resulting value is used to update the boolean expression's bitmap.
12061206
llvm::Value *Args[5] = {llvm::ConstantExpr::getBitCast(FuncNameVar, I8PtrTy),
12071207
Builder.getInt64(FunctionHash),
1208-
Builder.getInt32(CondID - 1),
1208+
Builder.getInt32(CondID),
12091209
MCDCCondBitmapAddr.getPointer(), Val};
12101210
Builder.CreateCall(
12111211
CGM.getIntrinsic(llvm::Intrinsic::instrprof_mcdc_condbitmap_update),

clang/lib/CodeGen/CodeGenPGO.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class CodeGenPGO {
3636
unsigned NumRegionCounters;
3737
uint64_t FunctionHash;
3838
std::unique_ptr<llvm::DenseMap<const Stmt *, unsigned>> RegionCounterMap;
39+
std::unique_ptr<llvm::DenseMap<const Stmt *, unsigned>> RegionMCDCBitmapMap;
40+
std::unique_ptr<llvm::DenseMap<const Stmt *, int16_t>> RegionCondIDMap;
3941
std::unique_ptr<llvm::DenseMap<const Stmt *, uint64_t>> StmtCountMap;
4042
std::unique_ptr<llvm::InstrProfRecord> ProfRecord;
4143
std::unique_ptr<MCDC::State> RegionMCDCState;

clang/lib/CodeGen/CoverageMappingGen.cpp

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -686,11 +686,12 @@ struct MCDCCoverageBuilder {
686686
llvm::SmallVector<mcdc::ConditionIDs> DecisionStack;
687687
MCDC::State &MCDCState;
688688
llvm::DenseMap<const Stmt *, mcdc::ConditionID> &CondIDs;
689-
mcdc::ConditionID NextID = 1;
689+
mcdc::ConditionID NextID = 0;
690690
bool NotMapped = false;
691691

692-
/// Represent a sentinel value of [0,0] for the bottom of DecisionStack.
693-
static constexpr mcdc::ConditionIDs DecisionStackSentinel{0, 0};
692+
/// Represent a sentinel value as a pair of final decisions for the bottom
693+
// of DecisionStack.
694+
static constexpr mcdc::ConditionIDs DecisionStackSentinel{-1, -1};
694695

695696
/// Is this a logical-AND operation?
696697
bool isLAnd(const BinaryOperator *E) const {
@@ -705,12 +706,12 @@ struct MCDCCoverageBuilder {
705706
/// Return whether the build of the control flow map is at the top-level
706707
/// (root) of a logical operator nest in a boolean expression prior to the
707708
/// assignment of condition IDs.
708-
bool isIdle() const { return (NextID == 1 && !NotMapped); }
709+
bool isIdle() const { return (NextID == 0 && !NotMapped); }
709710

710711
/// Return whether any IDs have been assigned in the build of the control
711712
/// flow map, indicating that the map is being generated for this boolean
712713
/// expression.
713-
bool isBuilding() const { return (NextID > 1); }
714+
bool isBuilding() const { return (NextID > 0); }
714715

715716
/// Set the given condition's ID.
716717
void setCondID(const Expr *Cond, mcdc::ConditionID ID) {
@@ -721,7 +722,7 @@ struct MCDCCoverageBuilder {
721722
mcdc::ConditionID getCondID(const Expr *Cond) const {
722723
auto I = CondIDs.find(CodeGenFunction::stripCond(Cond));
723724
if (I == CondIDs.end())
724-
return 0;
725+
return -1;
725726
else
726727
return I->second;
727728
}
@@ -789,15 +790,15 @@ struct MCDCCoverageBuilder {
789790
// Reset state if not doing mapping.
790791
if (NotMapped) {
791792
NotMapped = false;
792-
assert(NextID == 1);
793+
assert(NextID == 0);
793794
return 0;
794795
}
795796

796797
// Set number of conditions and reset.
797-
unsigned TotalConds = NextID - 1;
798+
unsigned TotalConds = NextID;
798799

799800
// Reset ID back to beginning.
800-
NextID = 1;
801+
NextID = 0;
801802

802803
return TotalConds;
803804
}
@@ -889,7 +890,7 @@ struct CounterCoverageMappingBuilder
889890
return RegionStack.size() - 1;
890891
}
891892

892-
size_t pushRegion(unsigned BitmapIdx, unsigned Conditions,
893+
size_t pushRegion(unsigned BitmapIdx, uint16_t Conditions,
893894
std::optional<SourceLocation> StartLoc = std::nullopt,
894895
std::optional<SourceLocation> EndLoc = std::nullopt) {
895896

@@ -1038,7 +1039,7 @@ struct CounterCoverageMappingBuilder
10381039
if (CodeGenFunction::isInstrumentedCondition(C)) {
10391040
mcdc::Parameters BranchParams;
10401041
mcdc::ConditionID ID = MCDCBuilder.getCondID(C);
1041-
if (ID > 0)
1042+
if (ID >= 0)
10421043
BranchParams = mcdc::BranchParameters{ID, Conds};
10431044

10441045
// If a condition can fold to true or false, the corresponding branch
@@ -2125,8 +2126,9 @@ static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
21252126

21262127
if (const auto *BranchParams =
21272128
std::get_if<mcdc::BranchParameters>(&R.MCDCParams)) {
2128-
OS << " [" << BranchParams->ID << "," << BranchParams->Conds[true];
2129-
OS << "," << BranchParams->Conds[false] << "] ";
2129+
OS << " [" << BranchParams->ID + 1 << ","
2130+
<< BranchParams->Conds[true] + 1;
2131+
OS << "," << BranchParams->Conds[false] + 1 << "] ";
21302132
}
21312133

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

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@
1919
namespace llvm::coverage::mcdc {
2020

2121
/// The ID for MCDCBranch.
22-
using ConditionID = unsigned int;
22+
using ConditionID = int16_t;
2323
using ConditionIDs = std::array<ConditionID, 2>;
2424

2525
struct DecisionParameters {
2626
/// Byte Index of Bitmap Coverage Object for a Decision Region.
2727
unsigned BitmapIdx;
2828

2929
/// Number of Conditions used for a Decision Region.
30-
unsigned NumConditions;
30+
uint16_t NumConditions;
3131

3232
DecisionParameters() = delete;
3333
DecisionParameters(unsigned BitmapIdx, unsigned NumConditions)

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -272,17 +272,17 @@ class MCDCRecordProcessor {
272272
// Walk the binary decision diagram and try assigning both false and true to
273273
// each node. When a terminal node (ID == 0) is reached, fill in the value in
274274
// the truth table.
275-
void buildTestVector(MCDCRecord::TestVector &TV, unsigned ID,
275+
void buildTestVector(MCDCRecord::TestVector &TV, mcdc::ConditionID ID,
276276
unsigned Index) {
277-
assert((Index & (1 << (ID - 1))) == 0);
277+
assert((Index & (1 << ID)) == 0);
278278

279279
for (auto MCDCCond : {MCDCRecord::MCDC_False, MCDCRecord::MCDC_True}) {
280280
static_assert(MCDCRecord::MCDC_False == 0);
281281
static_assert(MCDCRecord::MCDC_True == 1);
282-
Index |= MCDCCond << (ID - 1);
283-
TV[ID - 1] = MCDCCond;
282+
Index |= MCDCCond << ID;
283+
TV[ID] = MCDCCond;
284284
auto NextID = CondsMap[ID][MCDCCond];
285-
if (NextID > 0) {
285+
if (NextID >= 0) {
286286
buildTestVector(TV, NextID, Index);
287287
continue;
288288
}
@@ -299,17 +299,17 @@ class MCDCRecordProcessor {
299299
}
300300

301301
// Reset back to DontCare.
302-
TV[ID - 1] = MCDCRecord::MCDC_DontCare;
302+
TV[ID] = MCDCRecord::MCDC_DontCare;
303303
}
304304

305305
/// Walk the bits in the bitmap. A bit set to '1' indicates that the test
306306
/// vector at the corresponding index was executed during a test run.
307307
void findExecutedTestVectors() {
308308
// Walk the binary decision diagram to enumerate all possible test vectors.
309-
// We start at the root node (ID == 1) with all values being DontCare.
309+
// We start at the root node (ID == 0) with all values being DontCare.
310310
// `Index` encodes the bitmask of true values and is initially 0.
311311
MCDCRecord::TestVector TV(NumConditions, MCDCRecord::MCDC_DontCare);
312-
buildTestVector(TV, 1, 0);
312+
buildTestVector(TV, 0, 0);
313313
}
314314

315315
// Find an independence pair for each condition:
@@ -371,7 +371,7 @@ class MCDCRecordProcessor {
371371
for (const auto *B : Branches) {
372372
const auto &BranchParams = B->getBranchParams();
373373
CondsMap[BranchParams.ID] = BranchParams.Conds;
374-
PosToID[I] = BranchParams.ID - 1;
374+
PosToID[I] = BranchParams.ID;
375375
CondLoc[I] = B->startLoc();
376376
Folded[I++] = (B->Count.isZero() && B->FalseCount.isZero());
377377
}
@@ -566,20 +566,20 @@ class MCDCDecisionRecorder {
566566
assert(Branch.Kind == CounterMappingRegion::MCDCBranchRegion);
567567

568568
auto ConditionID = Branch.getBranchParams().ID;
569-
assert(ConditionID > 0 && "ConditionID should begin with 1");
569+
assert(ConditionID >= 0 && "ConditionID should be positive");
570570

571571
if (ConditionIDs.contains(ConditionID) ||
572-
ConditionID > DecisionParams.NumConditions)
572+
ConditionID >= DecisionParams.NumConditions)
573573
return NotProcessed;
574574

575575
if (!this->dominates(Branch))
576576
return NotProcessed;
577577

578578
assert(MCDCBranches.size() < DecisionParams.NumConditions);
579579

580-
// Put `ID=1` in front of `MCDCBranches` for convenience
580+
// Put `ID=0` in front of `MCDCBranches` for convenience
581581
// even if `MCDCBranches` is not topological.
582-
if (ConditionID == 1)
582+
if (ConditionID == 0)
583583
MCDCBranches.insert(MCDCBranches.begin(), &Branch);
584584
else
585585
MCDCBranches.push_back(&Branch);

llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,9 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
244244
unsigned LineStart = 0;
245245
for (size_t I = 0; I < NumRegions; ++I) {
246246
Counter C, C2;
247-
uint64_t BIDX, NC, ID, TID, FID;
247+
uint64_t BIDX, NC;
248+
// They are stored as internal values plus 1 (min is -1)
249+
uint64_t ID1, TID1, FID1;
248250
mcdc::Parameters Params;
249251
CounterMappingRegion::RegionKind Kind = CounterMappingRegion::CodeRegion;
250252

@@ -303,28 +305,29 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
303305
return Err;
304306
if (auto Err = readCounter(C2))
305307
return Err;
306-
if (auto Err = readIntMax(ID, std::numeric_limits<unsigned>::max()))
308+
if (auto Err = readIntMax(ID1, std::numeric_limits<int16_t>::max()))
307309
return Err;
308-
if (auto Err = readIntMax(TID, std::numeric_limits<unsigned>::max()))
310+
if (auto Err = readIntMax(TID1, std::numeric_limits<int16_t>::max()))
309311
return Err;
310-
if (auto Err = readIntMax(FID, std::numeric_limits<unsigned>::max()))
312+
if (auto Err = readIntMax(FID1, std::numeric_limits<int16_t>::max()))
311313
return Err;
312-
if (ID == 0)
314+
if (ID1 == 0)
313315
return make_error<CoverageMapError>(
314316
coveragemap_error::malformed,
315317
"MCDCConditionID shouldn't be zero");
316318
Params = mcdc::BranchParameters{
317-
static_cast<unsigned>(ID),
318-
{static_cast<unsigned>(FID), static_cast<unsigned>(TID)}};
319+
static_cast<int16_t>(static_cast<int16_t>(ID1) - 1),
320+
{static_cast<int16_t>(static_cast<int16_t>(FID1) - 1),
321+
static_cast<int16_t>(static_cast<int16_t>(TID1) - 1)}};
319322
break;
320323
case CounterMappingRegion::MCDCDecisionRegion:
321324
Kind = CounterMappingRegion::MCDCDecisionRegion;
322325
if (auto Err = readIntMax(BIDX, std::numeric_limits<unsigned>::max()))
323326
return Err;
324-
if (auto Err = readIntMax(NC, std::numeric_limits<unsigned>::max()))
327+
if (auto Err = readIntMax(NC, std::numeric_limits<int16_t>::max()))
325328
return Err;
326329
Params = mcdc::DecisionParameters{static_cast<unsigned>(BIDX),
327-
static_cast<unsigned>(NC)};
330+
static_cast<uint16_t>(NC)};
328331
break;
329332
default:
330333
return make_error<CoverageMapError>(coveragemap_error::malformed,

llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,16 @@ void CoverageMappingWriter::write(raw_ostream &OS) {
253253
writeCounter(MinExpressions, Count, OS);
254254
writeCounter(MinExpressions, FalseCount, OS);
255255
{
256+
// They are written as internal values plus 1.
256257
const auto &BranchParams = I->getBranchParams();
257258
ParamsShouldBeNull = false;
258-
assert(BranchParams.ID > 0);
259-
encodeULEB128(static_cast<unsigned>(BranchParams.ID), OS);
260-
encodeULEB128(static_cast<unsigned>(BranchParams.Conds[true]), OS);
261-
encodeULEB128(static_cast<unsigned>(BranchParams.Conds[false]), OS);
259+
assert(BranchParams.ID >= 0);
260+
unsigned ID1 = BranchParams.ID + 1;
261+
unsigned TID1 = BranchParams.Conds[true] + 1;
262+
unsigned FID1 = BranchParams.Conds[false] + 1;
263+
encodeULEB128(ID1, OS);
264+
encodeULEB128(TID1, OS);
265+
encodeULEB128(FID1, OS);
262266
}
263267
break;
264268
case CounterMappingRegion::MCDCDecisionRegion:

llvm/unittests/ProfileData/CoverageMappingTest.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
192192
addCMR(Counter::getZero(), File, LS, CS, LE, CE, true);
193193
}
194194

195-
void addMCDCDecisionCMR(unsigned Mask, unsigned NC, StringRef File,
195+
void addMCDCDecisionCMR(unsigned Mask, uint16_t NC, StringRef File,
196196
unsigned LS, unsigned CS, unsigned LE, unsigned CE) {
197197
auto &Regions = InputFunctions.back().Regions;
198198
unsigned FileID = getFileIndexForFunction(File);
@@ -872,9 +872,9 @@ TEST_P(CoverageMappingTest, non_code_region_bitmask) {
872872
addCMR(Counter::getCounter(3), "file", 1, 1, 5, 5);
873873

874874
addMCDCDecisionCMR(0, 2, "file", 7, 1, 7, 6);
875-
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 1, {0, 2},
875+
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 0, {-1, 1},
876876
"file", 7, 2, 7, 3);
877-
addMCDCBranchCMR(Counter::getCounter(2), Counter::getCounter(3), 2, {0, 0},
877+
addMCDCBranchCMR(Counter::getCounter(2), Counter::getCounter(3), 1, {-1, -1},
878878
"file", 7, 4, 7, 5);
879879

880880
EXPECT_THAT_ERROR(loadCoverageMapping(), Succeeded());
@@ -900,10 +900,10 @@ TEST_P(CoverageMappingTest, decision_before_expansion) {
900900
addExpansionCMR("foo", "B", 4, 19, 4, 20);
901901
addCMR(Counter::getCounter(0), "A", 1, 14, 1, 17);
902902
addCMR(Counter::getCounter(0), "A", 1, 14, 1, 17);
903-
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 1, {0, 2},
903+
addMCDCBranchCMR(Counter::getCounter(0), Counter::getCounter(1), 0, {-1, 1},
904904
"A", 1, 14, 1, 17);
905905
addCMR(Counter::getCounter(1), "B", 1, 14, 1, 17);
906-
addMCDCBranchCMR(Counter::getCounter(1), Counter::getCounter(2), 2, {0, 0},
906+
addMCDCBranchCMR(Counter::getCounter(1), Counter::getCounter(2), 1, {-1, -1},
907907
"B", 1, 14, 1, 17);
908908

909909
// InputFunctionCoverageData::Regions is rewritten after the write.

0 commit comments

Comments
 (0)