[llvm] 8cf1ac9 - [llvm-cov gcov] Improve accuracy when some edges are not measured

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 12 22:34:33 PDT 2020


Author: Fangrui Song
Date: 2020-09-12T22:33:41-07:00
New Revision: 8cf1ac97cec654923b4f80ad11506bf06ec34f65

URL: https://github.com/llvm/llvm-project/commit/8cf1ac97cec654923b4f80ad11506bf06ec34f65
DIFF: https://github.com/llvm/llvm-project/commit/8cf1ac97cec654923b4f80ad11506bf06ec34f65.diff

LOG: [llvm-cov gcov] Improve accuracy when some edges are not measured

Also guard against infinite recursion if GCOV_ARC_ON_TREE edges contain a cycle.

Added: 
    

Modified: 
    compiler-rt/test/profile/gcov-basic.c
    llvm/include/llvm/ProfileData/GCOV.h
    llvm/lib/ProfileData/GCOV.cpp
    llvm/test/tools/llvm-cov/gcov-8.c

Removed: 
    


################################################################################
diff  --git a/compiler-rt/test/profile/gcov-basic.c b/compiler-rt/test/profile/gcov-basic.c
index e00cebf4b781..0d8be6d7de08 100644
--- a/compiler-rt/test/profile/gcov-basic.c
+++ b/compiler-rt/test/profile/gcov-basic.c
@@ -27,6 +27,8 @@
 
 // CHECK: Runs:2
 
+#include <stdio.h>
+
 int main(int argc, char *argv[]) { // CHECK:      2: [[@LINE]]:int main
   if (argc > 1)                    // CHECK-NEXT: 2: [[@LINE]]:
     puts("hello");                 // CHECK-NEXT: 1: [[@LINE]]:

diff  --git a/llvm/include/llvm/ProfileData/GCOV.h b/llvm/include/llvm/ProfileData/GCOV.h
index f87eab6d3ead..3c6312f91674 100644
--- a/llvm/include/llvm/ProfileData/GCOV.h
+++ b/llvm/include/llvm/ProfileData/GCOV.h
@@ -15,6 +15,7 @@
 #define LLVM_PROFILEDATA_GCOV_H
 
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringMap.h"
@@ -261,6 +262,7 @@ class GCOVFunction {
   unsigned srcIdx;
   SmallVector<std::unique_ptr<GCOVBlock>, 0> Blocks;
   SmallVector<std::unique_ptr<GCOVArc>, 0> arcs, treeArcs;
+  DenseSet<const GCOVBlock *> visited;
 };
 
 /// GCOVBlock - Collects block information.

diff  --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp
index f8c576d305f0..d4a4a8979e81 100644
--- a/llvm/lib/ProfileData/GCOV.cpp
+++ b/llvm/lib/ProfileData/GCOV.cpp
@@ -231,7 +231,11 @@ bool GCOVFile::readGCDA(GCOVBuffer &buf) {
         sink.addDstEdge(arc.get());
         src.addSrcEdge(arc.get());
         fn->treeArcs.push_back(std::move(arc));
-        fn->propagateCounts(src, nullptr);
+
+        for (GCOVBlock &block : make_pointee_range(fn->Blocks))
+          fn->propagateCounts(block, nullptr);
+        for (size_t i = fn->treeArcs.size() - 1; i; --i)
+          fn->treeArcs[i - 1]->src.Counter += fn->treeArcs[i - 1]->Count;
       }
     }
     pos += 4 * length;
@@ -289,6 +293,11 @@ GCOVBlock &GCOVFunction::getExitBlock() const {
 // spanning tree, the count for each unmeasured arc (GCOV_ARC_ON_TREE) can be
 // uniquely identified.
 uint64_t GCOVFunction::propagateCounts(const GCOVBlock &v, GCOVArc *pred) {
+  // If GCOV_ARC_ON_TREE edges do form a tree, visited is not needed; otherwise
+  // this prevents infinite recursion.
+  if (!visited.insert(&v).second)
+    return 0;
+
   uint64_t excess = 0;
   for (GCOVArc *e : v.srcs())
     if (e != pred)

diff  --git a/llvm/test/tools/llvm-cov/gcov-8.c b/llvm/test/tools/llvm-cov/gcov-8.c
index 996e4cbe71b3..d557d8413018 100644
--- a/llvm/test/tools/llvm-cov/gcov-8.c
+++ b/llvm/test/tools/llvm-cov/gcov-8.c
@@ -20,7 +20,7 @@ int main() {                                      // GCOV:       1: [[@LINE]]:in
 // RUN: llvm-cov gcov gcov-8.c | FileCheck %s --check-prefixes=OUT,OUTFILE
 // OUT:          File 'gcov-8.c'
 // OUT-NEXT:     Lines executed:100.00% of 9
-// OUT-B-NEXT:   Branches executed:85.71% of 14
+// OUT-B-NEXT:   Branches executed:100.00% of 14
 // OUT-B-NEXT:   Taken at least once:71.43% of 14
 // OUT-B-NEXT:   No calls
 // OUTFILE-NEXT: Creating 'gcov-8.c.gcov'
@@ -66,6 +66,6 @@ int main() {                                      // GCOV:       1: [[@LINE]]:in
 // I-B-NEXT:branch:11,taken
 // I-B-NEXT:branch:11,nottaken
 //   I-NEXT:lcount:12,4
-// I-B-NEXT:branch:12,notexec
-// I-B-NEXT:branch:12,notexec
+// I-B-NEXT:branch:12,taken
+// I-B-NEXT:branch:12,nottaken
 //   I-NEXT:lcount:14,1


        


More information about the llvm-commits mailing list