Skip to content

Commit d98bf5a

Browse files
committed
[InstrProf] Single byte counters in coverage
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. 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 5c4a630 commit d98bf5a

18 files changed

+643
-102
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;
@@ -1278,7 +1282,10 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
12781282

12791283
eval.begin(CGF);
12801284
CGF.EmitBlock(LHSBlock);
1281-
CGF.incrementProfileCounter(E);
1285+
if (llvm::EnableSingleByteCoverage)
1286+
CGF.incrementProfileCounter(E->getTrueExpr());
1287+
else
1288+
CGF.incrementProfileCounter(E);
12821289
Visit(E->getTrueExpr());
12831290
eval.end(CGF);
12841291

@@ -1293,6 +1300,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
12931300

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

@@ -1301,6 +1310,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
13011310
E->getType());
13021311

13031312
CGF.EmitBlock(ContBlock);
1313+
if (llvm::EnableSingleByteCoverage)
1314+
CGF.incrementProfileCounter(E);
13041315
}
13051316

13061317
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.
@@ -1329,17 +1333,25 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
13291333

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

13381346
eval.begin(CGF);
13391347
CGF.EmitBlock(RHSBlock);
1348+
if (llvm::EnableSingleByteCoverage)
1349+
CGF.incrementProfileCounter(E->getFalseExpr());
13401350
ComplexPairTy RHS = Visit(E->getFalseExpr());
13411351
RHSBlock = Builder.GetInsertBlock();
13421352
CGF.EmitBlock(ContBlock);
1353+
if (llvm::EnableSingleByteCoverage)
1354+
CGF.incrementProfileCounter(E);
13431355
eval.end(CGF);
13441356

13451357
// 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.
@@ -4866,8 +4870,13 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
48664870

48674871
// If the dead side doesn't have labels we need, just emit the Live part.
48684872
if (!CGF.ContainsLabel(dead)) {
4869-
if (CondExprBool)
4873+
if (CondExprBool) {
4874+
if (llvm::EnableSingleByteCoverage) {
4875+
CGF.incrementProfileCounter(lhsExpr);
4876+
CGF.incrementProfileCounter(rhsExpr);
4877+
}
48704878
CGF.incrementProfileCounter(E);
4879+
}
48714880
Value *Result = Visit(live);
48724881

48734882
// If the live part is a throw expression, it acts like it has a void
@@ -4946,7 +4955,12 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
49464955
llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
49474956
llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
49484957

4949-
CGF.incrementProfileCounter(E, StepV);
4958+
if (llvm::EnableSingleByteCoverage) {
4959+
CGF.incrementProfileCounter(lhsExpr);
4960+
CGF.incrementProfileCounter(rhsExpr);
4961+
CGF.incrementProfileCounter(E);
4962+
} else
4963+
CGF.incrementProfileCounter(E, StepV);
49504964

49514965
llvm::Value *LHS = Visit(lhsExpr);
49524966
llvm::Value *RHS = Visit(rhsExpr);
@@ -4978,7 +4992,11 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
49784992
if (CGF.MCDCLogOpStack.empty())
49794993
CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
49804994

4981-
CGF.incrementProfileCounter(E);
4995+
if (llvm::EnableSingleByteCoverage)
4996+
CGF.incrementProfileCounter(lhsExpr);
4997+
else
4998+
CGF.incrementProfileCounter(E);
4999+
49825000
eval.begin(CGF);
49835001
Value *LHS = Visit(lhsExpr);
49845002
eval.end(CGF);
@@ -4994,6 +5012,9 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
49945012
if (CGF.MCDCLogOpStack.empty())
49955013
CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
49965014

5015+
if (llvm::EnableSingleByteCoverage)
5016+
CGF.incrementProfileCounter(rhsExpr);
5017+
49975018
eval.begin(CGF);
49985019
Value *RHS = Visit(rhsExpr);
49995020
eval.end(CGF);
@@ -5012,6 +5033,11 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
50125033
PN->addIncoming(LHS, LHSBlock);
50135034
PN->addIncoming(RHS, RHSBlock);
50145035

5036+
// When single byte coverage mode is enabled, add a counter to continuation
5037+
// block.
5038+
if (llvm::EnableSingleByteCoverage)
5039+
CGF.incrementProfileCounter(E);
5040+
50155041
return PN;
50165042
}
50175043

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;
@@ -853,7 +857,10 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
853857

854858
// Emit the 'then' code.
855859
EmitBlock(ThenBlock);
856-
incrementProfileCounter(&S);
860+
if (llvm::EnableSingleByteCoverage)
861+
incrementProfileCounter(S.getThen());
862+
else
863+
incrementProfileCounter(&S);
857864
{
858865
RunCleanupsScope ThenScope(*this);
859866
EmitStmt(S.getThen());
@@ -867,6 +874,9 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
867874
auto NL = ApplyDebugLocation::CreateEmpty(*this);
868875
EmitBlock(ElseBlock);
869876
}
877+
// When single byte coverage mode is enabled, add a counter to else block.
878+
if (llvm::EnableSingleByteCoverage)
879+
incrementProfileCounter(Else);
870880
{
871881
RunCleanupsScope ElseScope(*this);
872882
EmitStmt(Else);
@@ -880,6 +890,11 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
880890

881891
// Emit the continuation block for code after the if.
882892
EmitBlock(ContBlock, true);
893+
894+
// When single byte coverage mode is enabled, add a counter to continuation
895+
// block.
896+
if (llvm::EnableSingleByteCoverage)
897+
incrementProfileCounter(&S);
883898
}
884899

885900
void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
@@ -924,6 +939,10 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
924939
SourceLocToDebugLoc(R.getEnd()),
925940
checkIfLoopMustProgress(CondIsConstInt));
926941

942+
// When single byte coverage mode is enabled, add a counter to loop condition.
943+
if (llvm::EnableSingleByteCoverage)
944+
incrementProfileCounter(S.getCond());
945+
927946
// As long as the condition is true, go to the loop body.
928947
llvm::BasicBlock *LoopBody = createBasicBlock("while.body");
929948
if (EmitBoolCondBranch) {
@@ -956,7 +975,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
956975
{
957976
RunCleanupsScope BodyScope(*this);
958977
EmitBlock(LoopBody);
959-
incrementProfileCounter(&S);
978+
// When single byte coverage mode is enabled, add a counter to the body.
979+
if (llvm::EnableSingleByteCoverage)
980+
incrementProfileCounter(S.getBody());
981+
else
982+
incrementProfileCounter(&S);
960983
EmitStmt(S.getBody());
961984
}
962985

@@ -978,6 +1001,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
9781001
// a branch, try to erase it.
9791002
if (!EmitBoolCondBranch)
9801003
SimplifyForwardingBlocks(LoopHeader.getBlock());
1004+
1005+
// When single byte coverage mode is enabled, add a counter to continuation
1006+
// block.
1007+
if (llvm::EnableSingleByteCoverage)
1008+
incrementProfileCounter(&S);
9811009
}
9821010

9831011
void CodeGenFunction::EmitDoStmt(const DoStmt &S,
@@ -993,13 +1021,19 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
9931021
// Emit the body of the loop.
9941022
llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
9951023

996-
EmitBlockWithFallThrough(LoopBody, &S);
1024+
if (llvm::EnableSingleByteCoverage)
1025+
EmitBlockWithFallThrough(LoopBody, S.getBody());
1026+
else
1027+
EmitBlockWithFallThrough(LoopBody, &S);
9971028
{
9981029
RunCleanupsScope BodyScope(*this);
9991030
EmitStmt(S.getBody());
10001031
}
10011032

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

10041038
// C99 6.8.5.2: "The evaluation of the controlling expression takes place
10051039
// after each execution of the loop body."
@@ -1040,6 +1074,11 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
10401074
// emitting a branch, try to erase it.
10411075
if (!EmitBoolCondBranch)
10421076
SimplifyForwardingBlocks(LoopCond.getBlock());
1077+
1078+
// When single byte coverage mode is enabled, add a counter to continuation
1079+
// block.
1080+
if (llvm::EnableSingleByteCoverage)
1081+
incrementProfileCounter(&S);
10431082
}
10441083

10451084
void CodeGenFunction::EmitForStmt(const ForStmt &S,
@@ -1098,6 +1137,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
10981137
BreakContinueStack.back().ContinueBlock = Continue;
10991138
}
11001139

1140+
// When single byte coverage mode is enabled, add a counter to loop
1141+
// condition.
1142+
if (llvm::EnableSingleByteCoverage)
1143+
incrementProfileCounter(S.getCond());
1144+
11011145
llvm::BasicBlock *ExitBlock = LoopExit.getBlock();
11021146
// If there are any cleanups between here and the loop-exit scope,
11031147
// create a block to stage a loop exit along.
@@ -1128,8 +1172,12 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
11281172
// Treat it as a non-zero constant. Don't even create a new block for the
11291173
// body, just fall into it.
11301174
}
1131-
incrementProfileCounter(&S);
11321175

1176+
// When single byte coverage mode is enabled, add a counter to the body.
1177+
if (llvm::EnableSingleByteCoverage)
1178+
incrementProfileCounter(S.getBody());
1179+
else
1180+
incrementProfileCounter(&S);
11331181
{
11341182
// Create a separate cleanup scope for the body, in case it is not
11351183
// a compound statement.
@@ -1141,6 +1189,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
11411189
if (S.getInc()) {
11421190
EmitBlock(Continue.getBlock());
11431191
EmitStmt(S.getInc());
1192+
if (llvm::EnableSingleByteCoverage)
1193+
incrementProfileCounter(S.getInc());
11441194
}
11451195

11461196
BreakContinueStack.pop_back();
@@ -1156,6 +1206,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
11561206

11571207
// Emit the fall-through block.
11581208
EmitBlock(LoopExit.getBlock(), true);
1209+
1210+
// When single byte coverage mode is enabled, add a counter to continuation
1211+
// block.
1212+
if (llvm::EnableSingleByteCoverage)
1213+
incrementProfileCounter(&S);
11591214
}
11601215

11611216
void
@@ -1208,7 +1263,10 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
12081263
}
12091264

12101265
EmitBlock(ForBody);
1211-
incrementProfileCounter(&S);
1266+
if (llvm::EnableSingleByteCoverage)
1267+
incrementProfileCounter(S.getBody());
1268+
else
1269+
incrementProfileCounter(&S);
12121270

12131271
// Create a block for the increment. In case of a 'continue', we jump there.
12141272
JumpDest Continue = getJumpDestInCurrentScope("for.inc");
@@ -1238,6 +1296,11 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
12381296

12391297
// Emit the fall-through block.
12401298
EmitBlock(LoopExit.getBlock(), true);
1299+
1300+
// When single byte coverage mode is enabled, add a counter to continuation
1301+
// block.
1302+
if (llvm::EnableSingleByteCoverage)
1303+
incrementProfileCounter(&S);
12411304
}
12421305

12431306
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
@@ -1541,7 +1541,7 @@ class CodeGenFunction : public CodeGenTypeCache {
15411541
if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
15421542
!CurFn->hasFnAttribute(llvm::Attribute::NoProfile) &&
15431543
!CurFn->hasFnAttribute(llvm::Attribute::SkipProfile))
1544-
PGO.emitCounterIncrement(Builder, S, StepV);
1544+
PGO.emitCounterSetOrIncrement(Builder, S, StepV);
15451545
PGO.setCurrentStmt(S);
15461546
}
15471547

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -860,6 +860,7 @@ void CodeGenModule::Release() {
860860
checkAliases();
861861
EmitDeferredUnusedCoverageMappings();
862862
CodeGenPGO(*this).setValueProfilingFlag(getModule());
863+
CodeGenPGO(*this).setProfileVersion(getModule());
863864
if (CoverageMapping)
864865
CoverageMapping->emit();
865866
if (CodeGenOpts.SanitizeCfiCrossDso) {

0 commit comments

Comments
 (0)