[llvm] 1c99f65 - [llvm-cov gcov] Fix calculating coverage of template functions

Igor Kudrin via llvm-commits llvm-commits at lists.llvm.org
Tue Mar 15 09:48:17 PDT 2022


Author: Igor Kudrin
Date: 2022-03-15T20:46:22+04:00
New Revision: 1c99f650a7ac90c80ffd4830e05cd3408e64f42c

URL: https://github.com/llvm/llvm-project/commit/1c99f650a7ac90c80ffd4830e05cd3408e64f42c
DIFF: https://github.com/llvm/llvm-project/commit/1c99f650a7ac90c80ffd4830e05cd3408e64f42c.diff

LOG: [llvm-cov gcov] Fix calculating coverage of template functions

Template functions share the same lines in source files, so the common
container of lines' properties cannot be used to calculate the coverage
statistics of individual functions.

> cat tmpl.cpp
template <int N> int test() { return N; }
int main() { return test<1>() + test<2>(); }
> clang++ --coverage tmpl.cpp -o tmpl
> ./tmpl
> llvm-cov gcov tmpl.cpp -f
...
Function '_Z4testILi1EEiv'
Lines executed:100.00% of 1

Function '_Z4testILi2EEiv'
Lines executed:-nan% of 0
...
> llvm-cov-patched gcov tmpl.cpp -f
...
Function '_Z4testILi1EEiv'
Lines executed:100.00% of 1

Function '_Z4testILi2EEiv'
Lines executed:100.00% of 1
...

Differential Revision: https://reviews.llvm.org/D121390

Added: 
    llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.cpp
    llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.gcda
    llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.gcno
    llvm/test/tools/llvm-cov/gcov/tmpl.test

Modified: 
    llvm/lib/ProfileData/GCOV.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp
index 22062e60af2ab..feacf40b8d0ae 100644
--- a/llvm/lib/ProfileData/GCOV.cpp
+++ b/llvm/lib/ProfileData/GCOV.cpp
@@ -13,6 +13,7 @@
 
 #include "llvm/ProfileData/GCOV.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallSet.h"
 #include "llvm/Config/llvm-config.h"
 #include "llvm/Demangle/Demangle.h"
 #include "llvm/Support/Debug.h"
@@ -662,6 +663,8 @@ void Context::collectFunction(GCOVFunction &f, Summary &summary) {
   if (f.startLine >= si.startLineToFunctions.size())
     si.startLineToFunctions.resize(f.startLine + 1);
   si.startLineToFunctions[f.startLine].push_back(&f);
+  SmallSet<uint32_t, 16> lines;
+  SmallSet<uint32_t, 16> linesExec;
   for (const GCOVBlock &b : f.blocksRange()) {
     if (b.lines.empty())
       continue;
@@ -670,9 +673,9 @@ void Context::collectFunction(GCOVFunction &f, Summary &summary) {
       si.lines.resize(maxLineNum + 1);
     for (uint32_t lineNum : b.lines) {
       LineInfo &line = si.lines[lineNum];
-      if (!line.exists)
+      if (lines.insert(lineNum).second)
         ++summary.lines;
-      if (line.count == 0 && b.count)
+      if (b.count && linesExec.insert(lineNum).second)
         ++summary.linesExec;
       line.exists = true;
       line.count += b.count;

diff  --git a/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.cpp b/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.cpp
new file mode 100644
index 0000000000000..287b541443a4b
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.cpp
@@ -0,0 +1,4 @@
+template <int N>
+int test() { return N; }
+
+int main() { return test<1>() + test<2>(); }

diff  --git a/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.gcda b/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.gcda
new file mode 100644
index 0000000000000..d235d3c3de239
Binary files /dev/null and b/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.gcda 
diff er

diff  --git a/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.gcno b/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.gcno
new file mode 100644
index 0000000000000..13fab3e7f77a8
Binary files /dev/null and b/llvm/test/tools/llvm-cov/gcov/Inputs/tmpl.gcno 
diff er

diff  --git a/llvm/test/tools/llvm-cov/gcov/tmpl.test b/llvm/test/tools/llvm-cov/gcov/tmpl.test
new file mode 100644
index 0000000000000..7494ef33f6430
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/gcov/tmpl.test
@@ -0,0 +1,19 @@
+# Check that the coverage statistics for template functions are calculated as expected.
+
+RUN: rm -rf %t
+RUN: mkdir %t
+RUN: cd %t
+RUN: cp %p/Inputs/tmpl* .
+
+RUN: llvm-cov gcov tmpl.cpp -f | FileCheck %s --check-prefix=F
+RUN: llvm-cov gcov tmpl.cpp -t | FileCheck %s --check-prefix=T
+
+F:      Function '_Z4testILi1EEiv'
+F-NEXT: Lines executed:100.00% of 1
+F:      Function '_Z4testILi2EEiv'
+F-NEXT: Lines executed:100.00% of 1
+
+T:      -: 1:template <int N>
+T-NEXT: 2: 2:int test() { return N; }
+T-NEXT: -: 3:
+T-NEXT: 1: 4:int main() { return test<1>() + test<2>(); }


        


More information about the llvm-commits mailing list