summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cov
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-cov')
-rw-r--r--llvm/tools/llvm-cov/CMakeLists.txt1
-rw-r--r--llvm/tools/llvm-cov/CodeCoverage.cpp369
-rw-r--r--llvm/tools/llvm-cov/CoverageFilters.cpp14
-rw-r--r--llvm/tools/llvm-cov/CoverageFilters.h18
-rw-r--r--llvm/tools/llvm-cov/CoverageSummary.cpp4
-rw-r--r--llvm/tools/llvm-cov/CoverageSummary.h2
-rw-r--r--llvm/tools/llvm-cov/CoverageSummaryInfo.cpp2
-rw-r--r--llvm/tools/llvm-cov/CoverageSummaryInfo.h2
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageDataManager.cpp104
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageDataManager.h53
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.cpp22
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.h23
12 files changed, 137 insertions, 477 deletions
diff --git a/llvm/tools/llvm-cov/CMakeLists.txt b/llvm/tools/llvm-cov/CMakeLists.txt
index 54d9ece3988..b2d2b897ec9 100644
--- a/llvm/tools/llvm-cov/CMakeLists.txt
+++ b/llvm/tools/llvm-cov/CMakeLists.txt
@@ -8,7 +8,6 @@ add_llvm_tool(llvm-cov
CoverageReport.cpp
CoverageSummary.cpp
CoverageSummaryInfo.cpp
- SourceCoverageDataManager.cpp
SourceCoverageView.cpp
TestingSupport.cpp
)
diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp
index 1a5d6a50f9e..5fc5a849cec 100644
--- a/llvm/tools/llvm-cov/CodeCoverage.cpp
+++ b/llvm/tools/llvm-cov/CodeCoverage.cpp
@@ -16,15 +16,11 @@
#include "RenderingSupport.h"
#include "CoverageViewOptions.h"
#include "CoverageFilters.h"
-#include "SourceCoverageDataManager.h"
#include "SourceCoverageView.h"
#include "CoverageSummary.h"
#include "CoverageReport.h"
-#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/SmallString.h"
-#include "llvm/ADT/SmallSet.h"
-#include "llvm/ADT/DenseSet.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/ProfileData/CoverageMapping.h"
#include "llvm/ProfileData/CoverageMappingReader.h"
@@ -43,34 +39,6 @@ using namespace llvm;
using namespace coverage;
namespace {
-/// \brief Distribute the functions into instantiation sets.
-///
-/// An instantiation set is a collection of functions that have the same source
-/// code, ie, template functions specializations.
-class FunctionInstantiationSetCollector {
- typedef DenseMap<std::pair<unsigned, unsigned>,
- std::vector<const FunctionCoverageMapping *>> MapT;
- MapT InstantiatedFunctions;
-
-public:
- void insert(const FunctionCoverageMapping &Function, unsigned FileID) {
- auto I = Function.CountedRegions.begin(), E = Function.CountedRegions.end();
- while (I != E && I->FileID != FileID)
- ++I;
- assert(I != E && "function does not cover the given file");
- auto &Functions = InstantiatedFunctions[I->startLoc()];
- Functions.push_back(&Function);
- }
-
- MapT::iterator begin() {
- return InstantiatedFunctions.begin();
- }
-
- MapT::iterator end() {
- return InstantiatedFunctions.end();
- }
-};
-
/// \brief The implementation of the coverage tool.
class CodeCoverageTool {
public:
@@ -87,43 +55,21 @@ public:
/// \brief Return a memory buffer for the given source file.
ErrorOr<const MemoryBuffer &> getSourceFile(StringRef SourceFile);
- /// \brief Collect a set of function's file ids which correspond to the
- /// given source file. Return false if the set is empty.
- bool gatherInterestingFileIDs(StringRef SourceFile,
- const FunctionCoverageMapping &Function,
- SmallSet<unsigned, 8> &InterestingFileIDs);
+ /// \brief Create source views for the expansions of the view.
+ void attachExpansionSubViews(SourceCoverageView &View,
+ ArrayRef<ExpansionRecord> Expansions,
+ CoverageMapping &Coverage);
- /// \brief Find the file id which is not an expanded file id.
- bool findMainViewFileID(StringRef SourceFile,
- const FunctionCoverageMapping &Function,
- unsigned &MainViewFileID);
-
- bool findMainViewFileID(const FunctionCoverageMapping &Function,
- unsigned &MainViewFileID);
-
- /// \brief Create a source view which shows coverage for an expansion
- /// of a file.
- std::unique_ptr<SourceCoverageView>
- createExpansionSubView(const CountedRegion &ExpandedRegion,
- const FunctionCoverageMapping &Function);
-
- void attachExpansionSubViews(SourceCoverageView &View, unsigned ViewFileID,
- const FunctionCoverageMapping &Function);
-
- /// \brief Create a source view which shows coverage for an instantiation
- /// of a funciton.
+ /// \brief Create the source view of a particular function.
std::unique_ptr<SourceCoverageView>
- createInstantiationSubView(StringRef SourceFile,
- const FunctionCoverageMapping &Function);
+ createFunctionView(const FunctionRecord &Function, CoverageMapping &Coverage);
/// \brief Create the main source view of a particular source file.
std::unique_ptr<SourceCoverageView>
- createSourceFileView(StringRef SourceFile,
- ArrayRef<FunctionCoverageMapping> FunctionMappingRecords,
- bool UseOnlyRegionsInMainFile = false);
+ createSourceFileView(StringRef SourceFile, CoverageMapping &Coverage);
/// \brief Load the coverage mapping data. Return true if an error occured.
- bool load();
+ std::unique_ptr<CoverageMapping> load();
int run(Command Cmd, int argc, const char **argv);
@@ -137,29 +83,16 @@ public:
StringRef ObjectFilename;
CoverageViewOptions ViewOpts;
- std::unique_ptr<IndexedInstrProfReader> PGOReader;
+ std::string PGOFilename;
CoverageFiltersMatchAll Filters;
std::vector<std::string> SourceFiles;
std::vector<std::pair<std::string, std::unique_ptr<MemoryBuffer>>>
LoadedSourceFiles;
- std::vector<FunctionCoverageMapping> FunctionMappingRecords;
bool CompareFilenamesOnly;
StringMap<std::string> RemappedFilenames;
};
}
-static std::vector<StringRef>
-getUniqueFilenames(ArrayRef<FunctionCoverageMapping> FunctionMappingRecords) {
- std::vector<StringRef> Filenames;
- for (const auto &Function : FunctionMappingRecords)
- for (const auto &Filename : Function.Filenames)
- Filenames.push_back(Filename);
- std::sort(Filenames.begin(), Filenames.end());
- auto Last = std::unique(Filenames.begin(), Filenames.end());
- Filenames.erase(Last, Filenames.end());
- return Filenames;
-}
-
void CodeCoverageTool::error(const Twine &Message, StringRef Whence) {
errs() << "error: ";
if (!Whence.empty())
@@ -188,219 +121,115 @@ CodeCoverageTool::getSourceFile(StringRef SourceFile) {
return *LoadedSourceFiles.back().second;
}
-bool CodeCoverageTool::gatherInterestingFileIDs(
- StringRef SourceFile, const FunctionCoverageMapping &Function,
- SmallSet<unsigned, 8> &InterestingFileIDs) {
- bool Interesting = false;
- for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I) {
- if (SourceFile == Function.Filenames[I]) {
- InterestingFileIDs.insert(I);
- Interesting = true;
- }
- }
- return Interesting;
-}
-
-bool
-CodeCoverageTool::findMainViewFileID(StringRef SourceFile,
- const FunctionCoverageMapping &Function,
- unsigned &MainViewFileID) {
- llvm::SmallVector<bool, 8> IsExpandedFile(Function.Filenames.size(), false);
- llvm::SmallVector<bool, 8> FilenameEquivalence(Function.Filenames.size(),
- false);
- for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I) {
- if (SourceFile == Function.Filenames[I])
- FilenameEquivalence[I] = true;
- }
- for (const auto &CR : Function.CountedRegions) {
- if (CR.Kind == CounterMappingRegion::ExpansionRegion &&
- FilenameEquivalence[CR.FileID])
- IsExpandedFile[CR.ExpandedFileID] = true;
- }
- for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I) {
- if (!FilenameEquivalence[I] || IsExpandedFile[I])
- continue;
- MainViewFileID = I;
- return false;
- }
- return true;
-}
-
-bool
-CodeCoverageTool::findMainViewFileID(const FunctionCoverageMapping &Function,
- unsigned &MainViewFileID) {
- llvm::SmallVector<bool, 8> IsExpandedFile(Function.Filenames.size(), false);
- for (const auto &CR : Function.CountedRegions) {
- if (CR.Kind == CounterMappingRegion::ExpansionRegion)
- IsExpandedFile[CR.ExpandedFileID] = true;
- }
- for (unsigned I = 0, E = Function.Filenames.size(); I < E; ++I) {
- if (IsExpandedFile[I])
- continue;
- MainViewFileID = I;
- return false;
- }
- return true;
-}
-
-std::unique_ptr<SourceCoverageView> CodeCoverageTool::createExpansionSubView(
- const CountedRegion &ExpandedRegion,
- const FunctionCoverageMapping &Function) {
- auto SourceBuffer =
- getSourceFile(Function.Filenames[ExpandedRegion.ExpandedFileID]);
- if (!SourceBuffer)
- return nullptr;
- auto RegionManager = llvm::make_unique<SourceCoverageDataManager>();
- for (const auto &CR : Function.CountedRegions) {
- if (CR.FileID == ExpandedRegion.ExpandedFileID)
- RegionManager->insert(CR);
- }
- auto SubView = llvm::make_unique<SourceCoverageView>(SourceBuffer.get(),
- ViewOpts);
- SubView->load(std::move(RegionManager));
- attachExpansionSubViews(*SubView, ExpandedRegion.ExpandedFileID, Function);
- return SubView;
-}
-
-void CodeCoverageTool::attachExpansionSubViews(
- SourceCoverageView &View, unsigned ViewFileID,
- const FunctionCoverageMapping &Function) {
+void
+CodeCoverageTool::attachExpansionSubViews(SourceCoverageView &View,
+ ArrayRef<ExpansionRecord> Expansions,
+ CoverageMapping &Coverage) {
if (!ViewOpts.ShowExpandedRegions)
return;
- for (const auto &CR : Function.CountedRegions) {
- if (CR.Kind != CounterMappingRegion::ExpansionRegion)
+ for (const auto &Expansion : Expansions) {
+ auto ExpansionCoverage = Coverage.getCoverageForExpansion(Expansion);
+ if (ExpansionCoverage.empty())
continue;
- if (CR.FileID != ViewFileID)
+ auto SourceBuffer = getSourceFile(ExpansionCoverage.getFilename());
+ if (!SourceBuffer)
continue;
- auto SubView = createExpansionSubView(CR, Function);
- if (SubView)
- View.addExpansion(CR, std::move(SubView));
+
+ auto SubViewExpansions = ExpansionCoverage.getExpansions();
+ auto SubView = llvm::make_unique<SourceCoverageView>(
+ SourceBuffer.get(), ViewOpts, std::move(ExpansionCoverage));
+ attachExpansionSubViews(*SubView, SubViewExpansions, Coverage);
+ View.addExpansion(Expansion.Region, std::move(SubView));
}
}
std::unique_ptr<SourceCoverageView>
-CodeCoverageTool::createInstantiationSubView(
- StringRef SourceFile, const FunctionCoverageMapping &Function) {
- auto RegionManager = llvm::make_unique<SourceCoverageDataManager>();
- SmallSet<unsigned, 8> InterestingFileIDs;
- if (!gatherInterestingFileIDs(SourceFile, Function, InterestingFileIDs))
+CodeCoverageTool::createFunctionView(const FunctionRecord &Function,
+ CoverageMapping &Coverage) {
+ auto FunctionCoverage = Coverage.getCoverageForFunction(Function);
+ if (FunctionCoverage.empty())
return nullptr;
- // Get the interesting regions
- for (const auto &CR : Function.CountedRegions) {
- if (InterestingFileIDs.count(CR.FileID))
- RegionManager->insert(CR);
- }
-
- auto SourceBuffer = getSourceFile(SourceFile);
+ auto SourceBuffer = getSourceFile(FunctionCoverage.getFilename());
if (!SourceBuffer)
return nullptr;
- auto SubView = llvm::make_unique<SourceCoverageView>(SourceBuffer.get(),
- ViewOpts);
- SubView->load(std::move(RegionManager));
- unsigned MainFileID;
- if (!findMainViewFileID(SourceFile, Function, MainFileID))
- attachExpansionSubViews(*SubView, MainFileID, Function);
- return SubView;
-}
-std::unique_ptr<SourceCoverageView> CodeCoverageTool::createSourceFileView(
- StringRef SourceFile,
- ArrayRef<FunctionCoverageMapping> FunctionMappingRecords,
- bool UseOnlyRegionsInMainFile) {
- auto RegionManager = llvm::make_unique<SourceCoverageDataManager>();
- FunctionInstantiationSetCollector InstantiationSetCollector;
+ auto Expansions = FunctionCoverage.getExpansions();
+ auto View = llvm::make_unique<SourceCoverageView>(
+ SourceBuffer.get(), ViewOpts, std::move(FunctionCoverage));
+ attachExpansionSubViews(*View, Expansions, Coverage);
+
+ return View;
+}
+std::unique_ptr<SourceCoverageView>
+CodeCoverageTool::createSourceFileView(StringRef SourceFile,
+ CoverageMapping &Coverage) {
auto SourceBuffer = getSourceFile(SourceFile);
if (!SourceBuffer)
return nullptr;
- auto View =
- llvm::make_unique<SourceCoverageView>(SourceBuffer.get(), ViewOpts);
-
- for (const auto &Function : FunctionMappingRecords) {
- unsigned MainFileID;
- if (findMainViewFileID(SourceFile, Function, MainFileID))
- continue;
- SmallSet<unsigned, 8> InterestingFileIDs;
- if (UseOnlyRegionsInMainFile) {
- InterestingFileIDs.insert(MainFileID);
- } else if (!gatherInterestingFileIDs(SourceFile, Function,
- InterestingFileIDs))
- continue;
- // Get the interesting regions
- for (const auto &CR : Function.CountedRegions) {
- if (InterestingFileIDs.count(CR.FileID))
- RegionManager->insert(CR);
- }
- InstantiationSetCollector.insert(Function, MainFileID);
- attachExpansionSubViews(*View, MainFileID, Function);
- }
- if (RegionManager->getCoverageSegments().empty())
+ auto FileCoverage = Coverage.getCoverageForFile(SourceFile);
+ if (FileCoverage.empty())
return nullptr;
- View->load(std::move(RegionManager));
- // Show instantiations
- if (!ViewOpts.ShowFunctionInstantiations)
- return View;
- for (const auto &InstantiationSet : InstantiationSetCollector) {
- if (InstantiationSet.second.size() < 2)
- continue;
- for (auto Function : InstantiationSet.second) {
+
+ auto Expansions = FileCoverage.getExpansions();
+ auto View = llvm::make_unique<SourceCoverageView>(
+ SourceBuffer.get(), ViewOpts, std::move(FileCoverage));
+ attachExpansionSubViews(*View, Expansions, Coverage);
+
+ for (auto Function : Coverage.getInstantiations(SourceFile)) {
+ auto SubViewCoverage = Coverage.getCoverageForFunction(*Function);
+ auto SubViewExpansions = SubViewCoverage.getExpansions();
+ auto SubView = llvm::make_unique<SourceCoverageView>(
+ SourceBuffer.get(), ViewOpts, std::move(SubViewCoverage));
+ attachExpansionSubViews(*SubView, SubViewExpansions, Coverage);
+
+ if (SubView) {
unsigned FileID = Function->CountedRegions.front().FileID;
unsigned Line = 0;
for (const auto &CR : Function->CountedRegions)
if (CR.FileID == FileID)
Line = std::max(CR.LineEnd, Line);
- auto SubView = createInstantiationSubView(SourceFile, *Function);
- if (SubView)
- View->addInstantiation(Function->Name, Line, std::move(SubView));
+ View->addInstantiation(Function->Name, Line, std::move(SubView));
}
}
return View;
}
-bool CodeCoverageTool::load() {
+std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
auto CounterMappingBuff = MemoryBuffer::getFileOrSTDIN(ObjectFilename);
if (auto EC = CounterMappingBuff.getError()) {
error(EC.message(), ObjectFilename);
- return true;
+ return nullptr;
}
ObjectFileCoverageMappingReader MappingReader(CounterMappingBuff.get());
if (auto EC = MappingReader.readHeader()) {
error(EC.message(), ObjectFilename);
- return true;
+ return nullptr;
}
- std::vector<uint64_t> Counts;
- for (const auto &I : MappingReader) {
- FunctionCoverageMapping Function(I.FunctionName, I.Filenames);
-
- // Create the mapping regions with evaluated execution counts
- Counts.clear();
- PGOReader->getFunctionCounts(Function.Name, I.FunctionHash, Counts);
-
- // Get the biggest referenced counters
- bool RegionError = false;
- CounterMappingContext Ctx(I.Expressions, Counts);
- for (const auto &R : I.MappingRegions) {
- ErrorOr<int64_t> ExecutionCount = Ctx.evaluate(R.Count);
- if (ExecutionCount) {
- Function.CountedRegions.push_back(CountedRegion(R, *ExecutionCount));
- } else if (!RegionError) {
- colored_ostream(errs(), raw_ostream::RED)
- << "error: Regions and counters don't match in a function '"
- << Function.Name << "' (re-run the instrumented binary).";
- errs() << "\n";
- RegionError = true;
- }
- }
-
- if (RegionError || !Filters.matches(Function))
- continue;
+ std::unique_ptr<IndexedInstrProfReader> PGOReader;
+ if (auto EC = IndexedInstrProfReader::create(PGOFilename, PGOReader)) {
+ error(EC.message(), PGOFilename);
+ return nullptr;
+ }
- FunctionMappingRecords.push_back(Function);
+ auto CoverageOrErr = CoverageMapping::load(MappingReader, *PGOReader);
+ if (std::error_code EC = CoverageOrErr.getError()) {
+ colored_ostream(errs(), raw_ostream::RED)
+ << "error: Failed to load coverage: " << EC.message();
+ errs() << "\n";
+ return nullptr;
+ }
+ auto Coverage = std::move(CoverageOrErr.get());
+ unsigned Mismatched = Coverage->getMismatchedCount();
+ if (Mismatched) {
+ colored_ostream(errs(), raw_ostream::RED)
+ << "warning: " << Mismatched << " functions have mismatched data. ";
+ errs() << "\n";
}
if (CompareFilenamesOnly) {
- auto CoveredFiles = getUniqueFilenames(FunctionMappingRecords);
+ auto CoveredFiles = Coverage.get()->getUniqueSourceFiles();
for (auto &SF : SourceFiles) {
StringRef SFBase = sys::path::filename(SF);
for (const auto &CF : CoveredFiles)
@@ -412,7 +241,7 @@ bool CodeCoverageTool::load() {
}
}
- return false;
+ return Coverage;
}
int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
@@ -424,8 +253,8 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
cl::list<std::string> InputSourceFiles(
cl::Positional, cl::desc("<Source files>"), cl::ZeroOrMore);
- cl::opt<std::string> PGOFilename(
- "instr-profile", cl::Required,
+ cl::opt<std::string, true> PGOFilename(
+ "instr-profile", cl::Required, cl::location(this->PGOFilename),
cl::desc(
"File with the profile data obtained after an instrumented run"));
@@ -479,11 +308,6 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
ViewOpts.Debug = DebugDump;
CompareFilenamesOnly = FilenameEquivalence;
- if (auto EC = IndexedInstrProfReader::create(PGOFilename, PGOReader)) {
- error(EC.message(), PGOFilename);
- return 1;
- }
-
// Create the function filters
if (!NameFilters.empty() || !NameRegexFilters.empty()) {
auto NameFilterer = new CoverageFilters;
@@ -597,30 +421,28 @@ int CodeCoverageTool::show(int argc, const char **argv,
ViewOpts.ShowExpandedRegions = ShowExpansions;
ViewOpts.ShowFunctionInstantiations = ShowInstantiations;
- if (load())
+ auto Coverage = load();
+ if (!Coverage)
return 1;
if (!Filters.empty()) {
// Show functions
- for (const auto &Function : FunctionMappingRecords) {
- unsigned MainFileID;
- if (findMainViewFileID(Function, MainFileID))
+ for (const auto &Function : Coverage->getCoveredFunctions()) {
+ if (!Filters.matches(Function))
continue;
- StringRef SourceFile = Function.Filenames[MainFileID];
- auto mainView = createSourceFileView(SourceFile, Function, true);
+
+ auto mainView = createFunctionView(Function, *Coverage);
if (!mainView) {
ViewOpts.colored_ostream(outs(), raw_ostream::RED)
- << "warning: Could not read coverage for '" << Function.Name
- << " from " << SourceFile;
+ << "warning: Could not read coverage for '" << Function.Name;
outs() << "\n";
continue;
}
- ViewOpts.colored_ostream(outs(), raw_ostream::CYAN)
- << Function.Name << " from " << SourceFile << ":";
+ ViewOpts.colored_ostream(outs(), raw_ostream::CYAN) << Function.Name
+ << ":";
outs() << "\n";
mainView->render(outs(), /*WholeFile=*/false);
- if (FunctionMappingRecords.size() > 1)
- outs() << "\n";
+ outs() << "\n";
}
return 0;
}
@@ -630,11 +452,11 @@ int CodeCoverageTool::show(int argc, const char **argv,
if (SourceFiles.empty())
// Get the source files from the function coverage mapping
- for (StringRef Filename : getUniqueFilenames(FunctionMappingRecords))
+ for (StringRef Filename : Coverage->getUniqueSourceFiles())
SourceFiles.push_back(Filename);
for (const auto &SourceFile : SourceFiles) {
- auto mainView = createSourceFileView(SourceFile, FunctionMappingRecords);
+ auto mainView = createSourceFileView(SourceFile, *Coverage);
if (!mainView) {
ViewOpts.colored_ostream(outs(), raw_ostream::RED)
<< "warning: The file '" << SourceFile << "' isn't covered.";
@@ -665,11 +487,12 @@ int CodeCoverageTool::report(int argc, const char **argv,
ViewOpts.Colors = !NoColors;
- if (load())
+ auto Coverage = load();
+ if (!Coverage)
return 1;
CoverageSummary Summarizer;
- Summarizer.createSummaries(FunctionMappingRecords);
+ Summarizer.createSummaries(Coverage->getCoveredFunctions());
CoverageReport Report(ViewOpts, Summarizer);
if (SourceFiles.empty() && Filters.empty()) {
Report.renderFileReports(llvm::outs());
diff --git a/llvm/tools/llvm-cov/CoverageFilters.cpp b/llvm/tools/llvm-cov/CoverageFilters.cpp
index 999a6bbb747..325dd723578 100644
--- a/llvm/tools/llvm-cov/CoverageFilters.cpp
+++ b/llvm/tools/llvm-cov/CoverageFilters.cpp
@@ -17,21 +17,22 @@
using namespace llvm;
-bool NameCoverageFilter::matches(const FunctionCoverageMapping &Function) {
+bool NameCoverageFilter::matches(const coverage::FunctionRecord &Function) {
StringRef FuncName = Function.Name;
return FuncName.find(Name) != StringRef::npos;
}
-bool NameRegexCoverageFilter::matches(const FunctionCoverageMapping &Function) {
+bool
+NameRegexCoverageFilter::matches(const coverage::FunctionRecord &Function) {
return llvm::Regex(Regex).match(Function.Name);
}
-bool RegionCoverageFilter::matches(const FunctionCoverageMapping &Function) {
+bool RegionCoverageFilter::matches(const coverage::FunctionRecord &Function) {
return PassesThreshold(FunctionCoverageSummary::get(Function)
.RegionCoverage.getPercentCovered());
}
-bool LineCoverageFilter::matches(const FunctionCoverageMapping &Function) {
+bool LineCoverageFilter::matches(const coverage::FunctionRecord &Function) {
return PassesThreshold(
FunctionCoverageSummary::get(Function).LineCoverage.getPercentCovered());
}
@@ -40,7 +41,7 @@ void CoverageFilters::push_back(std::unique_ptr<CoverageFilter> Filter) {
Filters.push_back(std::move(Filter));
}
-bool CoverageFilters::matches(const FunctionCoverageMapping &Function) {
+bool CoverageFilters::matches(const coverage::FunctionRecord &Function) {
for (const auto &Filter : Filters) {
if (Filter->matches(Function))
return true;
@@ -48,7 +49,8 @@ bool CoverageFilters::matches(const FunctionCoverageMapping &Function) {
return false;
}
-bool CoverageFiltersMatchAll::matches(const FunctionCoverageMapping &Function) {
+bool
+CoverageFiltersMatchAll::matches(const coverage::FunctionRecord &Function) {
for (const auto &Filter : Filters) {
if (!Filter->matches(Function))
return false;
diff --git a/llvm/tools/llvm-cov/CoverageFilters.h b/llvm/tools/llvm-cov/CoverageFilters.h
index 99ecb791ffc..e543005c6bc 100644
--- a/llvm/tools/llvm-cov/CoverageFilters.h
+++ b/llvm/tools/llvm-cov/CoverageFilters.h
@@ -20,15 +20,15 @@
namespace llvm {
-using coverage::FunctionCoverageMapping;
-
/// \brief Matches specific functions that pass the requirement of this filter.
class CoverageFilter {
public:
virtual ~CoverageFilter() {}
/// \brief Return true if the function passes the requirements of this filter.
- virtual bool matches(const FunctionCoverageMapping &Function) { return true; }
+ virtual bool matches(const coverage::FunctionRecord &Function) {
+ return true;
+ }
};
/// \brief Matches functions that contain a specific string in their name.
@@ -38,7 +38,7 @@ class NameCoverageFilter : public CoverageFilter {
public:
NameCoverageFilter(StringRef Name) : Name(Name) {}
- bool matches(const FunctionCoverageMapping &Function) override;
+ bool matches(const coverage::FunctionRecord &Function) override;
};
/// \brief Matches functions whose name matches a certain regular expression.
@@ -48,7 +48,7 @@ class NameRegexCoverageFilter : public CoverageFilter {
public:
NameRegexCoverageFilter(StringRef Regex) : Regex(Regex) {}
- bool matches(const FunctionCoverageMapping &Function) override;
+ bool matches(const coverage::FunctionRecord &Function) override;
};
/// \brief Matches numbers that pass a certain threshold.
@@ -84,7 +84,7 @@ public:
RegionCoverageFilter(Operation Op, double Threshold)
: StatisticThresholdFilter(Op, Threshold) {}
- bool matches(const FunctionCoverageMapping &Function) override;
+ bool matches(const coverage::FunctionRecord &Function) override;
};
/// \brief Matches functions whose line coverage percentage
@@ -95,7 +95,7 @@ public:
LineCoverageFilter(Operation Op, double Threshold)
: StatisticThresholdFilter(Op, Threshold) {}
- bool matches(const FunctionCoverageMapping &Function) override;
+ bool matches(const coverage::FunctionRecord &Function) override;
};
/// \brief A collection of filters.
@@ -111,7 +111,7 @@ public:
bool empty() const { return Filters.empty(); }
- bool matches(const FunctionCoverageMapping &Function) override;
+ bool matches(const coverage::FunctionRecord &Function) override;
};
/// \brief A collection of filters.
@@ -119,7 +119,7 @@ public:
/// in an instance of this class.
class CoverageFiltersMatchAll : public CoverageFilters {
public:
- bool matches(const FunctionCoverageMapping &Function) override;
+ bool matches(const coverage::FunctionRecord &Function) override;
};
} // namespace llvm
diff --git a/llvm/tools/llvm-cov/CoverageSummary.cpp b/llvm/tools/llvm-cov/CoverageSummary.cpp
index c65c5bee00f..8df3bebbacf 100644
--- a/llvm/tools/llvm-cov/CoverageSummary.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummary.cpp
@@ -27,8 +27,8 @@ unsigned CoverageSummary::getFileID(StringRef Filename) {
return Filenames.size() - 1;
}
-void CoverageSummary::createSummaries(
- ArrayRef<coverage::FunctionCoverageMapping> Functions) {
+void
+CoverageSummary::createSummaries(ArrayRef<coverage::FunctionRecord> Functions) {
std::vector<std::pair<unsigned, size_t>> FunctionFileIDs;
FunctionFileIDs.resize(Functions.size());
diff --git a/llvm/tools/llvm-cov/CoverageSummary.h b/llvm/tools/llvm-cov/CoverageSummary.h
index 5d6a55559cd..b93103c8cf2 100644
--- a/llvm/tools/llvm-cov/CoverageSummary.h
+++ b/llvm/tools/llvm-cov/CoverageSummary.h
@@ -30,7 +30,7 @@ class CoverageSummary {
unsigned getFileID(StringRef Filename);
public:
- void createSummaries(ArrayRef<coverage::FunctionCoverageMapping> Functions);
+ void createSummaries(ArrayRef<coverage::FunctionRecord> Functions);
ArrayRef<FileCoverageSummary> getFileSummaries() { return FileSummaries; }
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
index 53173577d7f..334bc73e0d9 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp
@@ -18,7 +18,7 @@ using namespace llvm;
using namespace coverage;
FunctionCoverageSummary
-FunctionCoverageSummary::get(const FunctionCoverageMapping &Function) {
+FunctionCoverageSummary::get(const coverage::FunctionRecord &Function) {
// Compute the region coverage
size_t NumCodeRegions = 0, CoveredRegions = 0;
for (auto &CR : Function.CountedRegions) {
diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
index 8a40867b3e1..18b270433cd 100644
--- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h
+++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h
@@ -101,7 +101,7 @@ struct FunctionCoverageSummary {
/// \brief Compute the code coverage summary for the given function coverage
/// mapping record.
static FunctionCoverageSummary
- get(const coverage::FunctionCoverageMapping &Function);
+ get(const coverage::FunctionRecord &Function);
};
/// \brief A summary of file's code coverage.
diff --git a/llvm/tools/llvm-cov/SourceCoverageDataManager.cpp b/llvm/tools/llvm-cov/SourceCoverageDataManager.cpp
deleted file mode 100644
index a60ea6e2586..00000000000
--- a/llvm/tools/llvm-cov/SourceCoverageDataManager.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-//===- SourceCoverageDataManager.cpp - Manager for source file coverage
-// data-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class separates and merges mapping regions for a specific source file.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SourceCoverageDataManager.h"
-
-using namespace llvm;
-using namespace coverage;
-
-void SourceCoverageDataManager::insert(const CountedRegion &CR) {
- Regions.push_back(CR);
- Segments.clear();
-}
-
-namespace {
-class SegmentBuilder {
- std::vector<CoverageSegment> Segments;
- SmallVector<const CountedRegion *, 8> ActiveRegions;
-
- /// Start a segment with no count specified.
- void startSegment(unsigned Line, unsigned Col, bool IsRegionEntry) {
- Segments.emplace_back(Line, Col, IsRegionEntry);
- }
-
- /// Start a segment with the given Region's count.
- void startSegment(unsigned Line, unsigned Col, bool IsRegionEntry,
- const CountedRegion &Region) {
- if (Segments.empty())
- Segments.emplace_back(Line, Col, IsRegionEntry);
- CoverageSegment S = Segments.back();
- // Avoid creating empty regions.
- if (S.Line != Line || S.Col != Col) {
- Segments.emplace_back(Line, Col, IsRegionEntry);
- S = Segments.back();
- }
- // Set this region's count.
- if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion)
- Segments.back().setCount(Region.ExecutionCount);
- }
-
- /// Start a segment for the given region.
- void startSegment(const CountedRegion &Region) {
- startSegment(Region.LineStart, Region.ColumnStart, true, Region);
- }
-
- /// Pop the top region off of the active stack, starting a new segment with
- /// the containing Region's count.
- void popRegion() {
- const CountedRegion *Active = ActiveRegions.back();
- unsigned Line = Active->LineEnd, Col = Active->ColumnEnd;
- ActiveRegions.pop_back();
- if (ActiveRegions.empty())
- startSegment(Line, Col, /*IsRegionEntry=*/false);
- else
- startSegment(Line, Col, /*IsRegionEntry=*/false, *ActiveRegions.back());
- }
-
-public:
- /// Build a list of CoverageSegments from a sorted list of Regions.
- std::vector<CoverageSegment>
- buildSegments(ArrayRef<CountedRegion> Regions) {
- for (const auto &Region : Regions) {
- // Pop any regions that end before this one starts.
- while (!ActiveRegions.empty() &&
- ActiveRegions.back()->endLoc() <= Region.startLoc())
- popRegion();
- // Add this region to the stack.
- ActiveRegions.push_back(&Region);
- startSegment(Region);
- }
- // Pop any regions that are left in the stack.
- while (!ActiveRegions.empty())
- popRegion();
- return Segments;
- }
-};
-}
-
-ArrayRef<CoverageSegment> SourceCoverageDataManager::getCoverageSegments() {
- if (Segments.empty()) {
- // Sort the regions given that they're all in the same file at this point.
- std::sort(Regions.begin(), Regions.end(),
- [](const CountedRegion &LHS, const CountedRegion &RHS) {
- if (LHS.startLoc() == RHS.startLoc())
- // When LHS completely contains RHS, we sort LHS first.
- return RHS.endLoc() < LHS.endLoc();
- return LHS.startLoc() < RHS.startLoc();
- });
-
- Segments = SegmentBuilder().buildSegments(Regions);
- }
-
- return Segments;
-}
diff --git a/llvm/tools/llvm-cov/SourceCoverageDataManager.h b/llvm/tools/llvm-cov/SourceCoverageDataManager.h
deleted file mode 100644
index eec175222b4..00000000000
--- a/llvm/tools/llvm-cov/SourceCoverageDataManager.h
+++ /dev/null
@@ -1,53 +0,0 @@
-//===- SourceCoverageDataManager.h - Manager for source file coverage data-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This class separates and merges mapping regions for a specific source file.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_COV_SOURCECOVERAGEDATAMANAGER_H
-#define LLVM_COV_SOURCECOVERAGEDATAMANAGER_H
-
-#include "llvm/ProfileData/CoverageMapping.h"
-#include <vector>
-
-namespace llvm {
-
-struct CoverageSegment {
- unsigned Line;
- unsigned Col;
- bool IsRegionEntry;
- uint64_t Count;
- bool HasCount;
-
- CoverageSegment(unsigned Line, unsigned Col, bool IsRegionEntry)
- : Line(Line), Col(Col), IsRegionEntry(IsRegionEntry),
- Count(0), HasCount(false) {}
- void setCount(uint64_t NewCount) {
- Count = NewCount;
- HasCount = true;
- }
-};
-
-/// \brief Partions mapping regions by their kind and sums
-/// the execution counts of the regions that start at the same location.
-class SourceCoverageDataManager {
- std::vector<coverage::CountedRegion> Regions;
- std::vector<CoverageSegment> Segments;
-
-public:
- void insert(const coverage::CountedRegion &CR);
-
- /// \brief Return a sequence of non-overlapping coverage segments.
- ArrayRef<CoverageSegment> getCoverageSegments();
-};
-
-} // namespace llvm
-
-#endif // LLVM_COV_SOURCECOVERAGEDATAMANAGER_H
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp
index 3be54f828da..015099c7d02 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp
@@ -18,11 +18,11 @@
using namespace llvm;
-void SourceCoverageView::renderLine(raw_ostream &OS, StringRef Line,
- int64_t LineNumber,
- const CoverageSegment *WrappedSegment,
- ArrayRef<const CoverageSegment *> Segments,
- unsigned ExpansionCol) {
+void SourceCoverageView::renderLine(
+ raw_ostream &OS, StringRef Line, int64_t LineNumber,
+ const coverage::CoverageSegment *WrappedSegment,
+ ArrayRef<const coverage::CoverageSegment *> Segments,
+ unsigned ExpansionCol) {
Optional<raw_ostream::Colors> Highlight;
SmallVector<std::pair<unsigned, unsigned>, 2> HighlightedRanges;
@@ -110,7 +110,7 @@ void SourceCoverageView::renderLineNumberColumn(raw_ostream &OS,
}
void SourceCoverageView::renderRegionMarkers(
- raw_ostream &OS, ArrayRef<const CoverageSegment *> Segments) {
+ raw_ostream &OS, ArrayRef<const coverage::CoverageSegment *> Segments) {
SmallString<32> Buffer;
raw_svector_ostream BufferOS(Buffer);
@@ -158,14 +158,12 @@ void SourceCoverageView::render(raw_ostream &OS, bool WholeFile,
auto EndISV = InstantiationSubViews.end();
// Get the coverage information for the file.
- auto CoverageSegments = RegionManager->getCoverageSegments();
- assert(CoverageSegments.size() && "View with no coverage?");
- auto NextSegment = CoverageSegments.begin();
- auto EndSegment = CoverageSegments.end();
+ auto NextSegment = CoverageInfo.begin();
+ auto EndSegment = CoverageInfo.end();
unsigned FirstLine = NextSegment != EndSegment ? NextSegment->Line : 0;
- const CoverageSegment *WrappedSegment = nullptr;
- SmallVector<const CoverageSegment *, 8> LineSegments;
+ const coverage::CoverageSegment *WrappedSegment = nullptr;
+ SmallVector<const coverage::CoverageSegment *, 8> LineSegments;
for (line_iterator LI(File, /*SkipBlanks=*/false); !LI.is_at_eof(); ++LI) {
// If we aren't rendering the whole file, we need to filter out the prologue
// and epilogue.
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h
index 54a11d8c51c..d92a7486d9d 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.h
+++ b/llvm/tools/llvm-cov/SourceCoverageView.h
@@ -15,7 +15,6 @@
#define LLVM_COV_SOURCECOVERAGEVIEW_H
#include "CoverageViewOptions.h"
-#include "SourceCoverageDataManager.h"
#include "llvm/ProfileData/CoverageMapping.h"
#include "llvm/Support/MemoryBuffer.h"
#include <vector>
@@ -105,14 +104,14 @@ private:
const MemoryBuffer &File;
const CoverageViewOptions &Options;
- std::unique_ptr<SourceCoverageDataManager> RegionManager;
+ coverage::CoverageData CoverageInfo;
std::vector<ExpansionView> ExpansionSubViews;
std::vector<InstantiationView> InstantiationSubViews;
/// \brief Render a source line with highlighting.
void renderLine(raw_ostream &OS, StringRef Line, int64_t LineNumber,
- const CoverageSegment *WrappedSegment,
- ArrayRef<const CoverageSegment *> Segments,
+ const coverage::CoverageSegment *WrappedSegment,
+ ArrayRef<const coverage::CoverageSegment *> Segments,
unsigned ExpansionCol);
void renderIndent(raw_ostream &OS, unsigned Level);
@@ -126,16 +125,18 @@ private:
void renderLineNumberColumn(raw_ostream &OS, unsigned LineNo);
/// \brief Render all the region's execution counts on a line.
- void renderRegionMarkers(raw_ostream &OS,
- ArrayRef<const CoverageSegment *> Segments);
+ void
+ renderRegionMarkers(raw_ostream &OS,
+ ArrayRef<const coverage::CoverageSegment *> Segments);
static const unsigned LineCoverageColumnWidth = 7;
static const unsigned LineNumberColumnWidth = 5;
public:
SourceCoverageView(const MemoryBuffer &File,
- const CoverageViewOptions &Options)
- : File(File), Options(Options) {}
+ const CoverageViewOptions &Options,
+ coverage::CoverageData &&CoverageInfo)
+ : File(File), Options(Options), CoverageInfo(std::move(CoverageInfo)) {}
const CoverageViewOptions &getOptions() const { return Options; }
@@ -154,12 +155,6 @@ public:
/// \brief Print the code coverage information for a specific
/// portion of a source file to the output stream.
void render(raw_ostream &OS, bool WholeFile, unsigned IndentLevel = 0);
-
- /// \brief Load the coverage information required for rendering
- /// from the mapping regions in the data manager.
- void load(std::unique_ptr<SourceCoverageDataManager> Data) {
- RegionManager = std::move(Data);
- }
};
} // namespace llvm
OpenPOWER on IntegriCloud