summaryrefslogtreecommitdiff
path: root/docs/SourceBasedCodeCoverage.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/SourceBasedCodeCoverage.rst')
-rw-r--r--docs/SourceBasedCodeCoverage.rst110
1 files changed, 80 insertions, 30 deletions
diff --git a/docs/SourceBasedCodeCoverage.rst b/docs/SourceBasedCodeCoverage.rst
index 8d0a51fd3315f..abb682355b1c3 100644
--- a/docs/SourceBasedCodeCoverage.rst
+++ b/docs/SourceBasedCodeCoverage.rst
@@ -61,7 +61,7 @@ To compile code with coverage enabled, pass ``-fprofile-instr-generate
% clang++ -fprofile-instr-generate -fcoverage-mapping foo.cc -o foo
Note that linking together code with and without coverage instrumentation is
-supported: any uninstrumented code simply won't be accounted for.
+supported. Uninstrumented code simply won't be accounted for in reports.
Running the instrumented program
================================
@@ -95,28 +95,22 @@ Creating coverage reports
=========================
Raw profiles have to be **indexed** before they can be used to generate
-coverage reports. This is done using the "merge" tool in ``llvm-profdata``, so
-named because it can combine and index profiles at the same time:
+coverage reports. This is done using the "merge" tool in ``llvm-profdata``
+(which can combine multiple raw profiles and index them at the same time):
.. code-block:: console
# Step 3(a): Index the raw profile.
% llvm-profdata merge -sparse foo.profraw -o foo.profdata
-There are multiple different ways to render coverage reports. One option is to
-generate a line-oriented report:
+There are multiple different ways to render coverage reports. The simplest
+option is to generate a line-oriented report:
.. code-block:: console
# Step 3(b): Create a line-oriented coverage report.
% llvm-cov show ./foo -instr-profile=foo.profdata
-To demangle any C++ identifiers in the output, use:
-
-.. code-block:: console
-
- % llvm-cov show ./foo -instr-profile=foo.profdata | c++filt -n
-
This report includes a summary view as well as dedicated sub-views for
templated functions and their instantiations. For our example program, we get
distinct views for ``foo<int>(...)`` and ``foo<float>(...)``. If
@@ -125,38 +119,43 @@ region counts (even in macro expansions):
.. code-block:: none
- 20| 1|#define BAR(x) ((x) || (x))
+ 1| 20|#define BAR(x) ((x) || (x))
^20 ^2
2| 2|template <typename T> void foo(T x) {
- 22| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
+ 3| 22| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
^22 ^20 ^20^20
- 2| 4|}
+ 4| 2|}
------------------
| void foo<int>(int):
- | 1| 2|template <typename T> void foo(T x) {
- | 11| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
+ | 2| 1|template <typename T> void foo(T x) {
+ | 3| 11| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
| ^11 ^10 ^10^10
- | 1| 4|}
+ | 4| 1|}
------------------
| void foo<float>(int):
- | 1| 2|template <typename T> void foo(T x) {
- | 11| 3| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
+ | 2| 1|template <typename T> void foo(T x) {
+ | 3| 11| for (unsigned I = 0; I < 10; ++I) { BAR(I); }
| ^11 ^10 ^10^10
- | 1| 4|}
+ | 4| 1|}
------------------
-It's possible to generate a file-level summary of coverage statistics (instead
-of a line-oriented report) with:
+To generate a file-level summary of coverage statistics instead of a
+line-oriented report, try:
.. code-block:: console
# Step 3(c): Create a coverage summary.
% llvm-cov report ./foo -instr-profile=foo.profdata
- Filename Regions Miss Cover Functions Executed
- -----------------------------------------------------------------------
- /tmp/foo.cc 13 0 100.00% 3 100.00%
- -----------------------------------------------------------------------
- TOTAL 13 0 100.00% 3 100.00%
+ Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover
+ --------------------------------------------------------------------------------------------------------------------------------------
+ /tmp/foo.cc 13 0 100.00% 3 0 100.00% 13 0 100.00%
+ --------------------------------------------------------------------------------------------------------------------------------------
+ TOTAL 13 0 100.00% 3 0 100.00% 13 0 100.00%
+
+The ``llvm-cov`` tool supports specifying a custom demangler, writing out
+reports in a directory structure, and generating html reports. For the full
+list of options, please refer to the `command guide
+<http://llvm.org/docs/CommandGuide/llvm-cov.html>`_.
A few final notes:
@@ -177,6 +176,40 @@ A few final notes:
% llvm-profdata merge -sparse foo1.profraw foo2.profdata -o foo3.profdata
+Exporting coverage data
+=======================
+
+Coverage data can be exported into JSON using the ``llvm-cov export``
+sub-command. There is a comprehensive reference which defines the structure of
+the exported data at a high level in the llvm-cov source code.
+
+Interpreting reports
+====================
+
+There are four statistics tracked in a coverage summary:
+
+* Function coverage is the percentage of functions which have been executed at
+ least once. A function is considered to be executed if any of its
+ instantiations are executed.
+
+* Instantiation coverage is the percentage of function instantiations which
+ have been executed at least once. Template functions and static inline
+ functions from headers are two kinds of functions which may have multiple
+ instantiations.
+
+* Line coverage is the percentage of code lines which have been executed at
+ least once. Only executable lines within function bodies are considered to be
+ code lines.
+
+* Region coverage is the percentage of code regions which have been executed at
+ least once. A code region may span multiple lines (e.g in a large function
+ body with no control flow). However, it's also possible for a single line to
+ contain multiple code regions (e.g in "return x || y && z").
+
+Of these four statistics, function coverage is usually the least granular while
+region coverage is the most granular. The project-wide totals for each
+statistic are listed in the summary.
+
Format compatibility guarantees
===============================
@@ -189,9 +222,14 @@ Format compatibility guarantees
These formats are not forwards-compatible: i.e, a tool which uses format
version X will not be able to understand format version (X+k).
-* There is a third format in play: the format of the coverage mappings emitted
- into instrumented binaries. Tools must retain **backwards** compatibility
- with these formats. These formats are not forwards-compatible.
+* Tools must also retain **backwards** compatibility with the format of the
+ coverage mappings emitted into instrumented binaries. These formats are not
+ forwards-compatible.
+
+* The JSON coverage export format has a (major, minor, patch) version triple.
+ Only a major version increment indicates a backwards-incompatible change. A
+ minor version increment is for added functionality, and patch version
+ increments are for bugfixes.
Using the profiling runtime without static initializers
=======================================================
@@ -218,6 +256,18 @@ without using static initializers, do this manually:
otherwise. Calling this function multiple times appends profile data to an
existing on-disk raw profile.
+Collecting coverage reports for the llvm project
+================================================
+
+To prepare a coverage report for llvm (and any of its sub-projects), add
+``-DLLVM_BUILD_INSTRUMENTED_COVERAGE=On`` to the cmake configuration. Raw
+profiles will be written to ``$BUILD_DIR/profiles/``. To prepare an html
+report, run ``llvm/utils/prepare-code-coverage-artifact.py``.
+
+To specify an alternate directory for raw profiles, use
+``-DLLVM_PROFILE_DATA_DIR``. To change the size of the profile merge pool, use
+``-DLLVM_PROFILE_MERGE_POOL_SIZE``.
+
Drawbacks and limitations
=========================