Skip to content

Commit 23f895f

Browse files
authored
[InstrProf] Single byte counters in coverage (llvm#75425)
This patch inserts 1-byte counters instead of an 8-byte counters into llvm profiles for source-based code coverage. The origial idea was proposed as block-cov for PGO, and this patch repurposes that idea for coverage: https://groups.google.com/g/llvm-dev/c/r03Z6JoN7d4 The current 8-byte counters mechanism add counters to minimal regions, and infer the counters in the remaining regions via adding or subtracting counters. For example, it infers the counter in the if.else region by subtracting the counters between if.entry and if.then regions in an if statement. Whenever there is a control-flow merge, it adds the counters from all the incoming regions. However, we are not going to be able to infer counters by subtracting two execution counts when using single-byte counters. Therefore, this patch conservatively inserts additional counters for the cases where we need to add or subtract counters. RFC: https://discourse.llvm.org/t/rfc-single-byte-counters-for-source-based-code-coverage/75685
1 parent 7789fb6 commit 23f895f

File tree

15 files changed

+623
-92
lines changed

15 files changed

+623
-92
lines changed

clang/lib/CodeGen/CGExprAgg.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ using namespace CodeGen;
3333
// Aggregate Expression Emitter
3434
//===----------------------------------------------------------------------===//
3535

36+
namespace llvm {
37+
extern cl::opt<bool> EnableSingleByteCoverage;
38+
} // namespace llvm
39+
3640
namespace {
3741
class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
3842
CodeGenFunction &CGF;
@@ -1279,7 +1283,10 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
12791283

12801284
eval.begin(CGF);
12811285
CGF.EmitBlock(LHSBlock);
1282-
CGF.incrementProfileCounter(E);
1286+
if (llvm::EnableSingleByteCoverage)
1287+
CGF.incrementProfileCounter(E->getTrueExpr());
1288+
else
1289+
CGF.incrementProfileCounter(E);
12831290
Visit(E->getTrueExpr());
12841291
eval.end(CGF);
12851292

@@ -1294,6 +1301,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
12941301

12951302
eval.begin(CGF);
12961303
CGF.EmitBlock(RHSBlock);
1304+
if (llvm::EnableSingleByteCoverage)
1305+
CGF.incrementProfileCounter(E->getFalseExpr());
12971306
Visit(E->getFalseExpr());
12981307
eval.end(CGF);
12991308

@@ -1302,6 +1311,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
13021311
E->getType());
13031312

13041313
CGF.EmitBlock(ContBlock);
1314+
if (llvm::EnableSingleByteCoverage)
1315+
CGF.incrementProfileCounter(E);
13051316
}
13061317

13071318
void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {

clang/lib/CodeGen/CGExprComplex.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ using namespace CodeGen;
2828
// Complex Expression Emitter
2929
//===----------------------------------------------------------------------===//
3030

31+
namespace llvm {
32+
extern cl::opt<bool> EnableSingleByteCoverage;
33+
} // namespace llvm
34+
3135
typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
3236

3337
/// Return the complex type that we are meant to emit.
@@ -1330,17 +1334,25 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
13301334

13311335
eval.begin(CGF);
13321336
CGF.EmitBlock(LHSBlock);
1333-
CGF.incrementProfileCounter(E);
1337+
if (llvm::EnableSingleByteCoverage)
1338+
CGF.incrementProfileCounter(E->getTrueExpr());
1339+
else
1340+
CGF.incrementProfileCounter(E);
1341+
13341342
ComplexPairTy LHS = Visit(E->getTrueExpr());
13351343
LHSBlock = Builder.GetInsertBlock();
13361344
CGF.EmitBranch(ContBlock);
13371345
eval.end(CGF);
13381346

13391347
eval.begin(CGF);
13401348
CGF.EmitBlock(RHSBlock);
1349+
if (llvm::EnableSingleByteCoverage)
1350+
CGF.incrementProfileCounter(E->getFalseExpr());
13411351
ComplexPairTy RHS = Visit(E->getFalseExpr());
13421352
RHSBlock = Builder.GetInsertBlock();
13431353
CGF.EmitBlock(ContBlock);
1354+
if (llvm::EnableSingleByteCoverage)
1355+
CGF.incrementProfileCounter(E);
13441356
eval.end(CGF);
13451357

13461358
// Create a PHI node for the real part.

clang/lib/CodeGen/CGExprScalar.cpp

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ using llvm::Value;
5252
// Scalar Expression Emitter
5353
//===----------------------------------------------------------------------===//
5454

55+
namespace llvm {
56+
extern cl::opt<bool> EnableSingleByteCoverage;
57+
} // namespace llvm
58+
5559
namespace {
5660

5761
/// Determine whether the given binary operation may overflow.
@@ -4925,8 +4929,13 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
49254929

49264930
// If the dead side doesn't have labels we need, just emit the Live part.
49274931
if (!CGF.ContainsLabel(dead)) {
4928-
if (CondExprBool)
4932+
if (CondExprBool) {
4933+
if (llvm::EnableSingleByteCoverage) {
4934+
CGF.incrementProfileCounter(lhsExpr);
4935+
CGF.incrementProfileCounter(rhsExpr);
4936+
}
49294937
CGF.incrementProfileCounter(E);
4938+
}
49304939
Value *Result = Visit(live);
49314940

49324941
// If the live part is a throw expression, it acts like it has a void
@@ -5005,7 +5014,12 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
50055014
llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
50065015
llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
50075016

5008-
CGF.incrementProfileCounter(E, StepV);
5017+
if (llvm::EnableSingleByteCoverage) {
5018+
CGF.incrementProfileCounter(lhsExpr);
5019+
CGF.incrementProfileCounter(rhsExpr);
5020+
CGF.incrementProfileCounter(E);
5021+
} else
5022+
CGF.incrementProfileCounter(E, StepV);
50095023

50105024
llvm::Value *LHS = Visit(lhsExpr);
50115025
llvm::Value *RHS = Visit(rhsExpr);
@@ -5037,7 +5051,11 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
50375051
if (CGF.MCDCLogOpStack.empty())
50385052
CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
50395053

5040-
CGF.incrementProfileCounter(E);
5054+
if (llvm::EnableSingleByteCoverage)
5055+
CGF.incrementProfileCounter(lhsExpr);
5056+
else
5057+
CGF.incrementProfileCounter(E);
5058+
50415059
eval.begin(CGF);
50425060
Value *LHS = Visit(lhsExpr);
50435061
eval.end(CGF);
@@ -5053,6 +5071,9 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
50535071
if (CGF.MCDCLogOpStack.empty())
50545072
CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
50555073

5074+
if (llvm::EnableSingleByteCoverage)
5075+
CGF.incrementProfileCounter(rhsExpr);
5076+
50565077
eval.begin(CGF);
50575078
Value *RHS = Visit(rhsExpr);
50585079
eval.end(CGF);
@@ -5071,6 +5092,11 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
50715092
PN->addIncoming(LHS, LHSBlock);
50725093
PN->addIncoming(RHS, RHSBlock);
50735094

5095+
// When single byte coverage mode is enabled, add a counter to continuation
5096+
// block.
5097+
if (llvm::EnableSingleByteCoverage)
5098+
CGF.incrementProfileCounter(E);
5099+
50745100
return PN;
50755101
}
50765102

clang/lib/CodeGen/CGStmt.cpp

Lines changed: 68 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ using namespace CodeGen;
4343
// Statement Emission
4444
//===----------------------------------------------------------------------===//
4545

46+
namespace llvm {
47+
extern cl::opt<bool> EnableSingleByteCoverage;
48+
} // namespace llvm
49+
4650
void CodeGenFunction::EmitStopPoint(const Stmt *S) {
4751
if (CGDebugInfo *DI = getDebugInfo()) {
4852
SourceLocation Loc;
@@ -856,7 +860,10 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
856860

857861
// Emit the 'then' code.
858862
EmitBlock(ThenBlock);
859-
incrementProfileCounter(&S);
863+
if (llvm::EnableSingleByteCoverage)
864+
incrementProfileCounter(S.getThen());
865+
else
866+
incrementProfileCounter(&S);
860867
{
861868
RunCleanupsScope ThenScope(*this);
862869
EmitStmt(S.getThen());
@@ -870,6 +877,9 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
870877
auto NL = ApplyDebugLocation::CreateEmpty(*this);
871878
EmitBlock(ElseBlock);
872879
}
880+
// When single byte coverage mode is enabled, add a counter to else block.
881+
if (llvm::EnableSingleByteCoverage)
882+
incrementProfileCounter(Else);
873883
{
874884
RunCleanupsScope ElseScope(*this);
875885
EmitStmt(Else);
@@ -883,6 +893,11 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
883893

884894
// Emit the continuation block for code after the if.
885895
EmitBlock(ContBlock, true);
896+
897+
// When single byte coverage mode is enabled, add a counter to continuation
898+
// block.
899+
if (llvm::EnableSingleByteCoverage)
900+
incrementProfileCounter(&S);
886901
}
887902

888903
void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
@@ -927,6 +942,10 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
927942
SourceLocToDebugLoc(R.getEnd()),
928943
checkIfLoopMustProgress(CondIsConstInt));
929944

945+
// When single byte coverage mode is enabled, add a counter to loop condition.
946+
if (llvm::EnableSingleByteCoverage)
947+
incrementProfileCounter(S.getCond());
948+
930949
// As long as the condition is true, go to the loop body.
931950
llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
932951
if (EmitBoolCondBranch) {
@@ -959,7 +978,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
959978
{
960979
RunCleanupsScope BodyScope(*this);
961980
EmitBlock(LoopBody);
962-
incrementProfileCounter(&S);
981+
// When single byte coverage mode is enabled, add a counter to the body.
982+
if (llvm::EnableSingleByteCoverage)
983+
incrementProfileCounter(S.getBody());
984+
else
985+
incrementProfileCounter(&S);
963986
EmitStmt(S.getBody());
964987
}
965988

@@ -981,6 +1004,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
9811004
// a branch, try to erase it.
9821005
if (!EmitBoolCondBranch)
9831006
SimplifyForwardingBlocks(LoopHeader.getBlock());
1007+
1008+
// When single byte coverage mode is enabled, add a counter to continuation
1009+
// block.
1010+
if (llvm::EnableSingleByteCoverage)
1011+
incrementProfileCounter(&S);
9841012
}
9851013

9861014
void CodeGenFunction::EmitDoStmt(const DoStmt &S,
@@ -996,13 +1024,19 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
9961024
// Emit the body of the loop.
9971025
llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
9981026

999-
EmitBlockWithFallThrough(LoopBody, &S);
1027+
if (llvm::EnableSingleByteCoverage)
1028+
EmitBlockWithFallThrough(LoopBody, S.getBody());
1029+
else
1030+
EmitBlockWithFallThrough(LoopBody, &S);
10001031
{
10011032
RunCleanupsScope BodyScope(*this);
10021033
EmitStmt(S.getBody());
10031034
}
10041035

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

10071041
// C99 6.8.5.2: "The evaluation of the controlling expression takes place
10081042
// after each execution of the loop body."
@@ -1043,6 +1077,11 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
10431077
// emitting a branch, try to erase it.
10441078
if (!EmitBoolCondBranch)
10451079
SimplifyForwardingBlocks(LoopCond.getBlock());
1080+
1081+
// When single byte coverage mode is enabled, add a counter to continuation
1082+
// block.
1083+
if (llvm::EnableSingleByteCoverage)
1084+
incrementProfileCounter(&S);
10461085
}
10471086

10481087
void CodeGenFunction::EmitForStmt(const ForStmt &S,
@@ -1101,6 +1140,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
11011140
BreakContinueStack.back().ContinueBlock = Continue;
11021141
}
11031142

1143+
// When single byte coverage mode is enabled, add a counter to loop
1144+
// condition.
1145+
if (llvm::EnableSingleByteCoverage)
1146+
incrementProfileCounter(S.getCond());
1147+
11041148
llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
11051149
// If there are any cleanups between here and the loop-exit scope,
11061150
// create a block to stage a loop exit along.
@@ -1131,8 +1175,12 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
11311175
// Treat it as a non-zero constant. Don't even create a new block for the
11321176
// body, just fall into it.
11331177
}
1134-
incrementProfileCounter(&S);
11351178

1179+
// When single byte coverage mode is enabled, add a counter to the body.
1180+
if (llvm::EnableSingleByteCoverage)
1181+
incrementProfileCounter(S.getBody());
1182+
else
1183+
incrementProfileCounter(&S);
11361184
{
11371185
// Create a separate cleanup scope for the body, in case it is not
11381186
// a compound statement.
@@ -1144,6 +1192,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
11441192
if (S.getInc()) {
11451193
EmitBlock(Continue.getBlock());
11461194
EmitStmt(S.getInc());
1195+
if (llvm::EnableSingleByteCoverage)
1196+
incrementProfileCounter(S.getInc());
11471197
}
11481198

11491199
BreakContinueStack.pop_back();
@@ -1159,6 +1209,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
11591209

11601210
// Emit the fall-through block.
11611211
EmitBlock(LoopExit.getBlock(), true);
1212+
1213+
// When single byte coverage mode is enabled, add a counter to continuation
1214+
// block.
1215+
if (llvm::EnableSingleByteCoverage)
1216+
incrementProfileCounter(&S);
11621217
}
11631218

11641219
void
@@ -1211,7 +1266,10 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
12111266
}
12121267

12131268
EmitBlock(ForBody);
1214-
incrementProfileCounter(&S);
1269+
if (llvm::EnableSingleByteCoverage)
1270+
incrementProfileCounter(S.getBody());
1271+
else
1272+
incrementProfileCounter(&S);
12151273

12161274
// Create a block for the increment. In case of a 'continue', we jump there.
12171275
JumpDest Continue = getJumpDestInCurrentScope("for.inc");
@@ -1241,6 +1299,11 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
12411299

12421300
// Emit the fall-through block.
12431301
EmitBlock(LoopExit.getBlock(), true);
1302+
1303+
// When single byte coverage mode is enabled, add a counter to continuation
1304+
// block.
1305+
if (llvm::EnableSingleByteCoverage)
1306+
incrementProfileCounter(&S);
12441307
}
12451308

12461309
void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {

clang/lib/CodeGen/CodeGenFunction.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@
5252
using namespace clang;
5353
using namespace CodeGen;
5454

55+
namespace llvm {
56+
extern cl::opt<bool> EnableSingleByteCoverage;
57+
} // namespace llvm
58+
5559
/// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time
5660
/// markers.
5761
static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts,
@@ -1270,7 +1274,10 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
12701274
void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
12711275
const Stmt *S) {
12721276
llvm::BasicBlock *SkipCountBB = nullptr;
1273-
if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr()) {
1277+
// Do not skip over the instrumentation when single byte coverage mode is
1278+
// enabled.
1279+
if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr() &&
1280+
!llvm::EnableSingleByteCoverage) {
12741281
// When instrumenting for profiling, the fallthrough to certain
12751282
// statements needs to skip over the instrumentation code so that we
12761283
// get an accurate count.

clang/lib/CodeGen/CodeGenFunction.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1545,7 +1545,7 @@ class CodeGenFunction : public CodeGenTypeCache {
15451545
if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
15461546
!CurFn->hasFnAttribute(llvm::Attribute::NoProfile) &&
15471547
!CurFn->hasFnAttribute(llvm::Attribute::SkipProfile))
1548-
PGO.emitCounterIncrement(Builder, S, StepV);
1548+
PGO.emitCounterSetOrIncrement(Builder, S, StepV);
15491549
PGO.setCurrentStmt(S);
15501550
}
15511551

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -858,6 +858,7 @@ void CodeGenModule::Release() {
858858
checkAliases();
859859
EmitDeferredUnusedCoverageMappings();
860860
CodeGenPGO(*this).setValueProfilingFlag(getModule());
861+
CodeGenPGO(*this).setProfileVersion(getModule());
861862
if (CoverageMapping)
862863
CoverageMapping->emit();
863864
if (CodeGenOpts.SanitizeCfiCrossDso) {

0 commit comments

Comments
 (0)