Skip to content

[Coverage][Single] Enable Branch coverage for loop statements #113109

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

Open
wants to merge 56 commits into
base: users/chapuni/cov/single/nextcount
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
178b57c
[Coverage] Move SingleByteCoverage out of CountedRegion
chapuni Oct 2, 2024
aacb50d
[Coverage] Make SingleByteCoverage work consistent to merging
chapuni Oct 2, 2024
b9bbc7c
Rework. (Also reverts "[Coverage] Move SingleByteCoverage out of Cou…
chapuni Oct 5, 2024
52f072e
clang/test/CoverageMapping/single-byte-counters.cpp: Rewrite counter …
chapuni Oct 17, 2024
78e33ba
Merge branches 'users/chapuni/cov/single/test' and 'users/chapuni/cov…
chapuni Oct 21, 2024
5d19c77
[Coverage][Single] Enable Branch coverage for loop statements
chapuni Oct 18, 2024
bc708d5
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Oct 27, 2024
42735ff
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Oct 27, 2024
2842382
update
chapuni Oct 27, 2024
97a4a8f
test/llvm-cov: Transform %.c* tests to {%.test, Inputs/%.c*}
chapuni Nov 20, 2024
c50c492
Introduce test/llvm-cov/Inputs/yaml.makefile for convenience.
chapuni Nov 20, 2024
d7c5b44
Add tests for SingleByteCoverage
chapuni Nov 20, 2024
6675226
Merge branch 'users/chapuni/cov/single/test' into users/chapuni/cov/s…
chapuni Nov 20, 2024
5fc3408
Fix a test to fix linecount=1
chapuni Nov 20, 2024
d086491
Merge branch 'users/chapuni/cov/single/merge' into users/chapuni/cov/…
chapuni Nov 20, 2024
bb08de0
Merge branch 'users/chapuni/cov/single/merge' into users/chapuni/cov/…
chapuni Nov 20, 2024
8a3ef7c
Update single tests
chapuni Nov 20, 2024
e2f97d7
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Nov 20, 2024
eb7fff9
threads.c: Fixup on the clean testdir
chapuni Nov 20, 2024
7543095
Rename threads.c to threads.test since it is no longer C source file.
chapuni Nov 21, 2024
00ac90d
llvm/test/tools/llvm-cov/Inputs: Avoid wildcards `rm -rf %t*.dir`
chapuni Nov 21, 2024
fcb3ee8
Merge branch 'main' into users/chapuni/cov/single/test
chapuni Dec 21, 2024
5fa862a
Use `[[#min(C,n)]]` for tests
chapuni Dec 21, 2024
805e9a9
llvm-cov: Introduce `--binary-counters`
chapuni Dec 21, 2024
68d7b3b
Merge branch 'users/chapuni/cov/single/test' into users/chapuni/cov/s…
chapuni Dec 21, 2024
24457a7
Update tests
chapuni Dec 21, 2024
805dbd9
Merge branches 'users/chapuni/cov/single/merge' and 'users/chapuni/co…
chapuni Dec 21, 2024
f96b435
New SingleByteCoverage
chapuni Dec 21, 2024
2968ea6
Merge branch 'users/chapuni/cov/single/refactor' into users/chapuni/c…
chapuni Dec 21, 2024
cb3f959
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Dec 21, 2024
816484f
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Dec 21, 2024
47550d1
threads.c => threads.test (following #113114)
chapuni Dec 22, 2024
42c0c26
clang/test: Add tests that we missed while I was updating.
chapuni Dec 23, 2024
c0a93e2
Merge branches 'users/chapuni/cov/single/test' and 'users/chapuni/cov…
chapuni Dec 23, 2024
621263c
Update the test
chapuni Dec 23, 2024
39398a2
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Dec 23, 2024
f4dc4eb
s/Count1/BinaryCount/
chapuni Dec 23, 2024
822620b
Update desc
chapuni Dec 23, 2024
658bd48
Merge branch 'main' into users/chapuni/cov/binary
chapuni Dec 24, 2024
0780993
Merge branch 'users/chapuni/cov/binary' into users/chapuni/cov/single…
chapuni Dec 24, 2024
5dfe3e7
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Dec 24, 2024
1adf497
Eliminate (rewind) "refactor" changes
chapuni Dec 24, 2024
82b5913
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Dec 24, 2024
dfc99ba
Fix wrong merge resolutions
chapuni Dec 24, 2024
f3c9593
Reorganize CoverageMapping::SingleByteCoverage
chapuni Dec 24, 2024
3780e07
Prune commented-out line
chapuni Dec 24, 2024
894c383
Merge branch 'main' into users/chapuni/cov/single/refactor
chapuni Dec 27, 2024
7c26a2a
Merge branch 'main' into users/chapuni/cov/single/refactor
chapuni Dec 27, 2024
e11930a
Merge branch 'users/chapuni/cov/single/refactor' into users/chapuni/c…
chapuni Dec 27, 2024
ad7b753
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Dec 27, 2024
3069477
Merge branch 'main' into users/chapuni/cov/single/base
chapuni Dec 28, 2024
80d7b86
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Dec 28, 2024
e7fd5cd
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Jan 8, 2025
4428c9d
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Jan 8, 2025
bdcf47e
Merge branch 'users/chapuni/cov/single/nextcount' into users/chapuni/…
chapuni Jan 9, 2025
df025eb
Merge branch 'users/chapuni/cov/single/base' into users/chapuni/cov/s…
chapuni Jan 9, 2025
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
82 changes: 25 additions & 57 deletions clang/lib/CodeGen/CGStmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1069,15 +1069,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
SourceLocToDebugLoc(R.getEnd()),
checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S)));

// When single byte coverage mode is enabled, add a counter to loop condition.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(S.getCond());

// As long as the condition is true, go to the loop body.
llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
if (EmitBoolCondBranch) {
llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
if (ConditionScope.requiresCleanups())
if (getIsCounterPair(&S).second || ConditionScope.requiresCleanups())
ExitBlock = createBasicBlock("while.exit");
llvm::MDNode *Weights =
createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody()));
Expand All @@ -1088,6 +1084,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,

if (ExitBlock != LoopExit.getBlock()) {
EmitBlock(ExitBlock);
incrementProfileCounter(UseSkipPath, &S);
EmitBranchThroughCleanup(LoopExit);
}
} else if (const Attr *A = Stmt::getLikelihoodAttr(S.getBody())) {
Expand All @@ -1105,11 +1102,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
{
RunCleanupsScope BodyScope(*this);
EmitBlock(LoopBody);
// When single byte coverage mode is enabled, add a counter to the body.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(S.getBody());
else
incrementProfileCounter(&S);
incrementProfileCounter(UseExecPath, &S);
EmitStmt(S.getBody());
}

Expand All @@ -1129,13 +1122,10 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,

// The LoopHeader typically is just a branch if we skipped emitting
// a branch, try to erase it.
if (!EmitBoolCondBranch)
if (!EmitBoolCondBranch) {
SimplifyForwardingBlocks(LoopHeader.getBlock());

// When single byte coverage mode is enabled, add a counter to continuation
// block.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(&S);
PGO.markStmtAsUsed(true, &S);
}

if (CGM.shouldEmitConvergenceTokens())
ConvergenceTokenStack.pop_back();
Expand All @@ -1154,10 +1144,7 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
// Emit the body of the loop.
llvm::BasicBlock *LoopBody = createBasicBlock("do.body");

if (llvm::EnableSingleByteCoverage)
EmitBlockWithFallThrough(LoopBody, S.getBody());
else
EmitBlockWithFallThrough(LoopBody, &S);
EmitBlockWithFallThrough(LoopBody, &S);

if (CGM.shouldEmitConvergenceTokens())
ConvergenceTokenStack.push_back(emitConvergenceLoopToken(LoopBody));
Expand All @@ -1168,9 +1155,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
}

EmitBlock(LoopCond.getBlock());
// When single byte coverage mode is enabled, add a counter to loop condition.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(S.getCond());

// C99 6.8.5.2: "The evaluation of the controlling expression takes place
// after each execution of the loop body."
Expand All @@ -1193,16 +1177,25 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
SourceLocToDebugLoc(R.getEnd()),
checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S)));

auto *LoopFalse =
(getIsCounterPair(&S).second ? createBasicBlock("do.loopfalse")
: LoopExit.getBlock());

// As long as the condition is true, iterate the loop.
if (EmitBoolCondBranch) {
uint64_t BackedgeCount = getProfileCount(S.getBody()) - ParentCount;
Builder.CreateCondBr(
BoolCondVal, LoopBody, LoopExit.getBlock(),
BoolCondVal, LoopBody, LoopFalse,
createProfileWeightsForLoop(S.getCond(), BackedgeCount));
}

LoopStack.pop();

if (LoopFalse != LoopExit.getBlock()) {
EmitBlock(LoopFalse);
incrementProfileCounter(UseSkipPath, &S, /*UseBoth=*/true);
}

// Emit the exit block.
EmitBlock(LoopExit.getBlock());

Expand All @@ -1211,11 +1204,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
if (!EmitBoolCondBranch)
SimplifyForwardingBlocks(LoopCond.getBlock());

// When single byte coverage mode is enabled, add a counter to continuation
// block.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(&S);

if (CGM.shouldEmitConvergenceTokens())
ConvergenceTokenStack.pop_back();
}
Expand Down Expand Up @@ -1275,15 +1263,10 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
BreakContinueStack.back().ContinueBlock = Continue;
}

// When single byte coverage mode is enabled, add a counter to loop
// condition.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(S.getCond());

llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
// If there are any cleanups between here and the loop-exit scope,
// create a block to stage a loop exit along.
if (ForScope.requiresCleanups())
if (getIsCounterPair(&S).second || ForScope.requiresCleanups())
ExitBlock = createBasicBlock("for.cond.cleanup");

// As long as the condition is true, iterate the loop.
Expand All @@ -1302,20 +1285,19 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,

if (ExitBlock != LoopExit.getBlock()) {
EmitBlock(ExitBlock);
incrementProfileCounter(UseSkipPath, &S);
EmitBranchThroughCleanup(LoopExit);
}

EmitBlock(ForBody);
} else {
// Treat it as a non-zero constant. Don't even create a new block for the
// body, just fall into it.
PGO.markStmtAsUsed(true, &S);
}

// When single byte coverage mode is enabled, add a counter to the body.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(S.getBody());
else
incrementProfileCounter(&S);
incrementProfileCounter(UseExecPath, &S);

{
// Create a separate cleanup scope for the body, in case it is not
// a compound statement.
Expand All @@ -1327,8 +1309,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
if (S.getInc()) {
EmitBlock(Continue.getBlock());
EmitStmt(S.getInc());
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(S.getInc());
}

BreakContinueStack.pop_back();
Expand All @@ -1345,11 +1325,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
// Emit the fall-through block.
EmitBlock(LoopExit.getBlock(), true);

// When single byte coverage mode is enabled, add a counter to continuation
// block.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(&S);

if (CGM.shouldEmitConvergenceTokens())
ConvergenceTokenStack.pop_back();
}
Expand Down Expand Up @@ -1385,7 +1360,7 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
// If there are any cleanups between here and the loop-exit scope,
// create a block to stage a loop exit along.
llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
if (ForScope.requiresCleanups())
if (getIsCounterPair(&S).second || ForScope.requiresCleanups())
ExitBlock = createBasicBlock("for.cond.cleanup");

// The loop body, consisting of the specified body and the loop variable.
Expand All @@ -1403,14 +1378,12 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,

if (ExitBlock != LoopExit.getBlock()) {
EmitBlock(ExitBlock);
incrementProfileCounter(UseSkipPath, &S);
EmitBranchThroughCleanup(LoopExit);
}

EmitBlock(ForBody);
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(S.getBody());
else
incrementProfileCounter(&S);
incrementProfileCounter(UseExecPath, &S);

// Create a block for the increment. In case of a 'continue', we jump there.
JumpDest Continue = getJumpDestInCurrentScope("for.inc");
Expand Down Expand Up @@ -1441,11 +1414,6 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
// Emit the fall-through block.
EmitBlock(LoopExit.getBlock(), true);

// When single byte coverage mode is enabled, add a counter to continuation
// block.
if (llvm::EnableSingleByteCoverage)
incrementProfileCounter(&S);

if (CGM.shouldEmitConvergenceTokens())
ConvergenceTokenStack.pop_back();
}
Expand Down
11 changes: 2 additions & 9 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@
using namespace clang;
using namespace CodeGen;

namespace llvm {
extern cl::opt<bool> EnableSingleByteCoverage;
} // namespace llvm

/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
/// markers.
static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
Expand Down Expand Up @@ -1368,10 +1364,7 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
const Stmt *S) {
llvm::BasicBlock *SkipCountBB = nullptr;
// Do not skip over the instrumentation when single byte coverage mode is
// enabled.
if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr() &&
!llvm::EnableSingleByteCoverage) {
if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr()) {
// When instrumenting for profiling, the fallthrough to certain
// statements needs to skip over the instrumentation code so that we
// get an accurate count.
Expand All @@ -1380,7 +1373,7 @@ void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
}
EmitBlock(BB);
uint64_t CurrentCount = getCurrentProfileCount();
incrementProfileCounter(S);
incrementProfileCounter(UseExecPath, S);
setCurrentProfileCount(getCurrentProfileCount() + CurrentCount);
if (SkipCountBB)
EmitBlock(SkipCountBB);
Expand Down
79 changes: 4 additions & 75 deletions clang/lib/CodeGen/CodeGenPGO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -393,81 +393,6 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
return true;
}

bool TraverseWhileStmt(WhileStmt *While) {
// When single byte coverage mode is enabled, add a counter to condition and
// body.
bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
for (Stmt *CS : While->children()) {
if (!CS || NoSingleByteCoverage)
continue;
if (CS == While->getCond())
CounterMap[While->getCond()] = NextCounter++;
else if (CS == While->getBody())
CounterMap[While->getBody()] = NextCounter++;
}

Base::TraverseWhileStmt(While);
if (Hash.getHashVersion() != PGO_HASH_V1)
Hash.combine(PGOHash::EndOfScope);
return true;
}

bool TraverseDoStmt(DoStmt *Do) {
// When single byte coverage mode is enabled, add a counter to condition and
// body.
bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
for (Stmt *CS : Do->children()) {
if (!CS || NoSingleByteCoverage)
continue;
if (CS == Do->getCond())
CounterMap[Do->getCond()] = NextCounter++;
else if (CS == Do->getBody())
CounterMap[Do->getBody()] = NextCounter++;
}

Base::TraverseDoStmt(Do);
if (Hash.getHashVersion() != PGO_HASH_V1)
Hash.combine(PGOHash::EndOfScope);
return true;
}

bool TraverseForStmt(ForStmt *For) {
// When single byte coverage mode is enabled, add a counter to condition,
// increment and body.
bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
for (Stmt *CS : For->children()) {
if (!CS || NoSingleByteCoverage)
continue;
if (CS == For->getCond())
CounterMap[For->getCond()] = NextCounter++;
else if (CS == For->getInc())
CounterMap[For->getInc()] = NextCounter++;
else if (CS == For->getBody())
CounterMap[For->getBody()] = NextCounter++;
}

Base::TraverseForStmt(For);
if (Hash.getHashVersion() != PGO_HASH_V1)
Hash.combine(PGOHash::EndOfScope);
return true;
}

bool TraverseCXXForRangeStmt(CXXForRangeStmt *ForRange) {
// When single byte coverage mode is enabled, add a counter to body.
bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
for (Stmt *CS : ForRange->children()) {
if (!CS || NoSingleByteCoverage)
continue;
if (CS == ForRange->getBody())
CounterMap[ForRange->getBody()] = NextCounter++;
}

Base::TraverseCXXForRangeStmt(ForRange);
if (Hash.getHashVersion() != PGO_HASH_V1)
Hash.combine(PGOHash::EndOfScope);
return true;
}

// If the statement type \p N is nestable, and its nesting impacts profile
// stability, define a custom traversal which tracks the end of the statement
// in the hash (provided we're not using the V1 hash).
Expand All @@ -479,6 +404,10 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
return true; \
}

DEFINE_NESTABLE_TRAVERSAL(WhileStmt)
DEFINE_NESTABLE_TRAVERSAL(DoStmt)
DEFINE_NESTABLE_TRAVERSAL(ForStmt)
DEFINE_NESTABLE_TRAVERSAL(CXXForRangeStmt)
DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt)
DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt)
DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt)
Expand Down
Loading
Loading