aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen/CoverageMappingGen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CoverageMappingGen.cpp')
-rw-r--r--clang/lib/CodeGen/CoverageMappingGen.cpp50
1 files changed, 44 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp
index f091577..ce39b72 100644
--- a/clang/lib/CodeGen/CoverageMappingGen.cpp
+++ b/clang/lib/CodeGen/CoverageMappingGen.cpp
@@ -884,6 +884,9 @@ struct CounterCoverageMappingBuilder
/// The map of statements to count values.
llvm::DenseMap<const Stmt *, CounterPair> &CounterMap;
+ CounterExpressionBuilder::SubstMap MapToExpand;
+ unsigned NextCounterNum;
+
MCDC::State &MCDCState;
/// A stack of currently live regions.
@@ -958,7 +961,8 @@ struct CounterCoverageMappingBuilder
BranchCounterPair
getBranchCounterPair(const Stmt *S, Counter ParentCnt,
std::optional<Counter> SkipCntForOld = std::nullopt) {
- Counter ExecCnt = getRegionCounter(S);
+ auto &TheMap = CounterMap[S];
+ auto ExecCnt = Counter::getCounter(TheMap.Executed);
// The old behavior of SingleByte is unaware of Branches.
// Will be pruned after the migration of SingleByte.
@@ -968,13 +972,44 @@ struct CounterCoverageMappingBuilder
return {ExecCnt, *SkipCntForOld};
}
- return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)};
+ BranchCounterPair Counters = {ExecCnt,
+ Builder.subtract(ParentCnt, ExecCnt)};
+
+ if (!llvm::EnableSingleByteCoverage || !Counters.Skipped.isExpression()) {
+ assert(
+ !TheMap.Skipped.hasValue() &&
+ "SkipCnt shouldn't be allocated but refer to an existing counter.");
+ return Counters;
+ }
+
+ // Assign second if second is not assigned yet.
+ if (!TheMap.Skipped.hasValue())
+ TheMap.Skipped = NextCounterNum++;
+
+ // Replace an expression (ParentCnt - ExecCnt) with SkipCnt.
+ Counter SkipCnt = Counter::getCounter(TheMap.Skipped);
+ MapToExpand[SkipCnt] = Builder.subst(Counters.Skipped, MapToExpand);
+ Counters.Skipped = SkipCnt;
+ return Counters;
}
bool IsCounterEqual(Counter OutCount, Counter ParentCount) {
if (OutCount == ParentCount)
return true;
+ // Try comaparison with pre-replaced expressions.
+ //
+ // For example, getBranchCounterPair(#0) returns {#1, #0 - #1}.
+ // The sum of the pair should be equivalent to the Parent, #0.
+ // OTOH when (#0 - #1) is replaced with the new counter #2,
+ // The sum is (#1 + #2). If the reverse substitution #2 => (#0 - #1)
+ // can be applied, the sum can be transformed to (#1 + (#0 - #1)).
+ // To apply substitutions to both hand expressions, transform (LHS - RHS)
+ // and check isZero.
+ if (Builder.subst(Builder.subtract(OutCount, ParentCount), MapToExpand)
+ .isZero())
+ return true;
+
return false;
}
@@ -1188,12 +1223,14 @@ struct CounterCoverageMappingBuilder
/// and add it to the function's SourceRegions.
/// Returns Counter that corresponds to SC.
Counter createSwitchCaseRegion(const SwitchCase *SC, Counter ParentCount) {
+ Counter TrueCnt = getRegionCounter(SC);
+ Counter FalseCnt = (llvm::EnableSingleByteCoverage
+ ? Counter::getZero() // Folded
+ : subtractCounters(ParentCount, TrueCnt));
// Push region onto RegionStack but immediately pop it (which adds it to
// the function's SourceRegions) because it doesn't apply to any other
// source other than the SwitchCase.
- Counter TrueCnt = getRegionCounter(SC);
- popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(),
- subtractCounters(ParentCount, TrueCnt)));
+ popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(), FalseCnt));
return TrueCnt;
}
@@ -1460,7 +1497,8 @@ struct CounterCoverageMappingBuilder
llvm::DenseMap<const Stmt *, CounterPair> &CounterMap,
MCDC::State &MCDCState, SourceManager &SM, const LangOptions &LangOpts)
: CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap),
- MCDCState(MCDCState), MCDCBuilder(CVM.getCodeGenModule(), MCDCState) {}
+ NextCounterNum(CounterMap.size()), MCDCState(MCDCState),
+ MCDCBuilder(CVM.getCodeGenModule(), MCDCState) {}
/// Write the mapping data to the output stream
void write(llvm::raw_ostream &OS) {