mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-19 00:14:20 +00:00
llvm-cov: Use the number of executed functions for the function coverage metric.
This commit fixes llvm-cov's function coverage metric by using the number of executed functions instead of the number of fully covered functions. Differential Revision: http://reviews.llvm.org/D5196 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218672 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
f49592dddc
commit
38c59de6b1
@ -228,9 +228,13 @@ struct FunctionRecord {
|
||||
std::vector<std::string> Filenames;
|
||||
/// \brief Regions in the function along with their counts.
|
||||
std::vector<CountedRegion> CountedRegions;
|
||||
/// \brief The number of times this function was executed.
|
||||
uint64_t ExecutionCount;
|
||||
|
||||
FunctionRecord(StringRef Name, ArrayRef<StringRef> Filenames)
|
||||
: Name(Name), Filenames(Filenames.begin(), Filenames.end()) {}
|
||||
FunctionRecord(StringRef Name, ArrayRef<StringRef> Filenames,
|
||||
uint64_t ExecutionCount)
|
||||
: Name(Name), Filenames(Filenames.begin(), Filenames.end()),
|
||||
ExecutionCount(ExecutionCount) {}
|
||||
};
|
||||
|
||||
/// \brief Coverage information for a macro expansion or #included file.
|
||||
|
@ -167,7 +167,9 @@ CoverageMapping::load(ObjectFileCoverageMappingReader &CoverageReader,
|
||||
continue;
|
||||
}
|
||||
|
||||
FunctionRecord Function(Record.FunctionName, Record.Filenames);
|
||||
assert(Counts.size() != 0 && "Function's counts are empty");
|
||||
FunctionRecord Function(Record.FunctionName, Record.Filenames,
|
||||
Counts.front());
|
||||
CounterMappingContext Ctx(Record.Expressions, Counts);
|
||||
for (const auto &Region : Record.MappingRegions) {
|
||||
ErrorOr<int64_t> ExecutionCount = Ctx.evaluate(Region.Count);
|
||||
|
BIN
test/tools/llvm-cov/Inputs/report.covmapping
Normal file
BIN
test/tools/llvm-cov/Inputs/report.covmapping
Normal file
Binary file not shown.
BIN
test/tools/llvm-cov/Inputs/report.profdata
Normal file
BIN
test/tools/llvm-cov/Inputs/report.profdata
Normal file
Binary file not shown.
24
test/tools/llvm-cov/report.cpp
Normal file
24
test/tools/llvm-cov/report.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
// RUN: llvm-cov report %S/Inputs/report.covmapping -instr-profile %S/Inputs/report.profdata -no-colors 2>&1 | FileCheck %s
|
||||
|
||||
// CHECK: Filename Regions Miss Cover Functions Executed
|
||||
// CHECK: TOTAL 5 2 60.00% 4 75.00%
|
||||
|
||||
void foo(bool cond) {
|
||||
if (cond) {
|
||||
}
|
||||
}
|
||||
|
||||
void bar() {
|
||||
}
|
||||
|
||||
void func() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
foo(false);
|
||||
bar();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// llvm-cov doesn't work on big endian yet
|
||||
// XFAIL: powerpc64-, s390x, mips-, mips64-, sparc
|
@ -85,7 +85,7 @@ static Column column(StringRef Str, unsigned Width, const T &Value) {
|
||||
return Column(Str, Width).set(Value);
|
||||
}
|
||||
|
||||
static const unsigned FileReportColumns[] = {25, 10, 8, 8, 10, 8};
|
||||
static const unsigned FileReportColumns[] = {25, 10, 8, 8, 10, 10};
|
||||
static const unsigned FunctionReportColumns[] = {25, 10, 8, 8, 10, 8, 8};
|
||||
|
||||
/// \brief Prints a horizontal divider which spans across the given columns.
|
||||
@ -178,8 +178,8 @@ void CoverageReport::renderFunctionReports(raw_ostream &OS) {
|
||||
render(Function, OS);
|
||||
renderDivider(FunctionReportColumns, OS);
|
||||
OS << "\n";
|
||||
render(FunctionCoverageSummary("TOTAL", File.RegionCoverage,
|
||||
File.LineCoverage),
|
||||
render(FunctionCoverageSummary("TOTAL", /*ExecutionCount=*/0,
|
||||
File.RegionCoverage, File.LineCoverage),
|
||||
OS);
|
||||
}
|
||||
}
|
||||
@ -190,7 +190,8 @@ void CoverageReport::renderFileReports(raw_ostream &OS) {
|
||||
<< column("Miss", FileReportColumns[2], Column::RightAlignment)
|
||||
<< column("Cover", FileReportColumns[3], Column::RightAlignment)
|
||||
<< column("Functions", FileReportColumns[4], Column::RightAlignment)
|
||||
<< column("Cover", FileReportColumns[5], Column::RightAlignment) << "\n";
|
||||
<< column("Executed", FileReportColumns[5], Column::RightAlignment)
|
||||
<< "\n";
|
||||
renderDivider(FileReportColumns, OS);
|
||||
OS << "\n";
|
||||
for (const auto &File : Summary.getFileSummaries())
|
||||
|
@ -72,7 +72,7 @@ CoverageSummary::createSummaries(ArrayRef<coverage::FunctionRecord> Functions) {
|
||||
FileCoverageSummary CoverageSummary::getCombinedFileSummaries() {
|
||||
size_t NumRegions = 0, CoveredRegions = 0;
|
||||
size_t NumLines = 0, NonCodeLines = 0, CoveredLines = 0;
|
||||
size_t NumFunctionsCovered = 0, NumFunctions = 0;
|
||||
size_t NumFunctionsExecuted = 0, NumFunctions = 0;
|
||||
for (const auto &File : FileSummaries) {
|
||||
NumRegions += File.RegionCoverage.NumRegions;
|
||||
CoveredRegions += File.RegionCoverage.Covered;
|
||||
@ -81,12 +81,12 @@ FileCoverageSummary CoverageSummary::getCombinedFileSummaries() {
|
||||
NonCodeLines += File.LineCoverage.NonCodeLines;
|
||||
CoveredLines += File.LineCoverage.Covered;
|
||||
|
||||
NumFunctionsCovered += File.FunctionCoverage.FullyCovered;
|
||||
NumFunctionsExecuted += File.FunctionCoverage.Executed;
|
||||
NumFunctions += File.FunctionCoverage.NumFunctions;
|
||||
}
|
||||
return FileCoverageSummary(
|
||||
"TOTAL", RegionCoverageInfo(CoveredRegions, NumRegions),
|
||||
LineCoverageInfo(CoveredLines, NonCodeLines, NumLines),
|
||||
FunctionCoverageInfo(NumFunctionsCovered, NumFunctions),
|
||||
FunctionCoverageInfo(NumFunctionsExecuted, NumFunctions),
|
||||
None);
|
||||
}
|
||||
|
@ -65,7 +65,8 @@ FunctionCoverageSummary::get(const coverage::FunctionRecord &Function) {
|
||||
NumLines += LineCount;
|
||||
}
|
||||
return FunctionCoverageSummary(
|
||||
Function.Name, RegionCoverageInfo(CoveredRegions, NumCodeRegions),
|
||||
Function.Name, Function.ExecutionCount,
|
||||
RegionCoverageInfo(CoveredRegions, NumCodeRegions),
|
||||
LineCoverageInfo(CoveredLines, 0, NumLines));
|
||||
}
|
||||
|
||||
@ -74,7 +75,7 @@ FileCoverageSummary::get(StringRef Name,
|
||||
ArrayRef<FunctionCoverageSummary> FunctionSummaries) {
|
||||
size_t NumRegions = 0, CoveredRegions = 0;
|
||||
size_t NumLines = 0, NonCodeLines = 0, CoveredLines = 0;
|
||||
size_t NumFunctionsCovered = 0;
|
||||
size_t NumFunctionsExecuted = 0;
|
||||
for (const auto &Func : FunctionSummaries) {
|
||||
CoveredRegions += Func.RegionCoverage.Covered;
|
||||
NumRegions += Func.RegionCoverage.NumRegions;
|
||||
@ -83,13 +84,13 @@ FileCoverageSummary::get(StringRef Name,
|
||||
NonCodeLines += Func.LineCoverage.NonCodeLines;
|
||||
NumLines += Func.LineCoverage.NumLines;
|
||||
|
||||
if (Func.RegionCoverage.isFullyCovered())
|
||||
++NumFunctionsCovered;
|
||||
if (Func.ExecutionCount != 0)
|
||||
++NumFunctionsExecuted;
|
||||
}
|
||||
|
||||
return FileCoverageSummary(
|
||||
Name, RegionCoverageInfo(CoveredRegions, NumRegions),
|
||||
LineCoverageInfo(CoveredLines, NonCodeLines, NumLines),
|
||||
FunctionCoverageInfo(NumFunctionsCovered, FunctionSummaries.size()),
|
||||
FunctionCoverageInfo(NumFunctionsExecuted, FunctionSummaries.size()),
|
||||
FunctionSummaries);
|
||||
}
|
||||
|
@ -69,33 +69,34 @@ struct LineCoverageInfo {
|
||||
|
||||
/// \brief Provides information about function coverage for a file.
|
||||
struct FunctionCoverageInfo {
|
||||
/// \brief The number of functions that have full
|
||||
/// region coverage.
|
||||
size_t FullyCovered;
|
||||
/// \brief The number of functions that were executed.
|
||||
size_t Executed;
|
||||
|
||||
/// \brief The total number of functions in this file.
|
||||
size_t NumFunctions;
|
||||
|
||||
FunctionCoverageInfo(size_t FullyCovered, size_t NumFunctions)
|
||||
: FullyCovered(FullyCovered), NumFunctions(NumFunctions) {}
|
||||
FunctionCoverageInfo(size_t Executed, size_t NumFunctions)
|
||||
: Executed(Executed), NumFunctions(NumFunctions) {}
|
||||
|
||||
bool isFullyCovered() const { return FullyCovered == NumFunctions; }
|
||||
bool isFullyCovered() const { return Executed == NumFunctions; }
|
||||
|
||||
double getPercentCovered() const {
|
||||
return double(FullyCovered) / double(NumFunctions) * 100.0;
|
||||
return double(Executed) / double(NumFunctions) * 100.0;
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A summary of function's code coverage.
|
||||
struct FunctionCoverageSummary {
|
||||
StringRef Name;
|
||||
uint64_t ExecutionCount;
|
||||
RegionCoverageInfo RegionCoverage;
|
||||
LineCoverageInfo LineCoverage;
|
||||
|
||||
FunctionCoverageSummary(StringRef Name,
|
||||
FunctionCoverageSummary(StringRef Name, uint64_t ExecutionCount,
|
||||
const RegionCoverageInfo &RegionCoverage,
|
||||
const LineCoverageInfo &LineCoverage)
|
||||
: Name(Name), RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) {
|
||||
: Name(Name), ExecutionCount(ExecutionCount),
|
||||
RegionCoverage(RegionCoverage), LineCoverage(LineCoverage) {
|
||||
}
|
||||
|
||||
/// \brief Compute the code coverage summary for the given function coverage
|
||||
|
Loading…
x
Reference in New Issue
Block a user