aboutsummaryrefslogtreecommitdiff
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/CodeGen/CGExprAgg.cpp13
-rw-r--r--clang/lib/CodeGen/CGExprComplex.cpp14
-rw-r--r--clang/lib/CodeGen/CGExprScalar.cpp32
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp73
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp9
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h2
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp1
-rw-r--r--clang/lib/CodeGen/CodeGenPGO.cpp150
-rw-r--r--clang/lib/CodeGen/CodeGenPGO.h6
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.cpp206
10 files changed, 425 insertions, 81 deletions
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index d0d6202..5190b22 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -33,6 +33,10 @@ using namespace CodeGen;
// Aggregate Expression Emitter
//===----------------------------------------------------------------------===//
+namespace llvm {
+extern cl::opt<bool> EnableSingleByteCoverage;
+} // namespace llvm
+
namespace {
class AggExprEmitter : public StmtVisitor<AggExprEmitter> {
CodeGenFunction &CGF;
@@ -1279,7 +1283,10 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
eval.begin(CGF);
CGF.EmitBlock(LHSBlock);
- CGF.incrementProfileCounter(E);
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(E->getTrueExpr());
+ else
+ CGF.incrementProfileCounter(E);
Visit(E->getTrueExpr());
eval.end(CGF);
@@ -1294,6 +1301,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
eval.begin(CGF);
CGF.EmitBlock(RHSBlock);
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(E->getFalseExpr());
Visit(E->getFalseExpr());
eval.end(CGF);
@@ -1302,6 +1311,8 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
E->getType());
CGF.EmitBlock(ContBlock);
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(E);
}
void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) {
diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
index 176a7e0..0266ba9 100644
--- a/clang/lib/CodeGen/CGExprComplex.cpp
+++ b/clang/lib/CodeGen/CGExprComplex.cpp
@@ -28,6 +28,10 @@ using namespace CodeGen;
// Complex Expression Emitter
//===----------------------------------------------------------------------===//
+namespace llvm {
+extern cl::opt<bool> EnableSingleByteCoverage;
+} // namespace llvm
+
typedef CodeGenFunction::ComplexPairTy ComplexPairTy;
/// Return the complex type that we are meant to emit.
@@ -1330,7 +1334,11 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
eval.begin(CGF);
CGF.EmitBlock(LHSBlock);
- CGF.incrementProfileCounter(E);
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(E->getTrueExpr());
+ else
+ CGF.incrementProfileCounter(E);
+
ComplexPairTy LHS = Visit(E->getTrueExpr());
LHSBlock = Builder.GetInsertBlock();
CGF.EmitBranch(ContBlock);
@@ -1338,9 +1346,13 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
eval.begin(CGF);
CGF.EmitBlock(RHSBlock);
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(E->getFalseExpr());
ComplexPairTy RHS = Visit(E->getFalseExpr());
RHSBlock = Builder.GetInsertBlock();
CGF.EmitBlock(ContBlock);
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(E);
eval.end(CGF);
// Create a PHI node for the real part.
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 10b7457..8536570 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -52,6 +52,10 @@ using llvm::Value;
// Scalar Expression Emitter
//===----------------------------------------------------------------------===//
+namespace llvm {
+extern cl::opt<bool> EnableSingleByteCoverage;
+} // namespace llvm
+
namespace {
/// Determine whether the given binary operation may overflow.
@@ -4925,8 +4929,13 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
// If the dead side doesn't have labels we need, just emit the Live part.
if (!CGF.ContainsLabel(dead)) {
- if (CondExprBool)
+ if (CondExprBool) {
+ if (llvm::EnableSingleByteCoverage) {
+ CGF.incrementProfileCounter(lhsExpr);
+ CGF.incrementProfileCounter(rhsExpr);
+ }
CGF.incrementProfileCounter(E);
+ }
Value *Result = Visit(live);
// If the live part is a throw expression, it acts like it has a void
@@ -5005,7 +5014,12 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr);
llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty);
- CGF.incrementProfileCounter(E, StepV);
+ if (llvm::EnableSingleByteCoverage) {
+ CGF.incrementProfileCounter(lhsExpr);
+ CGF.incrementProfileCounter(rhsExpr);
+ CGF.incrementProfileCounter(E);
+ } else
+ CGF.incrementProfileCounter(E, StepV);
llvm::Value *LHS = Visit(lhsExpr);
llvm::Value *RHS = Visit(rhsExpr);
@@ -5037,7 +5051,11 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
if (CGF.MCDCLogOpStack.empty())
CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
- CGF.incrementProfileCounter(E);
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(lhsExpr);
+ else
+ CGF.incrementProfileCounter(E);
+
eval.begin(CGF);
Value *LHS = Visit(lhsExpr);
eval.end(CGF);
@@ -5053,6 +5071,9 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
if (CGF.MCDCLogOpStack.empty())
CGF.maybeUpdateMCDCTestVectorBitmap(condExpr);
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(rhsExpr);
+
eval.begin(CGF);
Value *RHS = Visit(rhsExpr);
eval.end(CGF);
@@ -5071,6 +5092,11 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) {
PN->addIncoming(LHS, LHSBlock);
PN->addIncoming(RHS, RHSBlock);
+ // When single byte coverage mode is enabled, add a counter to continuation
+ // block.
+ if (llvm::EnableSingleByteCoverage)
+ CGF.incrementProfileCounter(E);
+
return PN;
}
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index af51875..d0a3a71 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -43,6 +43,10 @@ using namespace CodeGen;
// Statement Emission
//===----------------------------------------------------------------------===//
+namespace llvm {
+extern cl::opt<bool> EnableSingleByteCoverage;
+} // namespace llvm
+
void CodeGenFunction::EmitStopPoint(const Stmt *S) {
if (CGDebugInfo *DI = getDebugInfo()) {
SourceLocation Loc;
@@ -856,7 +860,10 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// Emit the 'then' code.
EmitBlock(ThenBlock);
- incrementProfileCounter(&S);
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(S.getThen());
+ else
+ incrementProfileCounter(&S);
{
RunCleanupsScope ThenScope(*this);
EmitStmt(S.getThen());
@@ -870,6 +877,9 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
auto NL = ApplyDebugLocation::CreateEmpty(*this);
EmitBlock(ElseBlock);
}
+ // When single byte coverage mode is enabled, add a counter to else block.
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(Else);
{
RunCleanupsScope ElseScope(*this);
EmitStmt(Else);
@@ -883,6 +893,11 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) {
// Emit the continuation block for code after the if.
EmitBlock(ContBlock, true);
+
+ // When single byte coverage mode is enabled, add a counter to continuation
+ // block.
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(&S);
}
void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
@@ -927,6 +942,10 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
SourceLocToDebugLoc(R.getEnd()),
checkIfLoopMustProgress(CondIsConstInt));
+ // 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) {
@@ -959,7 +978,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
{
RunCleanupsScope BodyScope(*this);
EmitBlock(LoopBody);
- incrementProfileCounter(&S);
+ // When single byte coverage mode is enabled, add a counter to the body.
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(S.getBody());
+ else
+ incrementProfileCounter(&S);
EmitStmt(S.getBody());
}
@@ -981,6 +1004,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S,
// a branch, try to erase it.
if (!EmitBoolCondBranch)
SimplifyForwardingBlocks(LoopHeader.getBlock());
+
+ // When single byte coverage mode is enabled, add a counter to continuation
+ // block.
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(&S);
}
void CodeGenFunction::EmitDoStmt(const DoStmt &S,
@@ -996,13 +1024,19 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
// Emit the body of the loop.
llvm::BasicBlock *LoopBody = createBasicBlock("do.body");
- EmitBlockWithFallThrough(LoopBody, &S);
+ if (llvm::EnableSingleByteCoverage)
+ EmitBlockWithFallThrough(LoopBody, S.getBody());
+ else
+ EmitBlockWithFallThrough(LoopBody, &S);
{
RunCleanupsScope BodyScope(*this);
EmitStmt(S.getBody());
}
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."
@@ -1043,6 +1077,11 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S,
// emitting a branch, try to erase it.
if (!EmitBoolCondBranch)
SimplifyForwardingBlocks(LoopCond.getBlock());
+
+ // When single byte coverage mode is enabled, add a counter to continuation
+ // block.
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(&S);
}
void CodeGenFunction::EmitForStmt(const ForStmt &S,
@@ -1101,6 +1140,11 @@ 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.
@@ -1131,8 +1175,12 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
// Treat it as a non-zero constant. Don't even create a new block for the
// body, just fall into it.
}
- incrementProfileCounter(&S);
+ // When single byte coverage mode is enabled, add a counter to the body.
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(S.getBody());
+ else
+ incrementProfileCounter(&S);
{
// Create a separate cleanup scope for the body, in case it is not
// a compound statement.
@@ -1144,6 +1192,8 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S,
if (S.getInc()) {
EmitBlock(Continue.getBlock());
EmitStmt(S.getInc());
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(S.getInc());
}
BreakContinueStack.pop_back();
@@ -1159,6 +1209,11 @@ 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);
}
void
@@ -1211,7 +1266,10 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S,
}
EmitBlock(ForBody);
- incrementProfileCounter(&S);
+ if (llvm::EnableSingleByteCoverage)
+ incrementProfileCounter(S.getBody());
+ else
+ incrementProfileCounter(&S);
// Create a block for the increment. In case of a 'continue', we jump there.
JumpDest Continue = getJumpDestInCurrentScope("for.inc");
@@ -1241,6 +1299,11 @@ 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);
}
void CodeGenFunction::EmitReturnOfRValue(RValue RV, QualType Ty) {
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 1ad9050..b87fc86 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -52,6 +52,10 @@
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,
@@ -1270,7 +1274,10 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) {
void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB,
const Stmt *S) {
llvm::BasicBlock *SkipCountBB = nullptr;
- if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr()) {
+ // Do not skip over the instrumentation when single byte coverage mode is
+ // enabled.
+ if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr() &&
+ !llvm::EnableSingleByteCoverage) {
// When instrumenting for profiling, the fallthrough to certain
// statements needs to skip over the instrumentation code so that we
// get an accurate count.
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index b2800f6..06327a1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1545,7 +1545,7 @@ public:
if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
!CurFn->hasFnAttribute(llvm::Attribute::NoProfile) &&
!CurFn->hasFnAttribute(llvm::Attribute::SkipProfile))
- PGO.emitCounterIncrement(Builder, S, StepV);
+ PGO.emitCounterSetOrIncrement(Builder, S, StepV);
PGO.setCurrentStmt(S);
}
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 95e457b..1550b00 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -858,6 +858,7 @@ void CodeGenModule::Release() {
checkAliases();
EmitDeferredUnusedCoverageMappings();
CodeGenPGO(*this).setValueProfilingFlag(getModule());
+ CodeGenPGO(*this).setProfileVersion(getModule());
if (CoverageMapping)
CoverageMapping->emit();
if (CodeGenOpts.SanitizeCfiCrossDso) {
diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp
index 8aebd35..2619edf 100644
--- a/clang/lib/CodeGen/CodeGenPGO.cpp
+++ b/clang/lib/CodeGen/CodeGenPGO.cpp
@@ -23,6 +23,10 @@
#include "llvm/Support/MD5.h"
#include <optional>
+namespace llvm {
+extern cl::opt<bool> EnableSingleByteCoverage;
+} // namespace llvm
+
static llvm::cl::opt<bool>
EnableValueProfiling("enable-value-profiling",
llvm::cl::desc("Enable value profiling"),
@@ -346,6 +350,14 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
return Base::VisitBinaryOperator(S);
}
+ bool VisitConditionalOperator(ConditionalOperator *S) {
+ if (llvm::EnableSingleByteCoverage && S->getTrueExpr())
+ CounterMap[S->getTrueExpr()] = NextCounter++;
+ if (llvm::EnableSingleByteCoverage && S->getFalseExpr())
+ CounterMap[S->getFalseExpr()] = NextCounter++;
+ return Base::VisitConditionalOperator(S);
+ }
+
/// Include \p S in the function hash.
bool VisitStmt(Stmt *S) {
auto Type = updateCounterMappings(S);
@@ -361,8 +373,21 @@ struct MapRegionCounters : public RecursiveASTVisitor<MapRegionCounters> {
if (Hash.getHashVersion() == PGO_HASH_V1)
return Base::TraverseIfStmt(If);
+ // When single byte coverage mode is enabled, add a counter to then and
+ // else.
+ bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage;
+ for (Stmt *CS : If->children()) {
+ if (!CS || NoSingleByteCoverage)
+ continue;
+ if (CS == If->getThen())
+ CounterMap[If->getThen()] = NextCounter++;
+ else if (CS == If->getElse())
+ CounterMap[If->getElse()] = NextCounter++;
+ }
+
// Otherwise, keep track of which branch we're in while traversing.
VisitStmt(If);
+
for (Stmt *CS : If->children()) {
if (!CS)
continue;
@@ -376,6 +401,81 @@ 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).
@@ -387,10 +487,6 @@ 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)
@@ -1094,8 +1190,8 @@ CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader,
Fn->setEntryCount(FunctionCount);
}
-void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
- llvm::Value *StepV) {
+void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
+ llvm::Value *StepV) {
if (!RegionCounterMap || !Builder.GetInsertBlock())
return;
@@ -1105,13 +1201,19 @@ void CodeGenPGO::emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
Builder.getInt64(FunctionHash),
Builder.getInt32(NumRegionCounters),
Builder.getInt32(Counter), StepV};
- if (!StepV)
- Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
+
+ if (llvm::EnableSingleByteCoverage)
+ Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_cover),
ArrayRef(Args, 4));
- else
- Builder.CreateCall(
- CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
- ArrayRef(Args));
+ else {
+ if (!StepV)
+ Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment),
+ ArrayRef(Args, 4));
+ else
+ Builder.CreateCall(
+ CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment_step),
+ ArrayRef(Args));
+ }
}
bool CodeGenPGO::canEmitMCDCCoverage(const CGBuilderTy &Builder) {
@@ -1222,6 +1324,30 @@ void CodeGenPGO::setValueProfilingFlag(llvm::Module &M) {
uint32_t(EnableValueProfiling));
}
+void CodeGenPGO::setProfileVersion(llvm::Module &M) {
+ if (CGM.getCodeGenOpts().hasProfileClangInstr() &&
+ llvm::EnableSingleByteCoverage) {
+ const StringRef VarName(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
+ llvm::Type *IntTy64 = llvm::Type::getInt64Ty(M.getContext());
+ uint64_t ProfileVersion =
+ (INSTR_PROF_RAW_VERSION | VARIANT_MASK_BYTE_COVERAGE);
+
+ auto IRLevelVersionVariable = new llvm::GlobalVariable(
+ M, IntTy64, true, llvm::GlobalValue::WeakAnyLinkage,
+ llvm::Constant::getIntegerValue(IntTy64,
+ llvm::APInt(64, ProfileVersion)),
+ VarName);
+
+ IRLevelVersionVariable->setVisibility(llvm::GlobalValue::DefaultVisibility);
+ llvm::Triple TT(M.getTargetTriple());
+ if (TT.supportsCOMDAT()) {
+ IRLevelVersionVariable->setLinkage(llvm::GlobalValue::ExternalLinkage);
+ IRLevelVersionVariable->setComdat(M.getOrInsertComdat(VarName));
+ }
+ IRLevelVersionVariable->setDSOLocal(true);
+ }
+}
+
// This method either inserts a call to the profile run-time during
// instrumentation or puts profile data into metadata for PGO use.
void CodeGenPGO::valueProfile(CGBuilderTy &Builder, uint32_t ValueKind,
diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h
index d3c2b27..036fbf6 100644
--- a/clang/lib/CodeGen/CodeGenPGO.h
+++ b/clang/lib/CodeGen/CodeGenPGO.h
@@ -94,6 +94,8 @@ public:
// Set a module flag indicating if value profiling is enabled.
void setValueProfilingFlag(llvm::Module &M);
+ void setProfileVersion(llvm::Module &M);
+
private:
void setFuncName(llvm::Function *Fn);
void setFuncName(StringRef Name, llvm::GlobalValue::LinkageTypes Linkage);
@@ -108,8 +110,8 @@ private:
bool canEmitMCDCCoverage(const CGBuilderTy &Builder);
public:
- void emitCounterIncrement(CGBuilderTy &Builder, const Stmt *S,
- llvm::Value *StepV);
+ void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S,
+ llvm::Value *StepV);
void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S,
Address MCDCCondBitmapAddr);
void emitMCDCParameters(CGBuilderTy &Builder);
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index e25a927..71215da 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -31,6 +31,14 @@
// is textually included.
#define COVMAP_V3
+namespace llvm {
+cl::opt<bool>
+ EnableSingleByteCoverage("enable-single-byte-coverage",
+ llvm::cl::ZeroOrMore,
+ llvm::cl::desc("Enable single byte coverage"),
+ llvm::cl::Hidden, llvm::cl::init(false));
+} // namespace llvm
+
static llvm::cl::opt<bool> EmptyLineCommentCoverage(
"emptyline-comment-coverage",
llvm::cl::desc("Emit emptylines and comment lines as skipped regions (only "
@@ -832,16 +840,22 @@ struct CounterCoverageMappingBuilder
/// Return a counter for the subtraction of \c RHS from \c LHS
Counter subtractCounters(Counter LHS, Counter RHS, bool Simplify = true) {
+ assert(!llvm::EnableSingleByteCoverage &&
+ "cannot add counters when single byte coverage mode is enabled");
return Builder.subtract(LHS, RHS, Simplify);
}
/// Return a counter for the sum of \c LHS and \c RHS.
Counter addCounters(Counter LHS, Counter RHS, bool Simplify = true) {
+ assert(!llvm::EnableSingleByteCoverage &&
+ "cannot add counters when single byte coverage mode is enabled");
return Builder.add(LHS, RHS, Simplify);
}
Counter addCounters(Counter C1, Counter C2, Counter C3,
bool Simplify = true) {
+ assert(!llvm::EnableSingleByteCoverage &&
+ "cannot add counters when single byte coverage mode is enabled");
return addCounters(addCounters(C1, C2, Simplify), C3, Simplify);
}
@@ -1443,8 +1457,9 @@ struct CounterCoverageMappingBuilder
void VisitBreakStmt(const BreakStmt *S) {
assert(!BreakContinueStack.empty() && "break not in a loop or switch!");
- BreakContinueStack.back().BreakCount = addCounters(
- BreakContinueStack.back().BreakCount, getRegion().getCounter());
+ if (!llvm::EnableSingleByteCoverage)
+ BreakContinueStack.back().BreakCount = addCounters(
+ BreakContinueStack.back().BreakCount, getRegion().getCounter());
// FIXME: a break in a switch should terminate regions for all preceding
// case statements, not just the most recent one.
terminateRegion(S);
@@ -1452,8 +1467,9 @@ struct CounterCoverageMappingBuilder
void VisitContinueStmt(const ContinueStmt *S) {
assert(!BreakContinueStack.empty() && "continue stmt not in a loop!");
- BreakContinueStack.back().ContinueCount = addCounters(
- BreakContinueStack.back().ContinueCount, getRegion().getCounter());
+ if (!llvm::EnableSingleByteCoverage)
+ BreakContinueStack.back().ContinueCount = addCounters(
+ BreakContinueStack.back().ContinueCount, getRegion().getCounter());
terminateRegion(S);
}
@@ -1471,7 +1487,9 @@ struct CounterCoverageMappingBuilder
extendRegion(S);
Counter ParentCount = getRegion().getCounter();
- Counter BodyCount = getRegionCounter(S);
+ Counter BodyCount = llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S->getBody())
+ : getRegionCounter(S);
// Handle the body first so that we can get the backedge count.
BreakContinueStack.push_back(BreakContinue());
@@ -1484,7 +1502,9 @@ struct CounterCoverageMappingBuilder
// Go back to handle the condition.
Counter CondCount =
- addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
+ llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S->getCond())
+ : addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
propagateCounts(CondCount, S->getCond());
adjustForOutOfOrderTraversal(getEnd(S));
@@ -1494,7 +1514,11 @@ struct CounterCoverageMappingBuilder
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
Counter OutCount =
- addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
+ llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S)
+ : addCounters(BC.BreakCount,
+ subtractCounters(CondCount, BodyCount));
+
if (OutCount != ParentCount) {
pushRegion(OutCount);
GapRegionCounter = OutCount;
@@ -1503,38 +1527,53 @@ struct CounterCoverageMappingBuilder
}
// Create Branch Region around condition.
- createBranchRegion(S->getCond(), BodyCount,
- subtractCounters(CondCount, BodyCount));
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(S->getCond(), BodyCount,
+ subtractCounters(CondCount, BodyCount));
}
void VisitDoStmt(const DoStmt *S) {
extendRegion(S);
Counter ParentCount = getRegion().getCounter();
- Counter BodyCount = getRegionCounter(S);
+ Counter BodyCount = llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S->getBody())
+ : getRegionCounter(S);
BreakContinueStack.push_back(BreakContinue());
extendRegion(S->getBody());
- Counter BackedgeCount =
- propagateCounts(addCounters(ParentCount, BodyCount), S->getBody());
+
+ Counter BackedgeCount;
+ if (llvm::EnableSingleByteCoverage)
+ propagateCounts(BodyCount, S->getBody());
+ else
+ BackedgeCount =
+ propagateCounts(addCounters(ParentCount, BodyCount), S->getBody());
+
BreakContinue BC = BreakContinueStack.pop_back_val();
bool BodyHasTerminateStmt = HasTerminateStmt;
HasTerminateStmt = false;
- Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount);
+ Counter CondCount = llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S->getCond())
+ : addCounters(BackedgeCount, BC.ContinueCount);
propagateCounts(CondCount, S->getCond());
Counter OutCount =
- addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount));
+ llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S)
+ : addCounters(BC.BreakCount,
+ subtractCounters(CondCount, BodyCount));
if (OutCount != ParentCount) {
pushRegion(OutCount);
GapRegionCounter = OutCount;
}
// Create Branch Region around condition.
- createBranchRegion(S->getCond(), BodyCount,
- subtractCounters(CondCount, BodyCount));
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(S->getCond(), BodyCount,
+ subtractCounters(CondCount, BodyCount));
if (BodyHasTerminateStmt)
HasTerminateStmt = true;
@@ -1546,7 +1585,9 @@ struct CounterCoverageMappingBuilder
Visit(S->getInit());
Counter ParentCount = getRegion().getCounter();
- Counter BodyCount = getRegionCounter(S);
+ Counter BodyCount = llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S->getBody())
+ : getRegionCounter(S);
// The loop increment may contain a break or continue.
if (S->getInc())
@@ -1565,14 +1606,23 @@ struct CounterCoverageMappingBuilder
// the count for all the continue statements.
BreakContinue IncrementBC;
if (const Stmt *Inc = S->getInc()) {
- propagateCounts(addCounters(BackedgeCount, BodyBC.ContinueCount), Inc);
+ Counter IncCount;
+ if (llvm::EnableSingleByteCoverage)
+ IncCount = getRegionCounter(S->getInc());
+ else
+ IncCount = addCounters(BackedgeCount, BodyBC.ContinueCount);
+ propagateCounts(IncCount, Inc);
IncrementBC = BreakContinueStack.pop_back_val();
}
// Go back to handle the condition.
- Counter CondCount = addCounters(
- addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount),
- IncrementBC.ContinueCount);
+ Counter CondCount =
+ llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S->getCond())
+ : addCounters(
+ addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount),
+ IncrementBC.ContinueCount);
+
if (const Expr *Cond = S->getCond()) {
propagateCounts(CondCount, Cond);
adjustForOutOfOrderTraversal(getEnd(S));
@@ -1583,8 +1633,11 @@ struct CounterCoverageMappingBuilder
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
- Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount,
- subtractCounters(CondCount, BodyCount));
+ Counter OutCount =
+ llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S)
+ : addCounters(BodyBC.BreakCount, IncrementBC.BreakCount,
+ subtractCounters(CondCount, BodyCount));
if (OutCount != ParentCount) {
pushRegion(OutCount);
GapRegionCounter = OutCount;
@@ -1593,8 +1646,9 @@ struct CounterCoverageMappingBuilder
}
// Create Branch Region around condition.
- createBranchRegion(S->getCond(), BodyCount,
- subtractCounters(CondCount, BodyCount));
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(S->getCond(), BodyCount,
+ subtractCounters(CondCount, BodyCount));
}
void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
@@ -1605,7 +1659,9 @@ struct CounterCoverageMappingBuilder
Visit(S->getRangeStmt());
Counter ParentCount = getRegion().getCounter();
- Counter BodyCount = getRegionCounter(S);
+ Counter BodyCount = llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S->getBody())
+ : getRegionCounter(S);
BreakContinueStack.push_back(BreakContinue());
extendRegion(S->getBody());
@@ -1620,10 +1676,15 @@ struct CounterCoverageMappingBuilder
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount);
- Counter LoopCount =
- addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
- Counter OutCount =
- addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
+ Counter OutCount;
+ Counter LoopCount;
+ if (llvm::EnableSingleByteCoverage)
+ OutCount = getRegionCounter(S);
+ else {
+ LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount);
+ OutCount =
+ addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount));
+ }
if (OutCount != ParentCount) {
pushRegion(OutCount);
GapRegionCounter = OutCount;
@@ -1632,8 +1693,9 @@ struct CounterCoverageMappingBuilder
}
// Create Branch Region around condition.
- createBranchRegion(S->getCond(), BodyCount,
- subtractCounters(LoopCount, BodyCount));
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(S->getCond(), BodyCount,
+ subtractCounters(LoopCount, BodyCount));
}
void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {
@@ -1694,7 +1756,7 @@ struct CounterCoverageMappingBuilder
propagateCounts(Counter::getZero(), Body);
BreakContinue BC = BreakContinueStack.pop_back_val();
- if (!BreakContinueStack.empty())
+ if (!BreakContinueStack.empty() && !llvm::EnableSingleByteCoverage)
BreakContinueStack.back().ContinueCount = addCounters(
BreakContinueStack.back().ContinueCount, BC.ContinueCount);
@@ -1709,6 +1771,11 @@ struct CounterCoverageMappingBuilder
MostRecentLocation = getStart(S);
handleFileExit(ExitLoc);
+ // When single byte coverage mode is enabled, do not create branch region by
+ // early returning.
+ if (llvm::EnableSingleByteCoverage)
+ return;
+
// Create a Branch Region around each Case. Subtract the case's
// counter from the Parent counter to track the "False" branch count.
Counter CaseCountSum;
@@ -1741,8 +1808,10 @@ struct CounterCoverageMappingBuilder
extendRegion(S);
SourceMappingRegion &Parent = getRegion();
+ Counter Count = llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S)
+ : addCounters(Parent.getCounter(), getRegionCounter(S));
- Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S));
// Reuse the existing region if it starts at our label. This is typical of
// the first case in a switch.
if (Parent.hasStartLoc() && Parent.getBeginLoc() == getStart(S))
@@ -1860,7 +1929,9 @@ struct CounterCoverageMappingBuilder
extendRegion(S->getCond());
Counter ParentCount = getRegion().getCounter();
- Counter ThenCount = getRegionCounter(S);
+ Counter ThenCount = llvm::EnableSingleByteCoverage
+ ? getRegionCounter(S->getThen())
+ : getRegionCounter(S);
// Emitting a counter for the condition makes it easier to interpret the
// counter for the body when looking at the coverage.
@@ -1874,7 +1945,12 @@ struct CounterCoverageMappingBuilder
extendRegion(S->getThen());
Counter OutCount = propagateCounts(ThenCount, S->getThen());
- Counter ElseCount = subtractCounters(ParentCount, ThenCount);
+
+ 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;
@@ -1885,21 +1961,28 @@ struct CounterCoverageMappingBuilder
if (Gap)
fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount);
extendRegion(Else);
- OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else));
+
+ Counter ElseOutCount = propagateCounts(ElseCount, Else);
+ if (!llvm::EnableSingleByteCoverage)
+ OutCount = addCounters(OutCount, ElseOutCount);
if (ThenHasTerminateStmt)
HasTerminateStmt = true;
- } else
+ } else if (!llvm::EnableSingleByteCoverage)
OutCount = addCounters(OutCount, ElseCount);
+ if (llvm::EnableSingleByteCoverage)
+ OutCount = getRegionCounter(S);
+
if (OutCount != ParentCount) {
pushRegion(OutCount);
GapRegionCounter = OutCount;
}
- // Create Branch Region around condition.
- createBranchRegion(S->getCond(), ThenCount,
- subtractCounters(ParentCount, ThenCount));
+ if (!S->isConsteval() && !llvm::EnableSingleByteCoverage)
+ // Create Branch Region around condition.
+ createBranchRegion(S->getCond(), ThenCount,
+ subtractCounters(ParentCount, ThenCount));
}
void VisitCXXTryStmt(const CXXTryStmt *S) {
@@ -1925,7 +2008,9 @@ struct CounterCoverageMappingBuilder
extendRegion(E);
Counter ParentCount = getRegion().getCounter();
- Counter TrueCount = getRegionCounter(E);
+ Counter TrueCount = llvm::EnableSingleByteCoverage
+ ? getRegionCounter(E->getTrueExpr())
+ : getRegionCounter(E);
propagateCounts(ParentCount, E->getCond());
Counter OutCount;
@@ -1944,9 +2029,15 @@ struct CounterCoverageMappingBuilder
}
extendRegion(E->getFalseExpr());
- OutCount = addCounters(
- OutCount, propagateCounts(subtractCounters(ParentCount, TrueCount),
- 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) {
pushRegion(OutCount);
@@ -1954,8 +2045,9 @@ struct CounterCoverageMappingBuilder
}
// Create Branch Region around condition.
- createBranchRegion(E->getCond(), TrueCount,
- subtractCounters(ParentCount, TrueCount));
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(E->getCond(), TrueCount,
+ subtractCounters(ParentCount, TrueCount));
}
void createDecision(const BinaryOperator *E) {
@@ -2002,12 +2094,14 @@ struct CounterCoverageMappingBuilder
Counter ParentCnt = getRegion().getCounter();
// Create Branch Region around LHS condition.
- createBranchRegion(E->getLHS(), RHSExecCnt,
- subtractCounters(ParentCnt, RHSExecCnt), DecisionLHS);
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(E->getLHS(), RHSExecCnt,
+ subtractCounters(ParentCnt, RHSExecCnt), DecisionLHS);
// Create Branch Region around RHS condition.
- createBranchRegion(E->getRHS(), RHSTrueCnt,
- subtractCounters(RHSExecCnt, RHSTrueCnt), DecisionRHS);
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(E->getRHS(), RHSTrueCnt,
+ subtractCounters(RHSExecCnt, RHSTrueCnt), DecisionRHS);
// Create MCDC Decision Region if at top-level (root).
if (IsRootNode)
@@ -2058,12 +2152,14 @@ struct CounterCoverageMappingBuilder
Counter ParentCnt = getRegion().getCounter();
// Create Branch Region around LHS condition.
- createBranchRegion(E->getLHS(), subtractCounters(ParentCnt, RHSExecCnt),
- RHSExecCnt, DecisionLHS);
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(E->getLHS(), subtractCounters(ParentCnt, RHSExecCnt),
+ RHSExecCnt, DecisionLHS);
// Create Branch Region around RHS condition.
- createBranchRegion(E->getRHS(), subtractCounters(RHSExecCnt, RHSFalseCnt),
- RHSFalseCnt, DecisionRHS);
+ if (!llvm::EnableSingleByteCoverage)
+ createBranchRegion(E->getRHS(), subtractCounters(RHSExecCnt, RHSFalseCnt),
+ RHSFalseCnt, DecisionRHS);
// Create MCDC Decision Region if at top-level (root).
if (IsRootNode)