mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 12:43:36 +01:00
f85fa6973c
This is an enhancement to LLVM Source-Based Code Coverage in clang to track how many times individual branch-generating conditions are taken (evaluate to TRUE) and not taken (evaluate to FALSE). Individual conditions may comprise larger boolean expressions using boolean logical operators. This functionality is very similar to what is supported by GCOV except that it is very closely anchored to the ASTs. Differential Revision: https://reviews.llvm.org/D84467
111 lines
3.8 KiB
C++
111 lines
3.8 KiB
C++
//===- CoverageSummaryInfo.cpp - Coverage summary for function/file -------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// These structures are used to represent code coverage metrics
|
|
// for functions/files.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "CoverageSummaryInfo.h"
|
|
|
|
using namespace llvm;
|
|
using namespace coverage;
|
|
|
|
static void sumBranches(size_t &NumBranches, size_t &CoveredBranches,
|
|
const ArrayRef<CountedRegion> &Branches) {
|
|
for (const auto &BR : Branches) {
|
|
// Skip folded branches.
|
|
if (BR.Folded)
|
|
continue;
|
|
|
|
// "True" Condition Branches.
|
|
++NumBranches;
|
|
if (BR.ExecutionCount > 0)
|
|
++CoveredBranches;
|
|
// "False" Condition Branches.
|
|
++NumBranches;
|
|
if (BR.FalseExecutionCount > 0)
|
|
++CoveredBranches;
|
|
}
|
|
}
|
|
|
|
static void sumBranchExpansions(size_t &NumBranches, size_t &CoveredBranches,
|
|
const CoverageMapping &CM,
|
|
ArrayRef<ExpansionRecord> Expansions) {
|
|
for (const auto &Expansion : Expansions) {
|
|
auto CE = CM.getCoverageForExpansion(Expansion);
|
|
sumBranches(NumBranches, CoveredBranches, CE.getBranches());
|
|
sumBranchExpansions(NumBranches, CoveredBranches, CM, CE.getExpansions());
|
|
}
|
|
}
|
|
|
|
FunctionCoverageSummary
|
|
FunctionCoverageSummary::get(const CoverageMapping &CM,
|
|
const coverage::FunctionRecord &Function) {
|
|
// Compute the region coverage.
|
|
size_t NumCodeRegions = 0, CoveredRegions = 0;
|
|
for (auto &CR : Function.CountedRegions) {
|
|
if (CR.Kind != CounterMappingRegion::CodeRegion)
|
|
continue;
|
|
++NumCodeRegions;
|
|
if (CR.ExecutionCount != 0)
|
|
++CoveredRegions;
|
|
}
|
|
|
|
// Compute the line coverage
|
|
size_t NumLines = 0, CoveredLines = 0;
|
|
CoverageData CD = CM.getCoverageForFunction(Function);
|
|
for (const auto &LCS : getLineCoverageStats(CD)) {
|
|
if (!LCS.isMapped())
|
|
continue;
|
|
++NumLines;
|
|
if (LCS.getExecutionCount())
|
|
++CoveredLines;
|
|
}
|
|
|
|
// Compute the branch coverage, including branches from expansions.
|
|
size_t NumBranches = 0, CoveredBranches = 0;
|
|
sumBranches(NumBranches, CoveredBranches, CD.getBranches());
|
|
sumBranchExpansions(NumBranches, CoveredBranches, CM, CD.getExpansions());
|
|
|
|
return FunctionCoverageSummary(
|
|
Function.Name, Function.ExecutionCount,
|
|
RegionCoverageInfo(CoveredRegions, NumCodeRegions),
|
|
LineCoverageInfo(CoveredLines, NumLines),
|
|
BranchCoverageInfo(CoveredBranches, NumBranches));
|
|
}
|
|
|
|
FunctionCoverageSummary
|
|
FunctionCoverageSummary::get(const InstantiationGroup &Group,
|
|
ArrayRef<FunctionCoverageSummary> Summaries) {
|
|
std::string Name;
|
|
if (Group.hasName()) {
|
|
Name = std::string(Group.getName());
|
|
} else {
|
|
llvm::raw_string_ostream OS(Name);
|
|
OS << "Definition at line " << Group.getLine() << ", column "
|
|
<< Group.getColumn();
|
|
}
|
|
|
|
FunctionCoverageSummary Summary(Name);
|
|
Summary.ExecutionCount = Group.getTotalExecutionCount();
|
|
Summary.RegionCoverage = Summaries[0].RegionCoverage;
|
|
Summary.LineCoverage = Summaries[0].LineCoverage;
|
|
Summary.BranchCoverage = Summaries[0].BranchCoverage;
|
|
for (const auto &FCS : Summaries.drop_front()) {
|
|
Summary.RegionCoverage.merge(FCS.RegionCoverage);
|
|
Summary.LineCoverage.merge(FCS.LineCoverage);
|
|
|
|
// Sum branch coverage across instantiation groups for the summary rather
|
|
// than "merge" the maximum count. This is a clearer view into whether all
|
|
// created branches are covered.
|
|
Summary.BranchCoverage += FCS.BranchCoverage;
|
|
}
|
|
return Summary;
|
|
}
|