[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