@@ -941,6 +941,19 @@ struct CounterCoverageMappingBuilder
941
941
return Counter::getCounter (CounterMap[S]);
942
942
}
943
943
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
+
944
957
// / Push a region onto the stack.
945
958
// /
946
959
// / Returns the index on the stack where the region was pushed. This can be
@@ -1592,6 +1605,13 @@ struct CounterCoverageMappingBuilder
1592
1605
llvm::EnableSingleByteCoverage
1593
1606
? getRegionCounter (S->getCond ())
1594
1607
: 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
+ }
1595
1615
propagateCounts (CondCount, S->getCond ());
1596
1616
adjustForOutOfOrderTraversal (getEnd (S));
1597
1617
@@ -1600,13 +1620,11 @@ struct CounterCoverageMappingBuilder
1600
1620
if (Gap)
1601
1621
fillGapAreaWithCount (Gap->getBegin (), Gap->getEnd (), BodyCount);
1602
1622
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);
1608
1626
1609
- if (OutCount != ParentCount) {
1627
+ if (! IsCounterEqual ( OutCount, ParentCount) ) {
1610
1628
pushRegion (OutCount);
1611
1629
GapRegionCounter = OutCount;
1612
1630
if (BodyHasTerminateStmt)
@@ -1615,8 +1633,7 @@ struct CounterCoverageMappingBuilder
1615
1633
1616
1634
// Create Branch Region around condition.
1617
1635
if (!llvm::EnableSingleByteCoverage)
1618
- createBranchRegion (S->getCond (), BodyCount,
1619
- subtractCounters (CondCount, BodyCount));
1636
+ createBranchRegion (S->getCond (), BodyCount, ExitCount);
1620
1637
}
1621
1638
1622
1639
void VisitDoStmt (const DoStmt *S) {
@@ -1645,22 +1662,26 @@ struct CounterCoverageMappingBuilder
1645
1662
Counter CondCount = llvm::EnableSingleByteCoverage
1646
1663
? getRegionCounter (S->getCond ())
1647
1664
: 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
+ }
1648
1672
propagateCounts (CondCount, S->getCond ());
1649
1673
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)) {
1656
1678
pushRegion (OutCount);
1657
1679
GapRegionCounter = OutCount;
1658
1680
}
1659
1681
1660
1682
// Create Branch Region around condition.
1661
1683
if (!llvm::EnableSingleByteCoverage)
1662
- createBranchRegion (S->getCond (), BodyCount,
1663
- subtractCounters (CondCount, BodyCount));
1684
+ createBranchRegion (S->getCond (), BodyCount, ExitCount);
1664
1685
1665
1686
if (BodyHasTerminateStmt)
1666
1687
HasTerminateStmt = true ;
@@ -1709,6 +1730,13 @@ struct CounterCoverageMappingBuilder
1709
1730
: addCounters (
1710
1731
addCounters (ParentCount, BackedgeCount, BodyBC.ContinueCount ),
1711
1732
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
+ }
1712
1740
1713
1741
if (const Expr *Cond = S->getCond ()) {
1714
1742
propagateCounts (CondCount, Cond);
@@ -1723,9 +1751,8 @@ struct CounterCoverageMappingBuilder
1723
1751
Counter OutCount =
1724
1752
llvm::EnableSingleByteCoverage
1725
1753
? 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)) {
1729
1756
pushRegion (OutCount);
1730
1757
GapRegionCounter = OutCount;
1731
1758
if (BodyHasTerminateStmt)
@@ -1734,8 +1761,7 @@ struct CounterCoverageMappingBuilder
1734
1761
1735
1762
// Create Branch Region around condition.
1736
1763
if (!llvm::EnableSingleByteCoverage)
1737
- createBranchRegion (S->getCond (), BodyCount,
1738
- subtractCounters (CondCount, BodyCount));
1764
+ createBranchRegion (S->getCond (), BodyCount, ExitCount);
1739
1765
}
1740
1766
1741
1767
void VisitCXXForRangeStmt (const CXXForRangeStmt *S) {
@@ -1764,15 +1790,21 @@ struct CounterCoverageMappingBuilder
1764
1790
fillGapAreaWithCount (Gap->getBegin (), Gap->getEnd (), BodyCount);
1765
1791
1766
1792
Counter OutCount;
1793
+ Counter ExitCount;
1767
1794
Counter LoopCount;
1768
1795
if (llvm::EnableSingleByteCoverage)
1769
1796
OutCount = getRegionCounter (S);
1770
1797
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);
1774
1806
}
1775
- if (OutCount != ParentCount) {
1807
+ if (! IsCounterEqual ( OutCount, ParentCount) ) {
1776
1808
pushRegion (OutCount);
1777
1809
GapRegionCounter = OutCount;
1778
1810
if (BodyHasTerminateStmt)
@@ -1781,8 +1813,7 @@ struct CounterCoverageMappingBuilder
1781
1813
1782
1814
// Create Branch Region around condition.
1783
1815
if (!llvm::EnableSingleByteCoverage)
1784
- createBranchRegion (S->getCond (), BodyCount,
1785
- subtractCounters (LoopCount, BodyCount));
1816
+ createBranchRegion (S->getCond (), BodyCount, ExitCount);
1786
1817
}
1787
1818
1788
1819
void VisitObjCForCollectionStmt (const ObjCForCollectionStmt *S) {
@@ -1803,10 +1834,13 @@ struct CounterCoverageMappingBuilder
1803
1834
fillGapAreaWithCount (Gap->getBegin (), Gap->getEnd (), BodyCount);
1804
1835
1805
1836
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)) {
1810
1844
pushRegion (OutCount);
1811
1845
GapRegionCounter = OutCount;
1812
1846
}
@@ -2016,9 +2050,12 @@ struct CounterCoverageMappingBuilder
2016
2050
extendRegion (S->getCond ());
2017
2051
2018
2052
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));
2022
2059
2023
2060
// Emitting a counter for the condition makes it easier to interpret the
2024
2061
// counter for the body when looking at the coverage.
@@ -2033,12 +2070,6 @@ struct CounterCoverageMappingBuilder
2033
2070
extendRegion (S->getThen ());
2034
2071
Counter OutCount = propagateCounts (ThenCount, S->getThen ());
2035
2072
2036
- Counter ElseCount;
2037
- if (!llvm::EnableSingleByteCoverage)
2038
- ElseCount = subtractCounters (ParentCount, ThenCount);
2039
- else if (S->getElse ())
2040
- ElseCount = getRegionCounter (S->getElse ());
2041
-
2042
2073
if (const Stmt *Else = S->getElse ()) {
2043
2074
bool ThenHasTerminateStmt = HasTerminateStmt;
2044
2075
HasTerminateStmt = false ;
@@ -2061,15 +2092,14 @@ struct CounterCoverageMappingBuilder
2061
2092
if (llvm::EnableSingleByteCoverage)
2062
2093
OutCount = getRegionCounter (S);
2063
2094
2064
- if (OutCount != ParentCount) {
2095
+ if (! IsCounterEqual ( OutCount, ParentCount) ) {
2065
2096
pushRegion (OutCount);
2066
2097
GapRegionCounter = OutCount;
2067
2098
}
2068
2099
2069
2100
if (!S->isConsteval () && !llvm::EnableSingleByteCoverage)
2070
2101
// Create Branch Region around condition.
2071
- createBranchRegion (S->getCond (), ThenCount,
2072
- subtractCounters (ParentCount, ThenCount));
2102
+ createBranchRegion (S->getCond (), ThenCount, ElseCount);
2073
2103
}
2074
2104
2075
2105
void VisitCXXTryStmt (const CXXTryStmt *S) {
@@ -2095,9 +2125,11 @@ struct CounterCoverageMappingBuilder
2095
2125
extendRegion (E);
2096
2126
2097
2127
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));
2101
2133
Counter OutCount;
2102
2134
2103
2135
if (const auto *BCO = dyn_cast<BinaryConditionalOperator>(E)) {
@@ -2116,25 +2148,20 @@ struct CounterCoverageMappingBuilder
2116
2148
}
2117
2149
2118
2150
extendRegion (E->getFalseExpr ());
2119
- Counter FalseCount = llvm::EnableSingleByteCoverage
2120
- ? getRegionCounter (E->getFalseExpr ())
2121
- : subtractCounters (ParentCount, TrueCount);
2122
-
2123
2151
Counter FalseOutCount = propagateCounts (FalseCount, E->getFalseExpr ());
2124
2152
if (llvm::EnableSingleByteCoverage)
2125
2153
OutCount = getRegionCounter (E);
2126
2154
else
2127
2155
OutCount = addCounters (OutCount, FalseOutCount);
2128
2156
2129
- if (OutCount != ParentCount) {
2157
+ if (! IsCounterEqual ( OutCount, ParentCount) ) {
2130
2158
pushRegion (OutCount);
2131
2159
GapRegionCounter = OutCount;
2132
2160
}
2133
2161
2134
2162
// Create Branch Region around condition.
2135
2163
if (!llvm::EnableSingleByteCoverage)
2136
- createBranchRegion (E->getCond (), TrueCount,
2137
- subtractCounters (ParentCount, TrueCount));
2164
+ createBranchRegion (E->getCond (), TrueCount, FalseCount);
2138
2165
}
2139
2166
2140
2167
void createOrCancelDecision (const BinaryOperator *E, unsigned Since) {
@@ -2233,27 +2260,27 @@ struct CounterCoverageMappingBuilder
2233
2260
extendRegion (E->getRHS ());
2234
2261
propagateCounts (getRegionCounter (E), E->getRHS ());
2235
2262
2263
+ if (llvm::EnableSingleByteCoverage)
2264
+ return ;
2265
+
2236
2266
// Track RHS True/False Decision.
2237
2267
const auto DecisionRHS = MCDCBuilder.back ();
2238
2268
2269
+ // Extract the Parent Region Counter.
2270
+ Counter ParentCnt = getRegion ().getCounter ();
2271
+
2239
2272
// Extract the RHS's Execution Counter.
2240
- Counter RHSExecCnt = getRegionCounter (E );
2273
+ auto [ RHSExecCnt, LHSExitCnt] = getBranchCounterPair (E, ParentCnt );
2241
2274
2242
2275
// 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);
2247
2278
2248
2279
// 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);
2252
2281
2253
2282
// 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);
2257
2284
2258
2285
// Create MCDC Decision Region if at top-level (root).
2259
2286
if (IsRootNode)
@@ -2294,31 +2321,31 @@ struct CounterCoverageMappingBuilder
2294
2321
extendRegion (E->getRHS ());
2295
2322
propagateCounts (getRegionCounter (E), E->getRHS ());
2296
2323
2324
+ if (llvm::EnableSingleByteCoverage)
2325
+ return ;
2326
+
2297
2327
// Track RHS True/False Decision.
2298
2328
const auto DecisionRHS = MCDCBuilder.back ();
2299
2329
2330
+ // Extract the Parent Region Counter.
2331
+ Counter ParentCnt = getRegion ().getCounter ();
2332
+
2300
2333
// Extract the RHS's Execution Counter.
2301
- Counter RHSExecCnt = getRegionCounter (E );
2334
+ auto [ RHSExecCnt, LHSExitCnt] = getBranchCounterPair (E, ParentCnt );
2302
2335
2303
2336
// Extract the RHS's "False" Instance Counter.
2304
- Counter RHSFalseCnt = getRegionCounter (E->getRHS ());
2337
+ auto [RHSFalseCnt, RHSExitCnt] =
2338
+ getBranchCounterPair (E->getRHS (), RHSExecCnt);
2305
2339
2306
2340
if (!shouldVisitRHS (E->getLHS ())) {
2307
2341
GapRegionCounter = OutCount;
2308
2342
}
2309
2343
2310
- // Extract the Parent Region Counter.
2311
- Counter ParentCnt = getRegion ().getCounter ();
2312
-
2313
2344
// 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);
2317
2346
2318
2347
// 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);
2322
2349
2323
2350
// Create MCDC Decision Region if at top-level (root).
2324
2351
if (IsRootNode)
0 commit comments