Skip to content

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

Open
wants to merge 5 commits into
base: users/chapuni/cov/merge/forfile-base
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -1023,7 +1023,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;
Expand Down
6 changes: 5 additions & 1 deletion llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1448,7 +1448,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);

Expand All @@ -1458,6 +1460,8 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
getImpreciseRecordIndicesForFilename(Filename);
for (unsigned RecordIndex : RecordIndices) {
const FunctionRecord &Function = Functions[RecordIndex];
if (FilteredOutFunctions.count(&Function))
Copy link

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?

Copy link
Contributor Author

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.

continue;
auto MainFileID = findMainViewFileID(Filename, Function);
auto FileIDs = gatherFileIDs(Filename, Function);
FileCoverage.addFunctionRegions(
Expand Down
4 changes: 2 additions & 2 deletions llvm/test/tools/llvm-cov/branch-macros.test
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@

// FILE: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover
// FILE-NEXT: ---
// FILE-NEXT: branch-macros.cpp 16 4 75.00% 3 0 100.00% 32 0 100.00% 40 16 60.00%
// FILE-NEXT: branch-macros.cpp 28 5 82.14% 3 0 100.00% 39 0 100.00% 40 16 60.00%
// FILE-NEXT: ---
// FILE-NEXT: TOTAL 16 4 75.00% 3 0 100.00% 32 0 100.00% 40 16 60.00%
// FILE-NEXT: TOTAL 28 5 82.14% 3 0 100.00% 39 0 100.00% 40 16 60.00%
4 changes: 2 additions & 2 deletions llvm/test/tools/llvm-cov/branch-templates.test
Original file line number Diff line number Diff line change
Expand Up @@ -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%
22 changes: 11 additions & 11 deletions llvm/test/tools/llvm-cov/coverage_watermark.test
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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>
Expand All @@ -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>
4 changes: 2 additions & 2 deletions llvm/test/tools/llvm-cov/mcdc-templates-merge.test
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ CHECK: 3 0 100.00%
CHECK: 19 1 94.74%

# Branches
CHECK: 11 3 72.73%
CHECK: 24 9 62.50%

# MC/DC Conditions
CHECK: 4 2 50.00%
CHECK: 10 7 30.00%

REPORT: TOTAL
3 changes: 1 addition & 2 deletions llvm/test/tools/llvm-cov/zeroFunctionFile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
42 changes: 31 additions & 11 deletions llvm/tools/llvm-cov/CoverageReport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
26 changes: 0 additions & 26 deletions llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
51 changes: 13 additions & 38 deletions llvm/tools/llvm-cov/CoverageSummaryInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand Down Expand Up @@ -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; }
Expand Down Expand Up @@ -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; }
Expand Down Expand Up @@ -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; }
Expand Down Expand Up @@ -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;
Expand All @@ -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.
Expand All @@ -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.
Expand Down
16 changes: 13 additions & 3 deletions llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
Loading