-
Notifications
You must be signed in to change notification settings - Fork 14.3k
llvm-cov: Show FileCoverageSummary
with getCoverageForFile()
#121192
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: users/chapuni/cov/merge/forfile-base
Are you sure you want to change the base?
llvm-cov: Show FileCoverageSummary
with getCoverageForFile()
#121192
Conversation
@llvm/pr-subscribers-pgo Author: NAKAMURA Takumi (chapuni) Changes
For file indices, show also files that have no functions but any other Fixes #119282 Depends on: #121188, #121191 Full diff: https://github.com/llvm/llvm-project/pull/121192.diff 9 Files Affected:
diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
index c51733b46a1894..64416fdba1b247 100644
--- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
+++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
@@ -1012,7 +1012,9 @@ class CoverageMapping {
/// The given filename must be the name as recorded in the coverage
/// information. That is, only names returned from getUniqueSourceFiles will
/// yield a result.
- CoverageData getCoverageForFile(StringRef Filename) const;
+ CoverageData getCoverageForFile(
+ StringRef Filename,
+ const DenseSet<const FunctionRecord *> &FilteredOutFunctions = {}) const;
/// Get the coverage for a particular function.
CoverageData getCoverageForFunction(const FunctionRecord &Function) const;
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index feededcd7d1eb5..e7780b465186df 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -1422,7 +1422,9 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) {
return R.Kind == CounterMappingRegion::ExpansionRegion && R.FileID == FileID;
}
-CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
+CoverageData CoverageMapping::getCoverageForFile(
+ StringRef Filename,
+ const DenseSet<const FunctionRecord *> &FilteredOutFunctions) const {
assert(SingleByteCoverage);
MergeableCoverageData FileCoverage(*SingleByteCoverage, Filename);
@@ -1432,6 +1434,8 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
getImpreciseRecordIndicesForFilename(Filename);
for (unsigned RecordIndex : RecordIndices) {
const FunctionRecord &Function = Functions[RecordIndex];
+ if (FilteredOutFunctions.count(&Function))
+ continue;
auto MainFileID = findMainViewFileID(Filename, Function);
auto FileIDs = gatherFileIDs(Filename, Function);
FileCoverage.addFunctionRegions(
diff --git a/llvm/test/tools/llvm-cov/branch-templates.test b/llvm/test/tools/llvm-cov/branch-templates.test
index d5535022239f5f..594a3ca533678b 100644
--- a/llvm/test/tools/llvm-cov/branch-templates.test
+++ b/llvm/test/tools/llvm-cov/branch-templates.test
@@ -26,6 +26,6 @@
// REPORTFILE: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover
// REPORTFILE-NEXT: ---
-// REPORTFILE-NEXT: branch-templates.cpp 12 3 75.00% 2 0 100.00% 17 4 76.47% 8 4 50.00%
+// REPORTFILE-NEXT: branch-templates.cpp 12 2 83.33% 2 0 100.00% 17 3 82.35% 12 6 50.00%
// REPORTFILE-NEXT: ---
-// REPORTFILE-NEXT: TOTAL 12 3 75.00% 2 0 100.00% 17 4 76.47% 8 4 50.00%
+// REPORTFILE-NEXT: TOTAL 12 2 83.33% 2 0 100.00% 17 3 82.35% 12 6 50.00%
diff --git a/llvm/test/tools/llvm-cov/coverage_watermark.test b/llvm/test/tools/llvm-cov/coverage_watermark.test
index 5c48b4f0fb4bf4..818baa470bc38d 100644
--- a/llvm/test/tools/llvm-cov/coverage_watermark.test
+++ b/llvm/test/tools/llvm-cov/coverage_watermark.test
@@ -18,15 +18,15 @@ ORIGIN: <td class='column-entry-green'>
ORIGIN: 100.00% (2/2)
ORIGIN: <td class='column-entry-green'>
ORIGIN: 100.00% (3/3)
-ORIGIN: <td class='column-entry-red'>
-ORIGIN: 75.00% (9/12)
-ORIGIN: <td class='column-entry-red'>
-ORIGIN: 66.67% (4/6)
+ORIGIN: <td class='column-entry-yellow'>
+ORIGIN: 83.33% (10/12)
+ORIGIN: <td class='column-entry-yellow'>
+ORIGIN: 83.33% (5/6)
ORIGIN: <td class='column-entry-gray'>
ORIGIN: - (0/0)
ORIGIN: </tr>
-RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -format html -show-region-summary -show-instantiation-summary -o %t.html.dir -path-equivalence=/tmp,%S -coverage-watermark 80,70 %S/showTemplateInstantiations.cpp
+RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -format html -show-region-summary -show-instantiation-summary -o %t.html.dir -path-equivalence=/tmp,%S -coverage-watermark 90,70 %S/showTemplateInstantiations.cpp
RUN: FileCheck -check-prefix=DOWNGRADE1 %s -input-file %t.html.dir/index.html
DOWNGRADE:1 Totals
@@ -35,9 +35,9 @@ DOWNGRADE1: 100.00% (2/2)
DOWNGRADE1: <td class='column-entry-green'>
DOWNGRADE1: 100.00% (3/3)
DOWNGRADE1: <td class='column-entry-yellow'>
-DOWNGRADE1: 75.00% (9/12)
-DOWNGRADE1: <td class='column-entry-red'>
-DOWNGRADE1: 66.67% (4/6)
+DOWNGRADE1: 83.33% (10/12)
+DOWNGRADE1: <td class='column-entry-yellow'>
+DOWNGRADE1: 83.33% (5/6)
DOWNGRADE1: <td class='column-entry-gray'>
DOWNGRADE1: - (0/0)
DOWNGRADE1: </tr>
@@ -51,9 +51,9 @@ DOWNGRADE2: 100.00% (2/2)
DOWNGRADE2: <td class='column-entry-green'>
DOWNGRADE2: 100.00% (3/3)
DOWNGRADE2: <td class='column-entry-green'>
-DOWNGRADE2: 75.00% (9/12)
-DOWNGRADE2: <td class='column-entry-yellow'>
-DOWNGRADE2: 66.67% (4/6)
+DOWNGRADE2: 83.33% (10/12)
+DOWNGRADE2: <td class='column-entry-green'>
+DOWNGRADE2: 83.33% (5/6)
DOWNGRADE1: <td class='column-entry-gray'>
DOWNGRADE1: - (0/0)
DOWNGRADE1: </tr>
diff --git a/llvm/test/tools/llvm-cov/zeroFunctionFile.c b/llvm/test/tools/llvm-cov/zeroFunctionFile.c
index f463007fe7f60f..28caa5ac241650 100644
--- a/llvm/test/tools/llvm-cov/zeroFunctionFile.c
+++ b/llvm/test/tools/llvm-cov/zeroFunctionFile.c
@@ -16,5 +16,4 @@ int main() {
// RUN: llvm-cov show -j 1 %S/Inputs/zeroFunctionFile.covmapping -format html -instr-profile %t.profdata -o %t.dir
// RUN: FileCheck %s -input-file=%t.dir/index.html -check-prefix=HTML
// HTML-NO: 0.00% (0/0)
-// HTML: Files which contain no functions
-// HTML: zeroFunctionFile.h
+// HTML-NOT: Files which contain no functions
diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp b/llvm/tools/llvm-cov/CoverageReport.cpp
index 00aea4039bfdeb..0046b968756dd0 100644
--- a/llvm/tools/llvm-cov/CoverageReport.cpp
+++ b/llvm/tools/llvm-cov/CoverageReport.cpp
@@ -446,27 +446,47 @@ void CoverageReport::prepareSingleFileReport(const StringRef Filename,
const coverage::CoverageMapping *Coverage,
const CoverageViewOptions &Options, const unsigned LCP,
FileCoverageSummary *FileReport, const CoverageFilter *Filters) {
+ DenseSet<const coverage::FunctionRecord *> FilteredOutFunctions;
+ assert(FileReport->empty());
for (const auto &Group : Coverage->getInstantiationGroups(Filename)) {
- std::vector<FunctionCoverageSummary> InstantiationSummaries;
+ bool Updated = false;
for (const coverage::FunctionRecord *F : Group.getInstantiations()) {
- if (!Filters->matches(*Coverage, *F))
+ if (!Filters->matches(*Coverage, *F)) {
+ FilteredOutFunctions.insert(F);
continue;
- auto InstantiationSummary = FunctionCoverageSummary::get(*Coverage, *F);
- FileReport->addInstantiation(InstantiationSummary);
- InstantiationSummaries.push_back(InstantiationSummary);
+ }
+ FileReport->InstantiationCoverage.addFunction(
+ /*Covered=*/F->ExecutionCount > 0);
+ Updated = true;
}
- if (InstantiationSummaries.empty())
+ if (!Updated)
continue;
- auto GroupSummary =
- FunctionCoverageSummary::get(Group, InstantiationSummaries);
+ if (Options.Debug) {
+ 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();
+ }
- if (Options.Debug)
- outs() << "InstantiationGroup: " << GroupSummary.Name << " with "
+ outs() << "InstantiationGroup: " << Name << " with "
<< "size = " << Group.size() << "\n";
+ }
- FileReport->addFunction(GroupSummary);
+ FileReport->FunctionCoverage.addFunction(
+ /*Covered=*/Group.getTotalExecutionCount() > 0);
}
+
+ auto FileCoverage =
+ Coverage->getCoverageForFile(Filename, FilteredOutFunctions);
+ if (FileCoverage.empty())
+ return;
+
+ *static_cast<CoverageDataSummary *>(FileReport) +=
+ CoverageDataSummary(FileCoverage);
}
std::vector<FileCoverageSummary> CoverageReport::prepareFileReports(
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
index 86d11266ecdd7c..745a92103bccc9 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
@@ -110,29 +110,3 @@ FunctionCoverageSummary::get(const CoverageMapping &CM,
return Summary;
}
-
-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, Group.getTotalExecutionCount());
- Summary.RegionCoverage = Summaries[0].RegionCoverage;
- Summary.LineCoverage = Summaries[0].LineCoverage;
- Summary.BranchCoverage = Summaries[0].BranchCoverage;
- Summary.MCDCCoverage = Summaries[0].MCDCCoverage;
- for (const auto &FCS : Summaries.drop_front()) {
- Summary.RegionCoverage.merge(FCS.RegionCoverage);
- Summary.LineCoverage.merge(FCS.LineCoverage);
- Summary.BranchCoverage.merge(FCS.BranchCoverage);
- Summary.MCDCCoverage.merge(FCS.MCDCCoverage);
- }
- return Summary;
-}
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
index 42398ee06100e2..09ceba5de72719 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
@@ -41,11 +41,6 @@ class RegionCoverageInfo {
return *this;
}
- void merge(const RegionCoverageInfo &RHS) {
- Covered = std::max(Covered, RHS.Covered);
- NumRegions = std::max(NumRegions, RHS.NumRegions);
- }
-
size_t getCovered() const { return Covered; }
size_t getNumRegions() const { return NumRegions; }
@@ -82,11 +77,6 @@ class LineCoverageInfo {
return *this;
}
- void merge(const LineCoverageInfo &RHS) {
- Covered = std::max(Covered, RHS.Covered);
- NumLines = std::max(NumLines, RHS.NumLines);
- }
-
size_t getCovered() const { return Covered; }
size_t getNumLines() const { return NumLines; }
@@ -123,11 +113,6 @@ class BranchCoverageInfo {
return *this;
}
- void merge(const BranchCoverageInfo &RHS) {
- Covered = std::max(Covered, RHS.Covered);
- NumBranches = std::max(NumBranches, RHS.NumBranches);
- }
-
size_t getCovered() const { return Covered; }
size_t getNumBranches() const { return NumBranches; }
@@ -164,11 +149,6 @@ class MCDCCoverageInfo {
return *this;
}
- void merge(const MCDCCoverageInfo &RHS) {
- CoveredPairs = std::max(CoveredPairs, RHS.CoveredPairs);
- NumPairs = std::max(NumPairs, RHS.NumPairs);
- }
-
size_t getCoveredPairs() const { return CoveredPairs; }
size_t getNumPairs() const { return NumPairs; }
@@ -232,6 +212,13 @@ struct CoverageDataSummary {
CoverageDataSummary() = default;
CoverageDataSummary(const coverage::CoverageData &CD);
+ bool empty() const {
+ return (RegionCoverage.getNumRegions() == 0 &&
+ LineCoverage.getNumLines() == 0 &&
+ BranchCoverage.getNumBranches() == 0 &&
+ MCDCCoverage.getNumPairs() == 0);
+ }
+
auto &operator+=(const CoverageDataSummary &RHS) {
RegionCoverage += RHS.RegionCoverage;
LineCoverage += RHS.LineCoverage;
@@ -253,12 +240,6 @@ struct FunctionCoverageSummary : CoverageDataSummary {
/// mapping record.
static FunctionCoverageSummary get(const coverage::CoverageMapping &CM,
const coverage::FunctionRecord &Function);
-
- /// Compute the code coverage summary for an instantiation group \p Group,
- /// given a list of summaries for each instantiation in \p Summaries.
- static FunctionCoverageSummary
- get(const coverage::InstantiationGroup &Group,
- ArrayRef<FunctionCoverageSummary> Summaries);
};
/// A summary of file's code coverage.
@@ -270,24 +251,18 @@ struct FileCoverageSummary : CoverageDataSummary {
FileCoverageSummary() = default;
FileCoverageSummary(StringRef Name) : Name(Name) {}
+ bool empty() const {
+ return (CoverageDataSummary::empty() &&
+ FunctionCoverage.getNumFunctions() == 0 &&
+ InstantiationCoverage.getNumFunctions() == 0);
+ }
+
FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) {
*static_cast<CoverageDataSummary *>(this) += RHS;
FunctionCoverage += RHS.FunctionCoverage;
InstantiationCoverage += RHS.InstantiationCoverage;
return *this;
}
-
- void addFunction(const FunctionCoverageSummary &Function) {
- RegionCoverage += Function.RegionCoverage;
- LineCoverage += Function.LineCoverage;
- BranchCoverage += Function.BranchCoverage;
- MCDCCoverage += Function.MCDCCoverage;
- FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
- }
-
- void addInstantiation(const FunctionCoverageSummary &Function) {
- InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0);
- }
};
/// A cache for demangled symbols.
diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
index c94d3853fc0143..cb0ea6e0cdafc3 100644
--- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
@@ -23,6 +23,16 @@ using namespace llvm;
namespace {
+template <class SummaryTy>
+bool IsSummaryEmpty(const SummaryTy &Report, const CoverageViewOptions &Opts) {
+ return !(Report.FunctionCoverage.getNumFunctions() ||
+ (Opts.ShowInstantiationSummary &&
+ Report.InstantiationCoverage.getNumFunctions()) ||
+ (Opts.ShowRegionSummary && Report.RegionCoverage.getNumRegions()) ||
+ (Opts.ShowBranchSummary && Report.BranchCoverage.getNumBranches()) ||
+ (Opts.ShowMCDCSummary && Report.MCDCCoverage.getNumPairs()));
+}
+
// Return a string with the special characters in \p Str escaped.
std::string escape(StringRef Str, const CoverageViewOptions &Opts) {
std::string TabExpandedResult;
@@ -666,7 +676,7 @@ Error CoveragePrinterHTML::createIndexFile(
Coverage, Totals, SourceFiles, Opts, Filters);
bool EmptyFiles = false;
for (unsigned I = 0, E = FileReports.size(); I < E; ++I) {
- if (FileReports[I].FunctionCoverage.getNumFunctions())
+ if (!IsSummaryEmpty(FileReports[I], Opts))
emitFileSummary(OSRef, SourceFiles[I], FileReports[I]);
else
EmptyFiles = true;
@@ -734,7 +744,7 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport {
// Make directories at the top of the table.
for (auto &&SubDir : SubDirs) {
auto &Report = SubDir.second.first;
- if (!Report.FunctionCoverage.getNumFunctions())
+ if (IsSummaryEmpty(Report, Printer.Opts))
EmptyFiles.push_back(&Report);
else
emitTableRow(OSRef, Options, buildRelLinkToFile(Report.Name), Report,
@@ -743,7 +753,7 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport {
for (auto &&SubFile : SubFiles) {
auto &Report = SubFile.second;
- if (!Report.FunctionCoverage.getNumFunctions())
+ if (IsSummaryEmpty(Report, Printer.Opts))
EmptyFiles.push_back(&Report);
else
emitTableRow(OSRef, Options, buildRelLinkToFile(Report.Name), Report,
|
@@ -23,6 +23,16 @@ using namespace llvm; | |||
|
|||
namespace { | |||
|
|||
template <class SummaryTy> | |||
bool IsSummaryEmpty(const SummaryTy &Report, const CoverageViewOptions &Opts) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
function name case should be isSummaryEmpty
@@ -23,6 +23,16 @@ using namespace llvm; | |||
|
|||
namespace { | |||
|
|||
template <class SummaryTy> | |||
bool IsSummaryEmpty(const SummaryTy &Report, const CoverageViewOptions &Opts) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
case should be isSummaryEmpty
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
why? |
@@ -1432,6 +1434,8 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { | |||
getImpreciseRecordIndicesForFilename(Filename); | |||
for (unsigned RecordIndex : RecordIndices) { | |||
const FunctionRecord &Function = Functions[RecordIndex]; | |||
if (FilteredOutFunctions.count(&Function)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the commit message, it is not obvious to me why we are now filtering out functions. Can you explain?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The caller, llvm-cov, has the filter. I chose "blacklist" (rather than whitelist) since it is expected empty in usual cases.
They will be reintroduced later, "Any" in #121194 . |
FunctionCoverageSummary::get()
is removed since it was used only fromSingleFileReport
. "Merge" facilities withstd::max
are removed as well for now. They will be re-introduced later.For file indices, show also files that have no functions but any other
CoverageInfo
.Fixes #119282
Depends on: #120842, #121188, #121191