This is an archive of the discontinued LLVM Phabricator instance.

[llvm-cov][WIP] Add Per Directory coverage to llvm-cov
Needs ReviewPublic

Authored by ashpande on Jul 28 2022, 11:07 PM.

Details

Reviewers
phosek
gulfem
Summary

Per Directory Coverage: by default, llvm-cov reports are generated on a per file basis. While this works for small applications with few executable files, it can become cumbersome for very large projects, such as LLVM itself. The resulting HTML file can be large, and it can be hard to find any file. Moreover, directory structure is not preserved, so it can be difficult to know the coverage of one particular directory in a large report (unless you build it selectively beforehand).

The gcov code coverage frontend lcov defaults to a per directory structure. An example is here: LCOV LLVM Report. We would like to go one step further and default the report to output a report which preserves directory structure. For example, if a user builds LLVM with code coverage, the resulting report should replicate the llvm-monorepo. The user should be able to click on the directory and see the coverage for all the subdirectories, and so on until they can see the source files and their coverage info.

Implementation Details:
The function buildCoverageTree takes a vector of source files and builds the tree from it.
This is called by createIndexFile when llvm-cov is run.
CreateIndexFile calls itself recursively for every node in the tree that is not a leaf node.

Note: This is a very rough draft. I have to get the HTML generation working. Will clean this up and send more updates over the next couple of days.

Diff Detail

Event Timeline

ashpande created this revision.Jul 28 2022, 11:07 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 28 2022, 11:07 PM
ashpande requested review of this revision.Jul 28 2022, 11:07 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 28 2022, 11:07 PM

For future revisions, please use larger context as described in https://llvm.org/docs/Phabricator.html#requesting-a-review-via-the-web-interface

llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
71

This looks like an unrelated change.

357

For debugging output, we usually use the LLVM_DEBUG macro and the dbgs() stream, see https://llvm.org/docs/ProgrammersManual.html#the-llvm-debug-macro-and-debug-option

ashpande updated this revision to Diff 449891.Aug 4 2022, 12:39 AM

Updated with Debug log.
In the CoverageTreeNode struct, changed children from an array to an unordered set. This prevents the multiple child problem while building up the tree.
Tried to increase the context with -U999999, not sure if its correct now.

The patch is generating the HTML for folders but not the files. It's throwing an error saying "too many open files".

This might be because we are recursing over the tree and opening a new file each time. Node->Name is relative path, while Node->FCS.Name is the absolute path, FCS.Name is what llvm-cov is using. Chopping strings seems to be hacky, so have to figure out a way to be relative to repository root/ user specified DIR root. This should avoid the problem of too many files being open.

gulfem added a comment.Aug 5 2022, 8:06 AM

I have a few suggestions:

  1. In the commit message, please add the link to https://llvm.org/reports/coverage/index.html after "An example is here".
  2. I think you can introduce a flag into llvm-cov like -per-directory-coverage and enable this functionality when this flag is enabled.
llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp
343

I think one potential problem here is that we can have the same folder name, e.g. src in separate sub-projects like in https://lab.llvm.org/coverage/coverage-reports/index.html:

libcxx/src/memory.cpp
libcxxabi/src/cxa_vector.cpp

Maybe, you can use DirPath in Dirs instead of DirName to make sure that it works in such cases.

ashpande edited the summary of this revision. (Show Details)Aug 9 2022, 7:12 AM
ashpande updated this revision to Diff 452107.Aug 12 2022, 1:50 AM
ashpande marked an inline comment as done.

Block scoped the stream so that it is closed before calling the builder for children. This is more efficient than keeping the stream open

xgupta added a subscriber: xgupta.Aug 12 2022, 6:39 AM