Skip to content

Commit fc697f0

Browse files
committed
[Coverage] Introduce getBranchCounterPair(). NFC.
This aggregates the generation of branch counter pair as `ExecCnt` and `SkipCnt`, to aggregate `CounterExpr::subtract`. At the moment: - This change preserves the behavior of `llvm::EnableSingleByteCoverage`. Almost of SingleByteCoverage will be cleaned up by coming commits. - `getBranchCounterPair()` is not called in `llvm::EnableSingleByteCoverage`. I will implement the new behavior of SingleByteCoverage in it. - `IsCounterEqual(Out, Par)` is introduced instead of `Counter::operator==`. Tweaks would be required for the comparison for additional counters. - Braces around `assert()` is intentional. I will add a statement there. https://discourse.llvm.org/t/rfc-integrating-singlebytecoverage-with-branch-coverage/82492
1 parent 6c331e5 commit fc697f0

File tree

1 file changed

+102
-75
lines changed

1 file changed

+102
-75
lines changed

clang/lib/CodeGen/CoverageMappingGen.cpp

Lines changed: 102 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -941,6 +941,19 @@ struct CounterCoverageMappingBuilder
941941
return Counter::getCounter(CounterMap[S]);
942942
}
943943

944+
std::pair<Counter, Counter> getBranchCounterPair(const Stmt *S,
945+
Counter ParentCnt) {
946+
Counter ExecCnt = getRegionCounter(S);
947+
return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)};
948+
}
949+
950+
bool IsCounterEqual(Counter OutCount, Counter ParentCount) {
951+
if (OutCount == ParentCount)
952+
return true;
953+
954+
return false;
955+
}
956+
944957
/// Push a region onto the stack.
945958
///
946959
/// Returns the index on the stack where the region was pushed. This can be
@@ -1592,6 +1605,13 @@ struct CounterCoverageMappingBuilder
15921605
llvm::EnableSingleByteCoverage
15931606
? getRegionCounter(S->getCond())
15941607
: addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
1608+
auto [ExecCount, ExitCount] =
1609+
(llvm::EnableSingleByteCoverage
1610+
? std::make_pair(getRegionCounter(S), Counter::getZero())
1611+
: getBranchCounterPair(S, CondCount));
1612+
if (!llvm::EnableSingleByteCoverage) {
1613+
assert(ExecCount.isZero() || ExecCount == BodyCount);
1614+
}
15951615
propagateCounts(CondCount, S->getCond());
15961616
adjustForOutOfOrderTraversal(getEnd(S));
15971617

@@ -1600,13 +1620,11 @@ struct CounterCoverageMappingBuilder
16001620
if (Gap)
16011621
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
16021622

1603-
Counter OutCount =
1604-
llvm::EnableSingleByteCoverage
1605-
? getRegionCounter(S)
1606-
: addCounters(BC.BreakCount,
1607-
subtractCounters(CondCount, BodyCount));
1623+
Counter OutCount = llvm::EnableSingleByteCoverage
1624+
? getRegionCounter(S)
1625+
: addCounters(BC.BreakCount, ExitCount);
16081626

1609-
if (OutCount != ParentCount) {
1627+
if (!IsCounterEqual(OutCount, ParentCount)) {
16101628
pushRegion(OutCount);
16111629
GapRegionCounter = OutCount;
16121630
if (BodyHasTerminateStmt)
@@ -1615,8 +1633,7 @@ struct CounterCoverageMappingBuilder
16151633

16161634
// Create Branch Region around condition.
16171635
if (!llvm::EnableSingleByteCoverage)
1618-
createBranchRegion(S->getCond(), BodyCount,
1619-
subtractCounters(CondCount, BodyCount));
1636+
createBranchRegion(S->getCond(), BodyCount, ExitCount);
16201637
}
16211638

16221639
void VisitDoStmt(const DoStmt *S) {
@@ -1645,22 +1662,26 @@ struct CounterCoverageMappingBuilder
16451662
Counter CondCount = llvm::EnableSingleByteCoverage
16461663
? getRegionCounter(S->getCond())
16471664
: addCounters(BackedgeCount, BC.ContinueCount);
1665+
auto [ExecCount, ExitCount] =
1666+
(llvm::EnableSingleByteCoverage
1667+
? std::make_pair(getRegionCounter(S), Counter::getZero())
1668+
: getBranchCounterPair(S, CondCount));
1669+
if (!llvm::EnableSingleByteCoverage) {
1670+
assert(ExecCount.isZero() || ExecCount == BodyCount);
1671+
}
16481672
propagateCounts(CondCount, S->getCond());
16491673

1650-
Counter OutCount =
1651-
llvm::EnableSingleByteCoverage
1652-
? getRegionCounter(S)
1653-
: addCounters(BC.BreakCount,
1654-
subtractCounters(CondCount, BodyCount));
1655-
if (OutCount != ParentCount) {
1674+
Counter OutCount = llvm::EnableSingleByteCoverage
1675+
? getRegionCounter(S)
1676+
: addCounters(BC.BreakCount, ExitCount);
1677+
if (!IsCounterEqual(OutCount, ParentCount)) {
16561678
pushRegion(OutCount);
16571679
GapRegionCounter = OutCount;
16581680
}
16591681

16601682
// Create Branch Region around condition.
16611683
if (!llvm::EnableSingleByteCoverage)
1662-
createBranchRegion(S->getCond(), BodyCount,
1663-
subtractCounters(CondCount, BodyCount));
1684+
createBranchRegion(S->getCond(), BodyCount, ExitCount);
16641685

16651686
if (BodyHasTerminateStmt)
16661687
HasTerminateStmt = true;
@@ -1709,6 +1730,13 @@ struct CounterCoverageMappingBuilder
17091730
: addCounters(
17101731
addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount),
17111732
IncrementBC.ContinueCount);
1733+
auto [ExecCount, ExitCount] =
1734+
(llvm::EnableSingleByteCoverage
1735+
? std::make_pair(getRegionCounter(S), Counter::getZero())
1736+
: getBranchCounterPair(S, CondCount));
1737+
if (!llvm::EnableSingleByteCoverage) {
1738+
assert(ExecCount.isZero() || ExecCount == BodyCount);
1739+
}
17121740

17131741
if (const Expr *Cond = S->getCond()) {
17141742
propagateCounts(CondCount, Cond);
@@ -1723,9 +1751,8 @@ struct CounterCoverageMappingBuilder
17231751
Counter OutCount =
17241752
llvm::EnableSingleByteCoverage
17251753
? getRegionCounter(S)
1726-
: addCounters(BodyBC.BreakCount, IncrementBC.BreakCount,
1727-
subtractCounters(CondCount, BodyCount));
1728-
if (OutCount != ParentCount) {
1754+
: addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, ExitCount);
1755+
if (!IsCounterEqual(OutCount, ParentCount)) {
17291756
pushRegion(OutCount);
17301757
GapRegionCounter = OutCount;
17311758
if (BodyHasTerminateStmt)
@@ -1734,8 +1761,7 @@ struct CounterCoverageMappingBuilder
17341761

17351762
// Create Branch Region around condition.
17361763
if (!llvm::EnableSingleByteCoverage)
1737-
createBranchRegion(S->getCond(), BodyCount,
1738-
subtractCounters(CondCount, BodyCount));
1764+
createBranchRegion(S->getCond(), BodyCount, ExitCount);
17391765
}
17401766

17411767
void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
@@ -1764,15 +1790,21 @@ struct CounterCoverageMappingBuilder
17641790
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
17651791

17661792
Counter OutCount;
1793+
Counter ExitCount;
17671794
Counter LoopCount;
17681795
if (llvm::EnableSingleByteCoverage)
17691796
OutCount = getRegionCounter(S);
17701797
else {
1771-
LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
1772-
OutCount =
1773-
addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
1798+
LoopCount =
1799+
(ParentCount.isZero()
1800+
? ParentCount
1801+
: addCounters(ParentCount, BackedgeCount, BC.ContinueCount));
1802+
auto [ExecCount, SkipCount] = getBranchCounterPair(S, LoopCount);
1803+
ExitCount = SkipCount;
1804+
assert(ExecCount.isZero() || ExecCount == BodyCount);
1805+
OutCount = addCounters(BC.BreakCount, ExitCount);
17741806
}
1775-
if (OutCount != ParentCount) {
1807+
if (!IsCounterEqual(OutCount, ParentCount)) {
17761808
pushRegion(OutCount);
17771809
GapRegionCounter = OutCount;
17781810
if (BodyHasTerminateStmt)
@@ -1781,8 +1813,7 @@ struct CounterCoverageMappingBuilder
17811813

17821814
// Create Branch Region around condition.
17831815
if (!llvm::EnableSingleByteCoverage)
1784-
createBranchRegion(S->getCond(), BodyCount,
1785-
subtractCounters(LoopCount, BodyCount));
1816+
createBranchRegion(S->getCond(), BodyCount, ExitCount);
17861817
}
17871818

17881819
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
@@ -1803,10 +1834,13 @@ struct CounterCoverageMappingBuilder
18031834
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
18041835

18051836
Counter LoopCount =
1806-
addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
1807-
Counter OutCount =
1808-
addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
1809-
if (OutCount != ParentCount) {
1837+
(ParentCount.isZero()
1838+
? ParentCount
1839+
: addCounters(ParentCount, BackedgeCount, BC.ContinueCount));
1840+
auto [ExecCount, ExitCount] = getBranchCounterPair(S, LoopCount);
1841+
assert(ExecCount.isZero() || ExecCount == BodyCount);
1842+
Counter OutCount = addCounters(BC.BreakCount, ExitCount);
1843+
if (!IsCounterEqual(OutCount, ParentCount)) {
18101844
pushRegion(OutCount);
18111845
GapRegionCounter = OutCount;
18121846
}
@@ -2016,9 +2050,12 @@ struct CounterCoverageMappingBuilder
20162050
extendRegion(S->getCond());
20172051

20182052
Counter ParentCount = getRegion().getCounter();
2019-
Counter ThenCount = llvm::EnableSingleByteCoverage
2020-
? getRegionCounter(S->getThen())
2021-
: getRegionCounter(S);
2053+
auto [ThenCount, ElseCount] =
2054+
(llvm::EnableSingleByteCoverage
2055+
? std::make_pair(getRegionCounter(S->getThen()),
2056+
(S->getElse() ? getRegionCounter(S->getElse())
2057+
: Counter::getZero()))
2058+
: getBranchCounterPair(S, ParentCount));
20222059

20232060
// Emitting a counter for the condition makes it easier to interpret the
20242061
// counter for the body when looking at the coverage.
@@ -2033,12 +2070,6 @@ struct CounterCoverageMappingBuilder
20332070
extendRegion(S->getThen());
20342071
Counter OutCount = propagateCounts(ThenCount, S->getThen());
20352072

2036-
Counter ElseCount;
2037-
if (!llvm::EnableSingleByteCoverage)
2038-
ElseCount = subtractCounters(ParentCount, ThenCount);
2039-
else if (S->getElse())
2040-
ElseCount = getRegionCounter(S->getElse());
2041-
20422073
if (const Stmt *Else = S->getElse()) {
20432074
bool ThenHasTerminateStmt = HasTerminateStmt;
20442075
HasTerminateStmt = false;
@@ -2061,15 +2092,14 @@ struct CounterCoverageMappingBuilder
20612092
if (llvm::EnableSingleByteCoverage)
20622093
OutCount = getRegionCounter(S);
20632094

2064-
if (OutCount != ParentCount) {
2095+
if (!IsCounterEqual(OutCount, ParentCount)) {
20652096
pushRegion(OutCount);
20662097
GapRegionCounter = OutCount;
20672098
}
20682099

20692100
if (!S->isConsteval() && !llvm::EnableSingleByteCoverage)
20702101
// Create Branch Region around condition.
2071-
createBranchRegion(S->getCond(), ThenCount,
2072-
subtractCounters(ParentCount, ThenCount));
2102+
createBranchRegion(S->getCond(), ThenCount, ElseCount);
20732103
}
20742104

20752105
void VisitCXXTryStmt(const CXXTryStmt *S) {
@@ -2095,9 +2125,11 @@ struct CounterCoverageMappingBuilder
20952125
extendRegion(E);
20962126

20972127
Counter ParentCount = getRegion().getCounter();
2098-
Counter TrueCount = llvm::EnableSingleByteCoverage
2099-
? getRegionCounter(E->getTrueExpr())
2100-
: getRegionCounter(E);
2128+
auto [TrueCount, FalseCount] =
2129+
(llvm::EnableSingleByteCoverage
2130+
? std::make_pair(getRegionCounter(E->getTrueExpr()),
2131+
getRegionCounter(E->getFalseExpr()))
2132+
: getBranchCounterPair(E, ParentCount));
21012133
Counter OutCount;
21022134

21032135
if (const auto *BCO = dyn_cast<BinaryConditionalOperator>(E)) {
@@ -2116,25 +2148,20 @@ struct CounterCoverageMappingBuilder
21162148
}
21172149

21182150
extendRegion(E->getFalseExpr());
2119-
Counter FalseCount = llvm::EnableSingleByteCoverage
2120-
? getRegionCounter(E->getFalseExpr())
2121-
: subtractCounters(ParentCount, TrueCount);
2122-
21232151
Counter FalseOutCount = propagateCounts(FalseCount, E->getFalseExpr());
21242152
if (llvm::EnableSingleByteCoverage)
21252153
OutCount = getRegionCounter(E);
21262154
else
21272155
OutCount = addCounters(OutCount, FalseOutCount);
21282156

2129-
if (OutCount != ParentCount) {
2157+
if (!IsCounterEqual(OutCount, ParentCount)) {
21302158
pushRegion(OutCount);
21312159
GapRegionCounter = OutCount;
21322160
}
21332161

21342162
// Create Branch Region around condition.
21352163
if (!llvm::EnableSingleByteCoverage)
2136-
createBranchRegion(E->getCond(), TrueCount,
2137-
subtractCounters(ParentCount, TrueCount));
2164+
createBranchRegion(E->getCond(), TrueCount, FalseCount);
21382165
}
21392166

21402167
void createOrCancelDecision(const BinaryOperator *E, unsigned Since) {
@@ -2233,27 +2260,27 @@ struct CounterCoverageMappingBuilder
22332260
extendRegion(E->getRHS());
22342261
propagateCounts(getRegionCounter(E), E->getRHS());
22352262

2263+
if (llvm::EnableSingleByteCoverage)
2264+
return;
2265+
22362266
// Track RHS True/False Decision.
22372267
const auto DecisionRHS = MCDCBuilder.back();
22382268

2269+
// Extract the Parent Region Counter.
2270+
Counter ParentCnt = getRegion().getCounter();
2271+
22392272
// Extract the RHS's Execution Counter.
2240-
Counter RHSExecCnt = getRegionCounter(E);
2273+
auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt);
22412274

22422275
// Extract the RHS's "True" Instance Counter.
2243-
Counter RHSTrueCnt = getRegionCounter(E->getRHS());
2244-
2245-
// Extract the Parent Region Counter.
2246-
Counter ParentCnt = getRegion().getCounter();
2276+
auto [RHSTrueCnt, RHSExitCnt] =
2277+
getBranchCounterPair(E->getRHS(), RHSExecCnt);
22472278

22482279
// Create Branch Region around LHS condition.
2249-
if (!llvm::EnableSingleByteCoverage)
2250-
createBranchRegion(E->getLHS(), RHSExecCnt,
2251-
subtractCounters(ParentCnt, RHSExecCnt), DecisionLHS);
2280+
createBranchRegion(E->getLHS(), RHSExecCnt, LHSExitCnt, DecisionLHS);
22522281

22532282
// Create Branch Region around RHS condition.
2254-
if (!llvm::EnableSingleByteCoverage)
2255-
createBranchRegion(E->getRHS(), RHSTrueCnt,
2256-
subtractCounters(RHSExecCnt, RHSTrueCnt), DecisionRHS);
2283+
createBranchRegion(E->getRHS(), RHSTrueCnt, RHSExitCnt, DecisionRHS);
22572284

22582285
// Create MCDC Decision Region if at top-level (root).
22592286
if (IsRootNode)
@@ -2294,31 +2321,31 @@ struct CounterCoverageMappingBuilder
22942321
extendRegion(E->getRHS());
22952322
propagateCounts(getRegionCounter(E), E->getRHS());
22962323

2324+
if (llvm::EnableSingleByteCoverage)
2325+
return;
2326+
22972327
// Track RHS True/False Decision.
22982328
const auto DecisionRHS = MCDCBuilder.back();
22992329

2330+
// Extract the Parent Region Counter.
2331+
Counter ParentCnt = getRegion().getCounter();
2332+
23002333
// Extract the RHS's Execution Counter.
2301-
Counter RHSExecCnt = getRegionCounter(E);
2334+
auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt);
23022335

23032336
// Extract the RHS's "False" Instance Counter.
2304-
Counter RHSFalseCnt = getRegionCounter(E->getRHS());
2337+
auto [RHSFalseCnt, RHSExitCnt] =
2338+
getBranchCounterPair(E->getRHS(), RHSExecCnt);
23052339

23062340
if (!shouldVisitRHS(E->getLHS())) {
23072341
GapRegionCounter = OutCount;
23082342
}
23092343

2310-
// Extract the Parent Region Counter.
2311-
Counter ParentCnt = getRegion().getCounter();
2312-
23132344
// Create Branch Region around LHS condition.
2314-
if (!llvm::EnableSingleByteCoverage)
2315-
createBranchRegion(E->getLHS(), subtractCounters(ParentCnt, RHSExecCnt),
2316-
RHSExecCnt, DecisionLHS);
2345+
createBranchRegion(E->getLHS(), LHSExitCnt, RHSExecCnt, DecisionLHS);
23172346

23182347
// Create Branch Region around RHS condition.
2319-
if (!llvm::EnableSingleByteCoverage)
2320-
createBranchRegion(E->getRHS(), subtractCounters(RHSExecCnt, RHSFalseCnt),
2321-
RHSFalseCnt, DecisionRHS);
2348+
createBranchRegion(E->getRHS(), RHSExitCnt, RHSFalseCnt, DecisionRHS);
23222349

23232350
// Create MCDC Decision Region if at top-level (root).
23242351
if (IsRootNode)

0 commit comments

Comments
 (0)