diff options
author | Vedant Kumar <vsk@apple.com> | 2016-09-19 00:38:23 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2016-09-19 00:38:23 +0000 |
commit | e17f26f0669952a967c3981be6569cc0e624dbdb (patch) | |
tree | 2ff2ef5ea7dad593d84e69197ba57a66edd53382 /tools | |
parent | 40817d86f07ddcbbad56538866dd8349b985efa8 (diff) |
[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
Diffstat (limited to 'tools')
-rw-r--r-- | tools/llvm-cov/CoverageReport.cpp | 49 | ||||
-rw-r--r-- | tools/llvm-cov/CoverageSummaryInfo.cpp | 12 | ||||
-rw-r--r-- | tools/llvm-cov/CoverageSummaryInfo.h | 9 | ||||
-rw-r--r-- | tools/llvm-cov/SourceCoverageViewHTML.cpp | 7 |
4 files changed, 67 insertions, 10 deletions
diff --git a/tools/llvm-cov/CoverageReport.cpp b/tools/llvm-cov/CoverageReport.cpp index 332268a2343..e70cce40a98 100644 --- a/tools/llvm-cov/CoverageReport.cpp +++ b/tools/llvm-cov/CoverageReport.cpp @@ -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"; diff --git a/tools/llvm-cov/CoverageSummaryInfo.cpp b/tools/llvm-cov/CoverageSummaryInfo.cpp index ffdffbd4b7b..396cd655ca1 100644 --- a/tools/llvm-cov/CoverageSummaryInfo.cpp +++ b/tools/llvm-cov/CoverageSummaryInfo.cpp @@ -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); +} diff --git a/tools/llvm-cov/CoverageSummaryInfo.h b/tools/llvm-cov/CoverageSummaryInfo.h index 822742b635e..acf240d95de 100644 --- a/tools/llvm-cov/CoverageSummaryInfo.h +++ b/tools/llvm-cov/CoverageSummaryInfo.h @@ -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 diff --git a/tools/llvm-cov/SourceCoverageViewHTML.cpp b/tools/llvm-cov/SourceCoverageViewHTML.cpp index e64f31d546e..1ef3219b103 100644 --- a/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -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, |