mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-30 08:25:08 +00:00
[llvm-cov] Track function and instantiation coverage separately
These are distinct statistics which are useful to look at separately. Example: say you have a template function "foo" with 5 instantiations and only 3 of them are covered. Then this contributes (1/1) to the total function coverage and (3/5) to the total instantiation coverage. I.e, the old "Function Coverage" column has been renamed to "Instantiation Coverage", and the new "Function Coverage" aggregates information from the various instantiations of a function. One benefit of making this switch is that the Line and Region coverage columns will start making sense. Let's continue the example and assume that the 5 instantiations of "foo" cover {2, 4, 6, 8, 10} out of 10 lines respectively. The new line coverage for "foo" is (10/10), not (30/50). The old scenario got confusing because we'd report that there were more lines in a file than what was actually possible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281875 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
40817d86f0
commit
e17f26f066
@ -13,4 +13,4 @@ _Z4funcIiEiT_
|
||||
main
|
||||
0
|
||||
1
|
||||
0
|
||||
1
|
||||
|
@ -1,10 +1,26 @@
|
||||
RUN: llvm-profdata merge %S/Inputs/hideUnexecutedSubviews.proftext -o %t.profdata
|
||||
|
||||
RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %t.profdata -filename-equivalence %S/showTemplateInstantiations.cpp | FileCheck %s
|
||||
RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %t.profdata -filename-equivalence %S/showTemplateInstantiations.cpp | FileCheck -check-prefix=FILE %s
|
||||
|
||||
RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %t.profdata -format html -o %t.html.dir -filename-equivalence %S/showTemplateInstantiations.cpp
|
||||
RUN: FileCheck %s -input-file %t.html.dir/coverage/tmp/showTemplateInstantiations.cpp.html
|
||||
RUN: FileCheck -check-prefix=FILE %s -input-file %t.html.dir/coverage/tmp/showTemplateInstantiations.cpp.html
|
||||
|
||||
CHECK: Unexecuted instantiation: _Z4funcIbEiT_
|
||||
CHECK: Unexecuted instantiation: _Z4funcIiEiT_
|
||||
CHECK-NOT: Unexecuted instantiation
|
||||
FILE: Unexecuted instantiation: _Z4funcIbEiT_
|
||||
FILE: Unexecuted instantiation: _Z4funcIiEiT_
|
||||
FILE-NOT: Unexecuted instantiation
|
||||
|
||||
RUN: FileCheck -check-prefix=INDEX %s -input-file %t.html.dir/index.html
|
||||
|
||||
INDEX: <td class='column-entry-left'>Filename</td>
|
||||
INDEX: <td class='column-entry'>Function Coverage</td>
|
||||
INDEX: <td class='column-entry'>Instantiation Coverage</td>
|
||||
INDEX: <td class='column-entry'>Line Coverage</td>
|
||||
INDEX: <td class='column-entry'>Region Coverage</td>
|
||||
INDEX: <td class='column-entry-red'>
|
||||
INDEX: 50.00% (1/2)
|
||||
INDEX: <td class='column-entry-red'>
|
||||
INDEX: 33.33% (1/3)
|
||||
INDEX: <td class='column-entry-red'>
|
||||
INDEX: 41.67% (5/12)
|
||||
INDEX: <td class='column-entry-red'>
|
||||
INDEX: 20.00% (1/5)
|
||||
|
@ -1,11 +1,11 @@
|
||||
// RUN: llvm-cov report %S/Inputs/report.covmapping -instr-profile %S/Inputs/report.profdata -filename-equivalence 2>&1 | FileCheck %s
|
||||
// RUN: llvm-cov report %S/Inputs/report.covmapping -instr-profile %S/Inputs/report.profdata -filename-equivalence report.cpp 2>&1 | FileCheck -check-prefix=FILT-NEXT %s
|
||||
|
||||
// CHECK: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover
|
||||
// CHECK: Regions Missed Regions Cover Functions Missed Functions Executed Instantiations Missed Insts. Executed Lines Missed Lines Cover
|
||||
// CHECK-NEXT: ---
|
||||
// CHECK-NEXT: report.cpp 5 2 60.00% 4 1 75.00% 13 4 69.23%
|
||||
// CHECK-NEXT: report.cpp 5 2 60.00% 4 1 75.00% 4 1 75.00% 13 4 69.23%
|
||||
// CHECK-NEXT: ---
|
||||
// CHECK-NEXT: TOTAL 5 2 60.00% 4 1 75.00% 13 4 69.23%
|
||||
// CHECK-NEXT: TOTAL 5 2 60.00% 4 1 75.00% 4 1 75.00% 13 4 69.23%
|
||||
|
||||
// FILT: File 'report.cpp':
|
||||
// FILT-NEXT: Name Regions Miss Cover Lines Miss Cover
|
||||
|
@ -80,11 +80,14 @@ int main() { // TEXT: [[@LINE]]| 161|int main(
|
||||
// HTML-INDEX-LABEL: <table>
|
||||
// HTML-INDEX: <td class='column-entry-left'>Filename</td>
|
||||
// HTML-INDEX: <td class='column-entry'>Function Coverage</td>
|
||||
// HTML-INDEX: <td class='column-entry'>Instantiation Coverage</td>
|
||||
// HTML-INDEX: <td class='column-entry'>Line Coverage</td>
|
||||
// HTML-INDEX: <td class='column-entry'>Region Coverage</td>
|
||||
// HTML-INDEX: <a href='coverage{{.*}}showLineExecutionCounts.cpp.html'{{.*}}showLineExecutionCounts.cpp</a>
|
||||
// HTML-INDEX: <td class='column-entry-green'>
|
||||
// HTML-INDEX: 100.00% (1/1)
|
||||
// HTML-INDEX: <td class='column-entry-green'>
|
||||
// HTML-INDEX: 100.00% (1/1)
|
||||
// HTML-INDEX: <td class='column-entry-yellow'>
|
||||
// HTML-INDEX: 80.00% (16/20)
|
||||
// HTML-INDEX: <td class='column-entry-red'>
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "CoverageReport.h"
|
||||
#include "RenderingSupport.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
@ -85,7 +86,8 @@ Column column(StringRef Str, unsigned Width, const T &Value) {
|
||||
}
|
||||
|
||||
// Specify the default column widths.
|
||||
size_t FileReportColumns[] = {25, 12, 18, 10, 12, 18, 10, 12, 18, 10};
|
||||
size_t FileReportColumns[] = {25, 12, 18, 10, 12, 18, 10,
|
||||
16, 16, 10, 12, 18, 10};
|
||||
size_t FunctionReportColumns[] = {25, 10, 8, 8, 10, 8, 8};
|
||||
|
||||
/// \brief Adjust column widths to fit long file paths and function names.
|
||||
@ -139,6 +141,8 @@ void CoverageReport::render(const FileCoverageSummary &File,
|
||||
determineCoveragePercentageColor(File.RegionCoverage);
|
||||
auto FuncCoverageColor =
|
||||
determineCoveragePercentageColor(File.FunctionCoverage);
|
||||
auto InstantiationCoverageColor =
|
||||
determineCoveragePercentageColor(File.InstantiationCoverage);
|
||||
auto LineCoverageColor = determineCoveragePercentageColor(File.LineCoverage);
|
||||
SmallString<256> FileName = File.Name;
|
||||
sys::path::remove_dots(FileName, /*remove_dot_dots=*/true);
|
||||
@ -162,11 +166,20 @@ void CoverageReport::render(const FileCoverageSummary &File,
|
||||
File.FunctionCoverage.getPercentCovered())
|
||||
<< '%';
|
||||
OS << format("%*u", FileReportColumns[7],
|
||||
(unsigned)File.InstantiationCoverage.NumFunctions);
|
||||
OS << format("%*u", FileReportColumns[8],
|
||||
(unsigned)(File.InstantiationCoverage.NumFunctions -
|
||||
File.InstantiationCoverage.Executed));
|
||||
Options.colored_ostream(OS, InstantiationCoverageColor)
|
||||
<< format("%*.2f", FileReportColumns[9] - 1,
|
||||
File.InstantiationCoverage.getPercentCovered())
|
||||
<< '%';
|
||||
OS << format("%*u", FileReportColumns[10],
|
||||
(unsigned)File.LineCoverage.NumLines);
|
||||
Options.colored_ostream(OS, LineCoverageColor) << format(
|
||||
"%*u", FileReportColumns[8], (unsigned)File.LineCoverage.NotCovered);
|
||||
"%*u", FileReportColumns[11], (unsigned)File.LineCoverage.NotCovered);
|
||||
Options.colored_ostream(OS, LineCoverageColor)
|
||||
<< format("%*.2f", FileReportColumns[9] - 1,
|
||||
<< format("%*.2f", FileReportColumns[12] - 1,
|
||||
File.LineCoverage.getPercentCovered())
|
||||
<< '%';
|
||||
OS << "\n";
|
||||
@ -255,11 +268,28 @@ CoverageReport::prepareFileReports(FileCoverageSummary &Totals,
|
||||
|
||||
for (StringRef Filename : Files) {
|
||||
FileCoverageSummary Summary(Filename.drop_front(LCP));
|
||||
|
||||
// Map source locations to aggregate function coverage summaries.
|
||||
DenseMap<std::pair<unsigned, unsigned>, FunctionCoverageSummary> Summaries;
|
||||
|
||||
for (const auto &F : Coverage.getCoveredFunctions(Filename)) {
|
||||
FunctionCoverageSummary Function = FunctionCoverageSummary::get(F);
|
||||
Summary.addFunction(Function);
|
||||
Totals.addFunction(Function);
|
||||
auto StartLoc = F.CountedRegions[0].startLoc();
|
||||
|
||||
auto UniquedSummary = Summaries.insert({StartLoc, Function});
|
||||
if (!UniquedSummary.second)
|
||||
UniquedSummary.first->second.update(Function);
|
||||
|
||||
Summary.addInstantiation(Function);
|
||||
Totals.addInstantiation(Function);
|
||||
}
|
||||
|
||||
for (const auto &UniquedSummary : Summaries) {
|
||||
const FunctionCoverageSummary &FCS = UniquedSummary.second;
|
||||
Summary.addFunction(FCS);
|
||||
Totals.addFunction(FCS);
|
||||
}
|
||||
|
||||
FileReports.push_back(Summary);
|
||||
}
|
||||
|
||||
@ -288,9 +318,12 @@ void CoverageReport::renderFileReports(raw_ostream &OS,
|
||||
<< column("Functions", FileReportColumns[4], Column::RightAlignment)
|
||||
<< column("Missed Functions", FileReportColumns[5], Column::RightAlignment)
|
||||
<< column("Executed", FileReportColumns[6], Column::RightAlignment)
|
||||
<< column("Lines", FileReportColumns[7], Column::RightAlignment)
|
||||
<< column("Missed Lines", FileReportColumns[8], Column::RightAlignment)
|
||||
<< column("Cover", FileReportColumns[9], Column::RightAlignment) << "\n";
|
||||
<< column("Instantiations", FileReportColumns[7], Column::RightAlignment)
|
||||
<< column("Missed Insts.", FileReportColumns[8], Column::RightAlignment)
|
||||
<< column("Executed", FileReportColumns[9], Column::RightAlignment)
|
||||
<< column("Lines", FileReportColumns[10], Column::RightAlignment)
|
||||
<< column("Missed Lines", FileReportColumns[11], Column::RightAlignment)
|
||||
<< column("Cover", FileReportColumns[12], Column::RightAlignment) << "\n";
|
||||
renderDivider(FileReportColumns, OS);
|
||||
OS << "\n";
|
||||
|
||||
|
@ -69,3 +69,15 @@ FunctionCoverageSummary::get(const coverage::FunctionRecord &Function) {
|
||||
RegionCoverageInfo(CoveredRegions, NumCodeRegions),
|
||||
LineCoverageInfo(CoveredLines, 0, NumLines));
|
||||
}
|
||||
|
||||
void FunctionCoverageSummary::update(const FunctionCoverageSummary &Summary) {
|
||||
ExecutionCount += Summary.ExecutionCount;
|
||||
RegionCoverage.Covered =
|
||||
std::max(RegionCoverage.Covered, Summary.RegionCoverage.Covered);
|
||||
RegionCoverage.NotCovered =
|
||||
std::min(RegionCoverage.NotCovered, Summary.RegionCoverage.NotCovered);
|
||||
LineCoverage.Covered =
|
||||
std::max(LineCoverage.Covered, Summary.LineCoverage.Covered);
|
||||
LineCoverage.NotCovered =
|
||||
std::min(LineCoverage.NotCovered, Summary.LineCoverage.NotCovered);
|
||||
}
|
||||
|
@ -139,6 +139,10 @@ struct FunctionCoverageSummary {
|
||||
/// mapping record.
|
||||
static FunctionCoverageSummary
|
||||
get(const coverage::FunctionRecord &Function);
|
||||
|
||||
/// \brief Update the summary with information from another instantiation
|
||||
/// of this function.
|
||||
void update(const FunctionCoverageSummary &Summary);
|
||||
};
|
||||
|
||||
/// \brief A summary of file's code coverage.
|
||||
@ -147,6 +151,7 @@ struct FileCoverageSummary {
|
||||
RegionCoverageInfo RegionCoverage;
|
||||
LineCoverageInfo LineCoverage;
|
||||
FunctionCoverageInfo FunctionCoverage;
|
||||
FunctionCoverageInfo InstantiationCoverage;
|
||||
|
||||
FileCoverageSummary(StringRef Name) : Name(Name) {}
|
||||
|
||||
@ -155,6 +160,10 @@ struct FileCoverageSummary {
|
||||
LineCoverage += Function.LineCoverage;
|
||||
FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
|
||||
}
|
||||
|
||||
void addInstantiation(const FunctionCoverageSummary &Function) {
|
||||
InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
@ -287,8 +287,8 @@ void CoveragePrinterHTML::closeViewFile(OwnedStream OS) {
|
||||
static void emitColumnLabelsForIndex(raw_ostream &OS) {
|
||||
SmallVector<std::string, 4> Columns;
|
||||
Columns.emplace_back(tag("td", "Filename", "column-entry-left"));
|
||||
for (const char *Label :
|
||||
{"Function Coverage", "Line Coverage", "Region Coverage"})
|
||||
for (const char *Label : {"Function Coverage", "Instantiation Coverage",
|
||||
"Line Coverage", "Region Coverage"})
|
||||
Columns.emplace_back(tag("td", Label, "column-entry"));
|
||||
OS << tag("tr", join(Columns.begin(), Columns.end(), ""));
|
||||
}
|
||||
@ -334,6 +334,9 @@ void CoveragePrinterHTML::emitFileSummary(raw_ostream &OS, StringRef SF,
|
||||
AddCoverageTripleToColumn(FCS.FunctionCoverage.Executed,
|
||||
FCS.FunctionCoverage.NumFunctions,
|
||||
FCS.FunctionCoverage.getPercentCovered());
|
||||
AddCoverageTripleToColumn(FCS.InstantiationCoverage.Executed,
|
||||
FCS.InstantiationCoverage.NumFunctions,
|
||||
FCS.InstantiationCoverage.getPercentCovered());
|
||||
AddCoverageTripleToColumn(FCS.LineCoverage.Covered, FCS.LineCoverage.NumLines,
|
||||
FCS.LineCoverage.getPercentCovered());
|
||||
AddCoverageTripleToColumn(FCS.RegionCoverage.Covered,
|
||||
|
Loading…
Reference in New Issue
Block a user