This is an archive of the discontinued LLVM Phabricator instance.

[Coverage] Suppress creating a code region if the same area is covered by an expansion region.
ClosedPublic

Authored by ikudrin on Aug 29 2016, 3:32 AM.

Details

Summary

In many cases, these code regions are just redundant, but sometimes they could be assigned to the counter of the parent code region instead of the counter of the nested block.

Diff Detail

Repository
rL LLVM

Event Timeline

ikudrin updated this revision to Diff 69549.Aug 29 2016, 3:32 AM
ikudrin retitled this revision from to [Coverage] Suppress creating a code region if the same area is covered by an expansion region..
ikudrin updated this object.
ikudrin added reviewers: davidxl, bogner, vsk.
ikudrin added a subscriber: cfe-commits.

This patch fixes the following issue:

$ cat > test.cpp << EOF
void dummy() {}

#define MACRO_1 dummy()

#define MACRO_2 MACRO_1

int main() {
  int i = 0;
  if (i > 5)
    MACRO_2;
}
EOF
$ clang++ -fprofile-instr-generate -fcoverage-mapping dummy.cpp test.cpp
$ ./a.out
$ llvm-profdata merge -o default.profdata default.profraw
$ llvm-cov show a.out -instr-profile --show-expansions default.profdata
    1|      0|void dummy() {}
    2|       |
    3|      0|#define MACRO_1 dummy()
    4|       |
    5|      1|#define MACRO_2 MACRO_1
    6|       |
    7|      1|int main() {
    8|      1|  int i = 0;
    9|      1|  if (i > 5)
   10|      1|    MACRO_2;
  ------------------
  |  |    5|      1|#define MACRO_2 MACRO_1
  |  |  ------------------
  |  |  |  |    3|      0|#define MACRO_1 dummy()
  |  |  ------------------
  ------------------
   11|      1|}

The result of the fixed version:

  1|      0|void dummy() {}
  2|       |
  3|      0|#define MACRO_1 dummy()
  4|       |
  5|      0|#define MACRO_2 MACRO_1
  6|       |
  7|      1|int main() {
  8|      1|  int i = 0;
  9|      1|  if (i > 5)
 10|      0|    MACRO_2;
------------------
|  |    5|      0|#define MACRO_2 MACRO_1
|  |  ------------------
|  |  |  |    3|      0|#define MACRO_1 dummy()
|  |  ------------------
------------------
 11|      1|}
vsk edited edge metadata.Aug 29 2016, 11:13 AM

Thanks for looking into this! I like the SourceRegionFilter setup.

lib/CodeGen/CoverageMappingGen.cpp
261 ↗(On Diff #69549)

Nit, is the default value needed?

634 ↗(On Diff #69549)

Out of curiosity, is this stable_sort step required for correctness? Or would our CHECK lines break without this?

In either case, would it be feasible to merge this step with the stable_sort in CoverageMappingWriter::write()?

ikudrin updated this revision to Diff 69709.Aug 30 2016, 9:12 AM
ikudrin edited edge metadata.
  • Removed a default value in emitSourceRegions(), added the corresponding argument to its call in EmptyCoverageMappingBuilder::write().
  • Removed an additional sorting step in CounterCoverageMappingBuilder::write(), the patch is now depends on the extended sorting creteria in CoverageMappingWriter::write(), see D24034.
ikudrin added inline comments.Aug 30 2016, 9:19 AM
lib/CodeGen/CoverageMappingGen.cpp
261 ↗(On Diff #69709)

Well, passing a distinct empty value from EmptyCoverageMappingBuilder::write() is a bit clearer.

633 ↗(On Diff #69709)

I believe, it's mostly to make our tests happy, but I don't want to make more changes in the program's behaviour than needed.

vsk accepted this revision.Aug 30 2016, 9:49 AM
vsk edited edge metadata.

Lgtm!

This revision is now accepted and ready to land.Aug 30 2016, 9:49 AM
This revision was automatically updated to reflect the committed changes.