[cfe-dev] GCOV instrumentation for non-instantiated code (e.g. template functions)

Holtgrewe, Manuel manuel.holtgrewe at fu-berlin.de
Sun May 13 08:06:17 PDT 2012


Dear all,

(first of all: Sorry if there is any confusion because I am not using the right C++/compiler lingo, I'm more of a C++ "consumer" than a language lawyer/expert. I'm interested in any hints or corrections so I can learn, though).

I have done some work on the GCOV instrumentation that allows uninstantiated code (e.g. template functions, in-class defined member methods) to appear in GCOV output.

I have contacted Nick Lewicky (since he is the author of the GCOV cod ein Clang, so thanks to him!) and he gave my some guidance. Attached is my resulting patch to current trunk of Clang/LLVM. The code contains some debug output right now that needs to be removed before any possible future inclusion.

I would like to get some feedback on this:

- Do you think it is useful (I hope I can convince you below ;), i.e. would you consider it for inclusion into Clang/LLVM?
- Is my approach correct? Can it be improved upon?
- Are there other large issues to work on?
- Are there smaller issues to work on?

Also there are some questions:

- How can I check whether a member function was defined out-of-class? Currently, incorrect GCNO is generated here.
- Am I missing functions classes that no code is generated for, and: Is there a better way to look for them?
- Can you think of a good way to write tests for this or: How can I write tests for this using any existing Clang test system.
- Can you think of some systematic scheme of functions to generate "dead nodes" for?

Below is a quick description of my motivation and what the patch contains. The patch itself is attached, together with the output of compiling with -ftest-coverage -fprofile-arcs -o gcov_cases2, running the program and then calling gcov on them. The files ending on g++ are the output when compiling with g++, the files ending with clang++ are the output when compiling with patched clang++.

There are two example programs, one where the functions are called (gcov_cases.cpp) and one where no function is called (gcov_cases2.cpp).

Cheers!
Manuel

Motivation -- Why is this useful?
---------------------------------

Some C++ functions do not show up in GCOV output since no code is generated for them. Some examples are template functions but also in-class defined member methods. Consider the following small example program:

template <typename T>
void f()
{
  std::cout << T() << '\n';
}

class Klass
{
public:
  Klass()
  {
    f();
  }
};

int main() { return 0; }

Both the template function f and the constructor of Klass will not turn up in the GCNO file (which describe the program to GCOV in a graph structure). This means if you compile the program with coverage instrumentation, run it and then generate the gcov output, f and the constructor will not show up. They are treated like empty or comment lines.

This has the problem that the gcov output can no longer be considered a good measure for test coverage if you have a lot of template functions, e.g. when writing tests for a template library, say the STL or Boost.

My Approach
-----------

Currently, the GCOV support in is implemented in LLVM: LLVM looks at the generated generated debug meta data and generates the GCNO file with the graph structure. No debug meta data is generated for the uninstantiated code right now and (according to Nick) should not be added because of bloating up the output and DWARF does support debug symbols for uninstantiated code.

The first part of my patch is to generate meta data "gcov.extralines" that consists of one entry for each line that should be added to the GCOV output. This change is added to clang-trunk/lib/CodeGen/ModuleBuilder.cpp where I traverse the AST and look out for functions that no code is generated for. Currently, I look for function templates definitions that are not fully specialized and unused member function definitions or of uninstantiated C++ template classes. Unused virtual functions will have code emitted for them, as far as I understand.

This meta data is then interpreted in llvm-trunk/lib/Transforms/Instrumentation/GCOVProfiling.cpp and we emit fake functions in the GNO functions for them.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: clang.diff
Type: text/x-patch
Size: 9762 bytes
Desc: clang.diff
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120513/9f6f44d9/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcov_cases.cpp.gcov.clang++
Type: application/octet-stream
Size: 6265 bytes
Desc: gcov_cases.cpp.gcov.clang++
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120513/9f6f44d9/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcov_cases.cpp.gcov.g++
Type: application/octet-stream
Size: 6265 bytes
Desc: gcov_cases.cpp.gcov.g++
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120513/9f6f44d9/attachment-0001.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcov_cases2.cpp.gcov.clang++
Type: application/octet-stream
Size: 6312 bytes
Desc: gcov_cases2.cpp.gcov.clang++
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120513/9f6f44d9/attachment-0002.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcov_cases2.cpp.gcov.g++
Type: application/octet-stream
Size: 6312 bytes
Desc: gcov_cases2.cpp.gcov.g++
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120513/9f6f44d9/attachment-0003.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcov_cases2.cpp
Type: text/x-c++src
Size: 2818 bytes
Desc: gcov_cases2.cpp
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120513/9f6f44d9/attachment.cpp>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: gcov_cases.cpp
Type: text/x-c++src
Size: 2806 bytes
Desc: gcov_cases.cpp
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120513/9f6f44d9/attachment-0001.cpp>


More information about the cfe-dev mailing list