diff options
Diffstat (limited to 'clang/lib/CodeGen/CoverageMappingGen.cpp')
-rw-r--r-- | clang/lib/CodeGen/CoverageMappingGen.cpp | 50 |
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) { |