summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-cov
diff options
context:
space:
mode:
authorJustin Bogner <mail@justinbogner.com>2014-09-20 15:31:56 +0000
committerJustin Bogner <mail@justinbogner.com>2014-09-20 15:31:56 +0000
commit953e2407edb956eb846a79fc0dce08d032ea0d66 (patch)
tree617f3d06bf359ec67e4b312f2755e0453ce6cf9b /llvm/tools/llvm-cov
parentf584649ae397396016b1fbfc6fe8d8ea29e2ebf5 (diff)
downloadbcm5719-llvm-953e2407edb956eb846a79fc0dce08d032ea0d66.tar.gz
bcm5719-llvm-953e2407edb956eb846a79fc0dce08d032ea0d66.zip
llvm-cov: Disentangle the coverage data logic from the display (NFC)
This splits the logic for actually looking up coverage information from the logic that displays it. These were tangled rather thoroughly so this change is a bit large, but it mostly consists of moving things around. The coverage lookup logic itself now lives in the library, rather than being spread between the library and the tool. llvm-svn: 218184
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