[llvm-cov] Add support for loading coverage from multiple objects

Differential Revision: https://reviews.llvm.org/D25086

llvm-svn: 285088
This commit is contained in:
Vedant Kumar 2016-10-25 17:40:55 +00:00
parent 04fbf573ce
commit a3661effd9
4 changed files with 46 additions and 21 deletions

View File

@ -167,14 +167,14 @@ SHOW COMMAND
SYNOPSIS
^^^^^^^^
:program:`llvm-cov show` [*options*] -instr-profile *PROFILE* *BIN* [*SOURCES*]
:program:`llvm-cov show` [*options*] -instr-profile *PROFILE* *BIN* [*-object BIN,...*] [[*-object BIN*]] [*SOURCES*]
DESCRIPTION
^^^^^^^^^^^
The :program:`llvm-cov show` command shows line by line coverage of a binary
*BIN* using the profile data *PROFILE*. It can optionally be filtered to only
show the coverage for the files listed in *SOURCES*.
The :program:`llvm-cov show` command shows line by line coverage of the
binaries *BIN*,... using the profile data *PROFILE*. It can optionally be
filtered to only show the coverage for the files listed in *SOURCES*.
To use :program:`llvm-cov show`, you need a program that is compiled with
instrumentation to emit profile and coverage data. To build such a program with
@ -183,7 +183,7 @@ flags. If linking with the ``clang`` driver, pass ``-fprofile-instr-generate``
to the link stage to make sure the necessary runtime libraries are linked in.
The coverage information is stored in the built executable or library itself,
and this is what you should pass to :program:`llvm-cov show` as the *BIN*
and this is what you should pass to :program:`llvm-cov show` as a *BIN*
argument. The profile data is generated by running this instrumented program
normally. When the program exits it will write out a raw profile file,
typically called ``default.profraw``, which can be converted to a format that
@ -292,14 +292,14 @@ REPORT COMMAND
SYNOPSIS
^^^^^^^^
:program:`llvm-cov report` [*options*] -instr-profile *PROFILE* *BIN* [*SOURCES*]
:program:`llvm-cov report` [*options*] -instr-profile *PROFILE* *BIN* [*-object BIN,...*] [[*-object BIN*]] [*SOURCES*]
DESCRIPTION
^^^^^^^^^^^
The :program:`llvm-cov report` command displays a summary of the coverage of a
binary *BIN* using the profile data *PROFILE*. It can optionally be filtered to
only show the coverage for the files listed in *SOURCES*.
The :program:`llvm-cov report` command displays a summary of the coverage of
the binaries *BIN*,... using the profile data *PROFILE*. It can optionally be
filtered to only show the coverage for the files listed in *SOURCES*.
If no source files are provided, a summary line is printed for each file in the
coverage data. If any files are provided, summaries are shown for each function
@ -332,13 +332,13 @@ EXPORT COMMAND
SYNOPSIS
^^^^^^^^
:program:`llvm-cov export` [*options*] -instr-profile *PROFILE* *BIN*
:program:`llvm-cov export` [*options*] -instr-profile *PROFILE* *BIN* [*-object BIN,...*] [[*-object BIN*]]
DESCRIPTION
^^^^^^^^^^^
The :program:`llvm-cov export` command exports regions, functions, expansions,
and summaries of the coverage of a binary *BIN* using the profile data
and summaries of the coverage of the binaries *BIN*,... using the profile data
*PROFILE* as JSON.
For information on compiling programs for coverage and generating profile data,

View File

@ -0,0 +1,11 @@
// RUN: llvm-profdata merge %S/Inputs/multiple-files.proftext %S/Inputs/highlightedRanges.profdata -o %t.profdata
// RUN: llvm-cov report -object %S/Inputs/multiple-files.covmapping -instr-profile %t.profdata | FileCheck %s -check-prefix=OBJ1
// RUN: llvm-cov report %S/Inputs/multiple-files.covmapping -object %S/Inputs/highlightedRanges.covmapping -instr-profile %t.profdata | FileCheck %s -check-prefixes=OBJ1,OBJ2
// OBJ2: showHighlightedRanges.cpp
// OBJ1: f2.c
// OBJ1: f4.c
// OBJ1: f3.c
// OBJ1: f1.c

View File

@ -12,4 +12,4 @@ int main(int argc, const char *argv[]) {}
// WRONG-ARCH: Failed to load coverage
// RUN: not llvm-cov report -instr-profile %t.profdata 2>&1 | FileCheck --check-prefix=MISSING-BINARY %s
// MISSING-BINARY: 1 positional argument: See:
// MISSING-BINARY: No filenames specified!

View File

@ -116,7 +116,7 @@ private:
int export_(int argc, const char **argv,
CommandLineParserType commandLineParser);
std::string ObjectFilename;
std::vector<StringRef> ObjectFilenames;
CoverageViewOptions ViewOpts;
CoverageFiltersMatchAll Filters;
@ -325,13 +325,15 @@ static bool modifiedTimeGT(StringRef LHS, StringRef RHS) {
}
std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
for (StringRef ObjectFilename : ObjectFilenames)
if (modifiedTimeGT(ObjectFilename, PGOFilename))
warning("profile data may be out of date - object is newer",
ObjectFilename);
auto CoverageOrErr =
CoverageMapping::load(ObjectFilename, PGOFilename, CoverageArch);
CoverageMapping::load(ObjectFilenames, PGOFilename, CoverageArch);
if (Error E = CoverageOrErr.takeError()) {
error("Failed to load coverage: " + toString(std::move(E)), ObjectFilename);
error("Failed to load coverage: " + toString(std::move(E)),
join(ObjectFilenames.begin(), ObjectFilenames.end(), ", "));
return nullptr;
}
auto Coverage = std::move(CoverageOrErr.get());
@ -484,9 +486,12 @@ void CodeCoverageTool::writeSourceFileView(StringRef SourceFile,
}
int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
cl::opt<std::string, true> ObjectFilename(
cl::Positional, cl::Required, cl::location(this->ObjectFilename),
cl::desc("Covered executable or object file."));
cl::opt<std::string> CovFilename(
cl::Positional, cl::desc("Covered executable or object file."));
cl::list<std::string> CovFilenames(
"object", cl::desc("Coverage executable or object file"), cl::ZeroOrMore,
cl::CommaSeparated);
cl::list<std::string> InputSourceFiles(
cl::Positional, cl::desc("<Source files>"), cl::ZeroOrMore);
@ -568,6 +573,15 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) {
ViewOpts.Debug = DebugDump;
CompareFilenamesOnly = FilenameEquivalence;
if (!CovFilename.empty())
ObjectFilenames.emplace_back(CovFilename);
for (const std::string &Filename : CovFilenames)
ObjectFilenames.emplace_back(Filename);
if (ObjectFilenames.empty()) {
error("No filenames specified!");
::exit(1);
}
ViewOpts.Format = Format;
switch (ViewOpts.Format) {
case CoverageViewOptions::OutputFormat::Text: