Skip to content

[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

Merged
merged 15 commits into from
Jan 9, 2025
Merged
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 95 additions & 73 deletions clang/lib/CodeGen/CoverageMappingGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,19 @@ struct CounterCoverageMappingBuilder
return Counter::getCounter(CounterMap[S]);
}

std::pair<Counter, Counter> getBranchCounterPair(const Stmt *S,
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's not immediately obvious what the pair represents from this function name.

getExecutionCountAnd...?

or, make a lightweight POD struct to represent this

struct ExecCntAnd... { 
  Counter ExecCnt
  Counter ...
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like a silly std::pair :) Let me think more.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think changing the name is sufficient for making me less confused

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done but I am still dubious namings would be appropriate. Not all users expect [Exec, Skip], but [Exec, Exit] or similar. Do you have a better idea to resolve namings (not by structural assignments but by name)?

Counter ParentCnt) {
Counter ExecCnt = getRegionCounter(S);
return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)};
}

bool IsCounterEqual(Counter OutCount, Counter ParentCount) {
if (OutCount == ParentCount)
return true;

return false;
}

/// Push a region onto the stack.
///
/// Returns the index on the stack where the region was pushed. This can be
Expand Down Expand Up @@ -1592,6 +1605,13 @@ struct CounterCoverageMappingBuilder
llvm::EnableSingleByteCoverage
? getRegionCounter(S->getCond())
: addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
auto [ExecCount, ExitCount] =
(llvm::EnableSingleByteCoverage
? std::make_pair(getRegionCounter(S), Counter::getZero())
: getBranchCounterPair(S, CondCount));
if (!llvm::EnableSingleByteCoverage) {
assert(ExecCount.isZero() || ExecCount == BodyCount);
}
propagateCounts(CondCount, S->getCond());
adjustForOutOfOrderTraversal(getEnd(S));

Expand All @@ -1600,13 +1620,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)
Expand All @@ -1615,8 +1633,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) {
Expand Down Expand Up @@ -1645,22 +1662,26 @@ struct CounterCoverageMappingBuilder
Counter CondCount = llvm::EnableSingleByteCoverage
? getRegionCounter(S->getCond())
: addCounters(BackedgeCount, BC.ContinueCount);
auto [ExecCount, ExitCount] =
(llvm::EnableSingleByteCoverage
? std::make_pair(getRegionCounter(S), Counter::getZero())
: getBranchCounterPair(S, CondCount));
if (!llvm::EnableSingleByteCoverage) {
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;
Expand Down Expand Up @@ -1709,6 +1730,13 @@ struct CounterCoverageMappingBuilder
: addCounters(
addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount),
IncrementBC.ContinueCount);
auto [ExecCount, ExitCount] =
(llvm::EnableSingleByteCoverage
? std::make_pair(getRegionCounter(S), Counter::getZero())
: getBranchCounterPair(S, CondCount));
if (!llvm::EnableSingleByteCoverage) {
assert(ExecCount.isZero() || ExecCount == BodyCount);
}

if (const Expr *Cond = S->getCond()) {
propagateCounts(CondCount, Cond);
Expand All @@ -1723,9 +1751,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)
Expand All @@ -1734,8 +1761,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) {
Expand Down Expand Up @@ -1764,15 +1790,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)
Expand All @@ -1781,8 +1810,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) {
Expand All @@ -1804,9 +1832,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);
if (!IsCounterEqual(OutCount, ParentCount)) {
pushRegion(OutCount);
GapRegionCounter = OutCount;
}
Expand Down Expand Up @@ -2016,9 +2045,12 @@ struct CounterCoverageMappingBuilder
extendRegion(S->getCond());

Counter ParentCount = getRegion().getCounter();
Counter ThenCount = llvm::EnableSingleByteCoverage
? getRegionCounter(S->getThen())
: getRegionCounter(S);
auto [ThenCount, ElseCount] =
(llvm::EnableSingleByteCoverage
? std::make_pair(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.
Expand All @@ -2033,12 +2065,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;
Expand All @@ -2061,15 +2087,14 @@ struct CounterCoverageMappingBuilder
if (llvm::EnableSingleByteCoverage)
OutCount = getRegionCounter(S);

if (OutCount != ParentCount) {
if (!IsCounterEqual(OutCount, ParentCount)) {
pushRegion(OutCount);
GapRegionCounter = OutCount;
}

if (!S->isConsteval() && !llvm::EnableSingleByteCoverage)
// Create Branch Region around condition.
createBranchRegion(S->getCond(), ThenCount,
subtractCounters(ParentCount, ThenCount));
createBranchRegion(S->getCond(), ThenCount, ElseCount);
}

void VisitCXXTryStmt(const CXXTryStmt *S) {
Expand All @@ -2095,9 +2120,11 @@ struct CounterCoverageMappingBuilder
extendRegion(E);

Counter ParentCount = getRegion().getCounter();
Counter TrueCount = llvm::EnableSingleByteCoverage
? getRegionCounter(E->getTrueExpr())
: getRegionCounter(E);
auto [TrueCount, FalseCount] =
(llvm::EnableSingleByteCoverage
? std::make_pair(getRegionCounter(E->getTrueExpr()),
getRegionCounter(E->getFalseExpr()))
: getBranchCounterPair(E, ParentCount));
Counter OutCount;

if (const auto *BCO = dyn_cast<BinaryConditionalOperator>(E)) {
Expand All @@ -2116,25 +2143,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) {
Expand Down Expand Up @@ -2233,27 +2255,27 @@ 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 "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)
Expand Down Expand Up @@ -2294,31 +2316,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)
Expand Down
Loading