-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[Coverage] Introduce getBranchCounterPair()
. NFC.
#112702
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
fc697f0
ad13691
58feee3
ab84f17
9d3c3b0
dbcf896
19edcd3
4e41b99
d854fb1
bac2967
6bae87d
c8edf58
f2ba219
97015cb
9a40d20
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -938,6 +938,37 @@ struct CounterCoverageMappingBuilder | |
return Counter::getCounter(CounterMap[S]); | ||
} | ||
|
||
struct BranchCounterPair { | ||
Counter Executed; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comments on member variables? E.g.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still wonder which pair of names would fit best. I adopted "Exec" from I want them self-explained. |
||
Counter Skipped; | ||
}; | ||
|
||
BranchCounterPair getBranchCounterPair(const Stmt *S, Counter ParentCnt) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we add Doxygen comments for this? I'd like to be able to know what, e.g. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. |
||
Counter ExecCnt = getRegionCounter(S); | ||
return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; | ||
} | ||
|
||
/// Returns {TrueCnt,FalseCnt} for "implicit default". | ||
/// FalseCnt is considered as the False count on SwitchStmt. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment out of date? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
std::pair<Counter, Counter> | ||
getSwitchImplicitDefaultCounterPair(const Stmt *Cond, Counter ParentCount, | ||
Counter CaseCountSum) { | ||
// Simplify is skipped while building the counters above: it can get | ||
// really slow on top of switches with thousands of cases. Instead, | ||
// trigger simplification by adding zero to the last counter. | ||
CaseCountSum = | ||
addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true); | ||
|
||
return {CaseCountSum, Builder.subtract(ParentCount, CaseCountSum)}; | ||
} | ||
|
||
bool IsCounterEqual(Counter OutCount, Counter ParentCount) { | ||
ornata marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (OutCount == ParentCount) | ||
ornata marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return true; | ||
|
||
return false; | ||
} | ||
|
||
/// Push a region onto the stack. | ||
/// | ||
/// Returns the index on the stack where the region was pushed. This can be | ||
|
@@ -1588,6 +1619,13 @@ struct CounterCoverageMappingBuilder | |
llvm::EnableSingleByteCoverage | ||
? getRegionCounter(S->getCond()) | ||
: addCounters(ParentCount, BackedgeCount, BC.ContinueCount); | ||
auto [ExecCount, ExitCount] = | ||
(llvm::EnableSingleByteCoverage | ||
? BranchCounterPair{getRegionCounter(S), Counter::getZero()} | ||
: getBranchCounterPair(S, CondCount)); | ||
if (!llvm::EnableSingleByteCoverage) { | ||
chapuni marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assert(ExecCount.isZero() || ExecCount == BodyCount); | ||
} | ||
propagateCounts(CondCount, S->getCond()); | ||
adjustForOutOfOrderTraversal(getEnd(S)); | ||
|
||
|
@@ -1596,13 +1634,11 @@ struct CounterCoverageMappingBuilder | |
if (Gap) | ||
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); | ||
|
||
Counter OutCount = | ||
llvm::EnableSingleByteCoverage | ||
? getRegionCounter(S) | ||
: addCounters(BC.BreakCount, | ||
subtractCounters(CondCount, BodyCount)); | ||
Counter OutCount = llvm::EnableSingleByteCoverage | ||
? getRegionCounter(S) | ||
: addCounters(BC.BreakCount, ExitCount); | ||
|
||
if (OutCount != ParentCount) { | ||
if (!IsCounterEqual(OutCount, ParentCount)) { | ||
pushRegion(OutCount); | ||
GapRegionCounter = OutCount; | ||
if (BodyHasTerminateStmt) | ||
|
@@ -1611,8 +1647,7 @@ struct CounterCoverageMappingBuilder | |
|
||
// Create Branch Region around condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(S->getCond(), BodyCount, | ||
subtractCounters(CondCount, BodyCount)); | ||
createBranchRegion(S->getCond(), BodyCount, ExitCount); | ||
} | ||
|
||
void VisitDoStmt(const DoStmt *S) { | ||
|
@@ -1641,22 +1676,26 @@ struct CounterCoverageMappingBuilder | |
Counter CondCount = llvm::EnableSingleByteCoverage | ||
? getRegionCounter(S->getCond()) | ||
: addCounters(BackedgeCount, BC.ContinueCount); | ||
auto [ExecCount, ExitCount] = | ||
(llvm::EnableSingleByteCoverage | ||
? BranchCounterPair{getRegionCounter(S), Counter::getZero()} | ||
: getBranchCounterPair(S, CondCount)); | ||
if (!llvm::EnableSingleByteCoverage) { | ||
chapuni marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assert(ExecCount.isZero() || ExecCount == BodyCount); | ||
} | ||
propagateCounts(CondCount, S->getCond()); | ||
|
||
Counter OutCount = | ||
llvm::EnableSingleByteCoverage | ||
? getRegionCounter(S) | ||
: addCounters(BC.BreakCount, | ||
subtractCounters(CondCount, BodyCount)); | ||
if (OutCount != ParentCount) { | ||
Counter OutCount = llvm::EnableSingleByteCoverage | ||
? getRegionCounter(S) | ||
: addCounters(BC.BreakCount, ExitCount); | ||
if (!IsCounterEqual(OutCount, ParentCount)) { | ||
pushRegion(OutCount); | ||
GapRegionCounter = OutCount; | ||
} | ||
|
||
// Create Branch Region around condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(S->getCond(), BodyCount, | ||
subtractCounters(CondCount, BodyCount)); | ||
createBranchRegion(S->getCond(), BodyCount, ExitCount); | ||
|
||
if (BodyHasTerminateStmt) | ||
HasTerminateStmt = true; | ||
|
@@ -1705,6 +1744,13 @@ struct CounterCoverageMappingBuilder | |
: addCounters( | ||
addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), | ||
IncrementBC.ContinueCount); | ||
auto [ExecCount, ExitCount] = | ||
(llvm::EnableSingleByteCoverage | ||
ornata marked this conversation as resolved.
Show resolved
Hide resolved
|
||
? BranchCounterPair{getRegionCounter(S), Counter::getZero()} | ||
: getBranchCounterPair(S, CondCount)); | ||
if (!llvm::EnableSingleByteCoverage) { | ||
chapuni marked this conversation as resolved.
Show resolved
Hide resolved
|
||
assert(ExecCount.isZero() || ExecCount == BodyCount); | ||
} | ||
|
||
if (const Expr *Cond = S->getCond()) { | ||
propagateCounts(CondCount, Cond); | ||
|
@@ -1719,9 +1765,8 @@ struct CounterCoverageMappingBuilder | |
Counter OutCount = | ||
llvm::EnableSingleByteCoverage | ||
? getRegionCounter(S) | ||
: addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, | ||
subtractCounters(CondCount, BodyCount)); | ||
if (OutCount != ParentCount) { | ||
: addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, ExitCount); | ||
if (!IsCounterEqual(OutCount, ParentCount)) { | ||
pushRegion(OutCount); | ||
GapRegionCounter = OutCount; | ||
if (BodyHasTerminateStmt) | ||
|
@@ -1730,8 +1775,7 @@ struct CounterCoverageMappingBuilder | |
|
||
// Create Branch Region around condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(S->getCond(), BodyCount, | ||
subtractCounters(CondCount, BodyCount)); | ||
createBranchRegion(S->getCond(), BodyCount, ExitCount); | ||
} | ||
|
||
void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { | ||
|
@@ -1760,15 +1804,18 @@ struct CounterCoverageMappingBuilder | |
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); | ||
|
||
Counter OutCount; | ||
Counter ExitCount; | ||
Counter LoopCount; | ||
if (llvm::EnableSingleByteCoverage) | ||
OutCount = getRegionCounter(S); | ||
else { | ||
LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); | ||
OutCount = | ||
addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); | ||
auto [ExecCount, SkipCount] = getBranchCounterPair(S, LoopCount); | ||
ExitCount = SkipCount; | ||
assert(ExecCount.isZero() || ExecCount == BodyCount); | ||
OutCount = addCounters(BC.BreakCount, ExitCount); | ||
} | ||
if (OutCount != ParentCount) { | ||
if (!IsCounterEqual(OutCount, ParentCount)) { | ||
pushRegion(OutCount); | ||
GapRegionCounter = OutCount; | ||
if (BodyHasTerminateStmt) | ||
|
@@ -1777,8 +1824,7 @@ struct CounterCoverageMappingBuilder | |
|
||
// Create Branch Region around condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(S->getCond(), BodyCount, | ||
subtractCounters(LoopCount, BodyCount)); | ||
createBranchRegion(S->getCond(), BodyCount, ExitCount); | ||
} | ||
|
||
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { | ||
|
@@ -1800,9 +1846,10 @@ struct CounterCoverageMappingBuilder | |
|
||
Counter LoopCount = | ||
addCounters(ParentCount, BackedgeCount, BC.ContinueCount); | ||
Counter OutCount = | ||
addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); | ||
if (OutCount != ParentCount) { | ||
auto [ExecCount, ExitCount] = getBranchCounterPair(S, LoopCount); | ||
assert(ExecCount.isZero() || ExecCount == BodyCount); | ||
Counter OutCount = addCounters(BC.BreakCount, ExitCount); | ||
ornata marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (!IsCounterEqual(OutCount, ParentCount)) { | ||
pushRegion(OutCount); | ||
GapRegionCounter = OutCount; | ||
} | ||
|
@@ -1873,15 +1920,9 @@ struct CounterCoverageMappingBuilder | |
// the hidden branch, which will be added later by the CodeGen. This region | ||
// will be associated with the switch statement's condition. | ||
if (!HasDefaultCase) { | ||
// Simplify is skipped while building the counters above: it can get | ||
// really slow on top of switches with thousands of cases. Instead, | ||
// trigger simplification by adding zero to the last counter. | ||
CaseCountSum = | ||
addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true); | ||
|
||
// This is considered as the False count on SwitchStmt. | ||
Counter SwitchFalse = subtractCounters(ParentCount, CaseCountSum); | ||
createBranchRegion(S->getCond(), CaseCountSum, SwitchFalse); | ||
auto Counters = getSwitchImplicitDefaultCounterPair( | ||
S->getCond(), ParentCount, CaseCountSum); | ||
createBranchRegion(S->getCond(), Counters.first, Counters.second); | ||
} | ||
} | ||
|
||
|
@@ -2010,9 +2051,12 @@ struct CounterCoverageMappingBuilder | |
extendRegion(S->getCond()); | ||
|
||
Counter ParentCount = getRegion().getCounter(); | ||
Counter ThenCount = llvm::EnableSingleByteCoverage | ||
? getRegionCounter(S->getThen()) | ||
: getRegionCounter(S); | ||
auto [ThenCount, ElseCount] = | ||
(llvm::EnableSingleByteCoverage | ||
? BranchCounterPair{getRegionCounter(S->getThen()), | ||
(S->getElse() ? getRegionCounter(S->getElse()) | ||
: Counter::getZero())} | ||
: getBranchCounterPair(S, ParentCount)); | ||
|
||
// Emitting a counter for the condition makes it easier to interpret the | ||
// counter for the body when looking at the coverage. | ||
|
@@ -2027,12 +2071,6 @@ struct CounterCoverageMappingBuilder | |
extendRegion(S->getThen()); | ||
Counter OutCount = propagateCounts(ThenCount, S->getThen()); | ||
|
||
Counter ElseCount; | ||
if (!llvm::EnableSingleByteCoverage) | ||
ElseCount = subtractCounters(ParentCount, ThenCount); | ||
else if (S->getElse()) | ||
ElseCount = getRegionCounter(S->getElse()); | ||
|
||
if (const Stmt *Else = S->getElse()) { | ||
bool ThenHasTerminateStmt = HasTerminateStmt; | ||
HasTerminateStmt = false; | ||
|
@@ -2055,15 +2093,14 @@ struct CounterCoverageMappingBuilder | |
if (llvm::EnableSingleByteCoverage) | ||
OutCount = getRegionCounter(S); | ||
|
||
if (OutCount != ParentCount) { | ||
if (!IsCounterEqual(OutCount, ParentCount)) { | ||
pushRegion(OutCount); | ||
GapRegionCounter = OutCount; | ||
} | ||
|
||
if (!llvm::EnableSingleByteCoverage) | ||
// Create Branch Region around condition. | ||
createBranchRegion(S->getCond(), ThenCount, | ||
subtractCounters(ParentCount, ThenCount)); | ||
createBranchRegion(S->getCond(), ThenCount, ElseCount); | ||
} | ||
|
||
void VisitCXXTryStmt(const CXXTryStmt *S) { | ||
|
@@ -2089,9 +2126,11 @@ struct CounterCoverageMappingBuilder | |
extendRegion(E); | ||
|
||
Counter ParentCount = getRegion().getCounter(); | ||
Counter TrueCount = llvm::EnableSingleByteCoverage | ||
? getRegionCounter(E->getTrueExpr()) | ||
: getRegionCounter(E); | ||
auto [TrueCount, FalseCount] = | ||
(llvm::EnableSingleByteCoverage | ||
? BranchCounterPair{getRegionCounter(E->getTrueExpr()), | ||
getRegionCounter(E->getFalseExpr())} | ||
: getBranchCounterPair(E, ParentCount)); | ||
Counter OutCount; | ||
|
||
if (const auto *BCO = dyn_cast<BinaryConditionalOperator>(E)) { | ||
|
@@ -2110,25 +2149,20 @@ struct CounterCoverageMappingBuilder | |
} | ||
|
||
extendRegion(E->getFalseExpr()); | ||
Counter FalseCount = llvm::EnableSingleByteCoverage | ||
? getRegionCounter(E->getFalseExpr()) | ||
: subtractCounters(ParentCount, TrueCount); | ||
|
||
Counter FalseOutCount = propagateCounts(FalseCount, E->getFalseExpr()); | ||
if (llvm::EnableSingleByteCoverage) | ||
OutCount = getRegionCounter(E); | ||
else | ||
OutCount = addCounters(OutCount, FalseOutCount); | ||
|
||
if (OutCount != ParentCount) { | ||
if (!IsCounterEqual(OutCount, ParentCount)) { | ||
pushRegion(OutCount); | ||
GapRegionCounter = OutCount; | ||
} | ||
|
||
// Create Branch Region around condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(E->getCond(), TrueCount, | ||
subtractCounters(ParentCount, TrueCount)); | ||
createBranchRegion(E->getCond(), TrueCount, FalseCount); | ||
} | ||
|
||
void createOrCancelDecision(const BinaryOperator *E, unsigned Since) { | ||
|
@@ -2227,27 +2261,27 @@ struct CounterCoverageMappingBuilder | |
extendRegion(E->getRHS()); | ||
propagateCounts(getRegionCounter(E), E->getRHS()); | ||
|
||
if (llvm::EnableSingleByteCoverage) | ||
ornata marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return; | ||
|
||
// Track RHS True/False Decision. | ||
const auto DecisionRHS = MCDCBuilder.back(); | ||
|
||
// Extract the Parent Region Counter. | ||
Counter ParentCnt = getRegion().getCounter(); | ||
|
||
// Extract the RHS's Execution Counter. | ||
Counter RHSExecCnt = getRegionCounter(E); | ||
auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt); | ||
|
||
// Extract the RHS's "True" Instance Counter. | ||
Counter RHSTrueCnt = getRegionCounter(E->getRHS()); | ||
|
||
// Extract the Parent Region Counter. | ||
Counter ParentCnt = getRegion().getCounter(); | ||
auto [RHSTrueCnt, RHSExitCnt] = | ||
getBranchCounterPair(E->getRHS(), RHSExecCnt); | ||
|
||
// Create Branch Region around LHS condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(E->getLHS(), RHSExecCnt, | ||
subtractCounters(ParentCnt, RHSExecCnt), DecisionLHS); | ||
createBranchRegion(E->getLHS(), RHSExecCnt, LHSExitCnt, DecisionLHS); | ||
|
||
// Create Branch Region around RHS condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(E->getRHS(), RHSTrueCnt, | ||
subtractCounters(RHSExecCnt, RHSTrueCnt), DecisionRHS); | ||
createBranchRegion(E->getRHS(), RHSTrueCnt, RHSExitCnt, DecisionRHS); | ||
|
||
// Create MCDC Decision Region if at top-level (root). | ||
if (IsRootNode) | ||
|
@@ -2288,31 +2322,31 @@ struct CounterCoverageMappingBuilder | |
extendRegion(E->getRHS()); | ||
propagateCounts(getRegionCounter(E), E->getRHS()); | ||
|
||
if (llvm::EnableSingleByteCoverage) | ||
return; | ||
|
||
// Track RHS True/False Decision. | ||
const auto DecisionRHS = MCDCBuilder.back(); | ||
|
||
// Extract the Parent Region Counter. | ||
Counter ParentCnt = getRegion().getCounter(); | ||
|
||
// Extract the RHS's Execution Counter. | ||
Counter RHSExecCnt = getRegionCounter(E); | ||
auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt); | ||
|
||
// Extract the RHS's "False" Instance Counter. | ||
Counter RHSFalseCnt = getRegionCounter(E->getRHS()); | ||
auto [RHSFalseCnt, RHSExitCnt] = | ||
getBranchCounterPair(E->getRHS(), RHSExecCnt); | ||
|
||
if (!shouldVisitRHS(E->getLHS())) { | ||
GapRegionCounter = OutCount; | ||
} | ||
|
||
// Extract the Parent Region Counter. | ||
Counter ParentCnt = getRegion().getCounter(); | ||
|
||
// Create Branch Region around LHS condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(E->getLHS(), subtractCounters(ParentCnt, RHSExecCnt), | ||
RHSExecCnt, DecisionLHS); | ||
createBranchRegion(E->getLHS(), LHSExitCnt, RHSExecCnt, DecisionLHS); | ||
|
||
// Create Branch Region around RHS condition. | ||
if (!llvm::EnableSingleByteCoverage) | ||
createBranchRegion(E->getRHS(), subtractCounters(RHSExecCnt, RHSFalseCnt), | ||
RHSFalseCnt, DecisionRHS); | ||
createBranchRegion(E->getRHS(), RHSExitCnt, RHSFalseCnt, DecisionRHS); | ||
|
||
// Create MCDC Decision Region if at top-level (root). | ||
if (IsRootNode) | ||
|
Uh oh!
There was an error while loading. Please reload this page.