Skip to content

Commit

Permalink
[llvm-cov] Add support for loading coverage from multiple objects
Browse files Browse the repository at this point in the history
Differential Revision: https://reviews.llvm.org/D25086

llvm-svn: 285088
  • Loading branch information
vedantk committed Oct 25, 2016
1 parent 04fbf57 commit a3661ef
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 21 deletions.
22 changes: 11 additions & 11 deletions llvm/docs/CommandGuide/llvm-cov.rst
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
11 changes: 11 additions & 0 deletions llvm/test/tools/llvm-cov/load-multiple-objects.test
@@ -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
2 changes: 1 addition & 1 deletion llvm/test/tools/llvm-cov/universal-binary.c
Expand Up @@ -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!
32 changes: 23 additions & 9 deletions llvm/tools/llvm-cov/CodeCoverage.cpp
Expand Up @@ -116,7 +116,7 @@ class CodeCoverageTool {
int export_(int argc, const char **argv,
CommandLineParserType commandLineParser);

std::string ObjectFilename;
std::vector<StringRef> ObjectFilenames;
CoverageViewOptions ViewOpts;
CoverageFiltersMatchAll Filters;

Expand Down Expand Up @@ -325,13 +325,15 @@ static bool modifiedTimeGT(StringRef LHS, StringRef RHS) {
}

std::unique_ptr<CoverageMapping> CodeCoverageTool::load() {
if (modifiedTimeGT(ObjectFilename, PGOFilename))
warning("profile data may be out of date - object is newer",
ObjectFilename);
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());
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit a3661ef

Please sign in to comment.