Details
Diff Detail
Event Timeline
The motivation case for this patch is the following:
$ cat > sample.cpp << EOF #define DO_LOOP1() \ for (int K = 0; K < 2; ++K) {} #define DO_LOOP2() \ for (int K = 0; K < 2; ++K) {} #define JUST_EXPAND() DO_LOOP2() int main() { DO_LOOP1(); JUST_EXPAND(); return 0; } EOF $ clang++ -fprofile-instr-generate -fcoverage-mapping sample.cpp $ ./a.out $ llvm-profdata merge -o default.profdata default.profraw $ llvm-cov show a.out -instr-profile default.profdata | 1|#define DO_LOOP1() \ 3| 2| for (int K = 0; K < 2; ++K) {} | 3| | 4|#define DO_LOOP2() \ 3| 5| for (int K = 0; K < 2; ++K) {} | 6| 3| 7|#define JUST_EXPAND() DO_LOOP2() | 8| 1| 9|int main() { 3| 10| DO_LOOP1(); 1| 11| JUST_EXPAND(); 1| 12| return 0; 1| 13|}
As you may see, the counts for DO_LOOP macroses are 3, and these values are propagated to the outer code. As a result, counts for lines 7 and 10 are shown as 3 which looks quite weird.
After applying the patch, the output of llvm-cov looks more predictable:
$ llvm-cov show a.out -instr-profile default.profdata | 1|#define DO_LOOP1() \ 3| 2| for (int K = 0; K < 2; ++K) {} | 3| | 4|#define DO_LOOP2() \ 3| 5| for (int K = 0; K < 2; ++K) {} | 6| 1| 7|#define JUST_EXPAND() DO_LOOP2() | 8| 1| 9|int main() { 1| 10| DO_LOOP1(); 1| 11| JUST_EXPAND(); 1| 12| return 0; 1| 13|}
Another example which is also fixed by this patch:
$ cat > sample.cpp << EOF #define DO_LOOP() \ for (int k = 0; k < 2; ++k) {} #define DO_SOMETHING() \ { \ DO_LOOP(); \ } int main() { DO_SOMETHING(); DO_SOMETHING(); return 0; } EOF $ clang++ -fprofile-instr-generate -fcoverage-mapping sample.cpp $ ./a.out $ llvm-profdata merge -o default.profdata default.profraw $ llvm-cov show a.out -instr-profile default.profdata | 1|#define DO_LOOP() \ 6| 2| for (int k = 0; k < 2; ++k) {} | 3| | 4|#define DO_SOMETHING() \ 2| 5| { \ 3| 6| DO_LOOP(); \ 2| 7| } | 8| 1| 9|int main() { 1| 10| DO_SOMETHING(); 1| 11| DO_SOMETHING(); 1| 12| return 0; 1| 13|}
Pay attention to line 6. The patched llvm-cov generates the following output:
$ llvm-cov show a.out -instr-profile default.profdata | 1|#define DO_LOOP() \ 6| 2| for (int k = 0; k < 2; ++k) {} | 3| | 4|#define DO_SOMETHING() \ 2| 5| { \ 2| 6| DO_LOOP(); \ 2| 7| } | 8| 1| 9|int main() { 1| 10| DO_SOMETHING(); 1| 11| DO_SOMETHING(); 1| 12| return 0; 1| 13|}
Your little motivating examples are great -- please add them as test cases as well.
llvm/trunk/lib/ProfileData/CoverageMapping.cpp | ||
---|---|---|
327 ↗ | (On Diff #52813) | what is this change about? |
410 ↗ | (On Diff #52813) | Can you add a comment here with more explanation? |
llvm/trunk/unittests/ProfileData/CoverageMappingTest.cpp | ||
526 ↗ | (On Diff #52813) | Also add a test for "include". |
- Reworked to correspond the changes of D18610.
- Expanded the test.
- Added some comments.
I'll add test cases for llvm-cov with the next update.
The code looks correct, but after a second though, I wonder if the logic in
fixExpansionRegion
should really be done in Clang: tools/clang/lib/CodeGen/CoverageMappingGen.cpp
The counter expression for the expansion region should really be the counter of the enclosing region, instead of 'enclosing region counter + ....'.
- To fully fix the original issue, D19725 is required.
- Simplified the logic of combining regions.
- Improved comments.
- Reworked test cases to check only the issue with combining expansions.
Thanks, this is great!
unittests/ProfileData/CoverageMappingTest.cpp | ||
---|---|---|
453 | Could you use distinct counters here (e.g {2,3,5,7})? It would help show that the right regions are merged together. |
other than vsk's comments, lgtm.
lib/ProfileData/CoverageMapping.cpp | ||
---|---|---|
377 | Clarify that ExpansionRegions from expanding a macro nested in another macro will have the same source locations. For such a case, the expansion regions's counts need to be combined. |
Clarify that ExpansionRegions from expanding a macro nested in another macro will have the same source locations. For such a case, the expansion regions's counts need to be combined.