[compiler-rt] 013f067 - [gcov] Emit GCOV_TAG_OBJECT_SUMMARY/GCOV_TAG_PROGRAM_SUMMARY correctly and fix llvm-cov's decoding of runcount

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon May 11 21:54:18 PDT 2020


Author: Fangrui Song
Date: 2020-05-11T21:53:53-07:00
New Revision: 013f06703e132c31cf3e8bdb2ae7c6b89b8f8fc2

URL: https://github.com/llvm/llvm-project/commit/013f06703e132c31cf3e8bdb2ae7c6b89b8f8fc2
DIFF: https://github.com/llvm/llvm-project/commit/013f06703e132c31cf3e8bdb2ae7c6b89b8f8fc2.diff

LOG: [gcov] Emit GCOV_TAG_OBJECT_SUMMARY/GCOV_TAG_PROGRAM_SUMMARY correctly and fix llvm-cov's decoding of runcount

gcov 9 (r264462) started to use GCOV_TAG_OBJECT_SUMMARY. Before,
GCOV_TAG_PROGRAM_SUMMARY was used.
libclang_rt.profile should emit just one tag according to the version.

Another bug introduced by rL194499 is that the wrong runcount field was
selected.

Fix the two bugs so that gcov can correctly decode "Runs:" from
libclang_rt.profile produced .gcda files, and llvm-cov gcov can
correctly decode "Runs:" from libgcov produced .gcda files.

Added: 
    

Modified: 
    compiler-rt/lib/profile/GCDAProfiling.c
    llvm/lib/ProfileData/GCOV.cpp
    llvm/test/tools/llvm-cov/Inputs/test_-a.cpp.gcov
    llvm/test/tools/llvm-cov/Inputs/test_-a.h.gcov
    llvm/test/tools/llvm-cov/Inputs/test_-a_-b.cpp.gcov
    llvm/test/tools/llvm-cov/Inputs/test_-a_-b.h.gcov
    llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.cpp.gcov
    llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.h.gcov
    llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.cpp.gcov
    llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.h.gcov
    llvm/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov
    llvm/test/tools/llvm-cov/Inputs/test_missing.h.gcov
    llvm/test/tools/llvm-cov/Inputs/test_no_options.cpp.gcov
    llvm/test/tools/llvm-cov/Inputs/test_no_options.h.gcov
    llvm/test/tools/llvm-cov/Inputs/test_objdir.cpp.gcov
    llvm/test/tools/llvm-cov/Inputs/test_objdir.h.gcov
    llvm/test/tools/llvm-cov/Inputs/test_paths.cpp.gcov
    llvm/test/tools/llvm-cov/Inputs/test_paths.h.gcov
    llvm/test/tools/llvm-cov/gcov-4.7.c
    llvm/test/tools/llvm-cov/gcov-8.c
    llvm/test/tools/llvm-cov/gcov-9.c

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c
index 6833609fbed8..fe39ce993996 100644
--- a/compiler-rt/lib/profile/GCDAProfiling.c
+++ b/compiler-rt/lib/profile/GCDAProfiling.c
@@ -66,6 +66,14 @@ typedef unsigned long long uint64_t;
 
 /* #define DEBUG_GCDAPROFILING */
 
+enum {
+  GCOV_TAG_FUNCTION = 0x01000000,
+  GCOV_TAG_COUNTER_ARCS = 0x01a10000,
+  // GCOV_TAG_OBJECT_SUMMARY superseded GCOV_TAG_PROGRAM_SUMMARY in GCC 9.
+  GCOV_TAG_OBJECT_SUMMARY = 0xa1000000,
+  GCOV_TAG_PROGRAM_SUMMARY = 0xa3000000,
+};
+
 /*
  * --- GCOV file format I/O primitives ---
  */
@@ -538,8 +546,6 @@ void llvm_gcda_emit_arcs(uint32_t num_counters, uint64_t *counters) {
 
 COMPILER_RT_VISIBILITY
 void llvm_gcda_summary_info() {
-  const uint32_t obj_summary_len = 9; /* Length for gcov compatibility. */
-  uint32_t i;
   uint32_t runs = 1;
   static uint32_t run_counted = 0; // We only want to increase the run count once.
   uint32_t val = 0;
@@ -551,42 +557,43 @@ void llvm_gcda_summary_info() {
 
   if (val != (uint32_t)-1) {
     /* There are counters present in the file. Merge them. */
-    if (val != 0xa1000000) {
-      fprintf(stderr, "profiling: %s: cannot merge previous run count: "
-                      "corrupt object tag (0x%08x)\n",
+    if (val != (gcov_version >= 90 ? GCOV_TAG_OBJECT_SUMMARY
+                                   : GCOV_TAG_PROGRAM_SUMMARY)) {
+      fprintf(stderr,
+              "profiling: %s: cannot merge previous run count: "
+              "corrupt object tag (0x%08x)\n",
               filename, val);
       return;
     }
 
     val = read_32bit_value(); /* length */
-    if (val != obj_summary_len) {
-      fprintf(stderr, "profiling: %s: cannot merge previous run count: "
-                      "mismatched object length (%d)\n",
-              filename, val);
-      return;
-    }
-
-    read_32bit_value(); /* checksum, unused */
-    read_32bit_value(); /* num, unused */
+    read_32bit_value();
+    if (gcov_version < 90)
+      read_32bit_value();
     uint32_t prev_runs = read_32bit_value();
+    for (uint32_t i = gcov_version < 90 ? 3 : 2; i < val; ++i)
+      read_32bit_value();
     /* Add previous run count to new counter, if not already counted before. */
     runs = run_counted ? prev_runs : prev_runs + 1;
   }
 
   cur_pos = save_cur_pos;
 
-  /* Object summary tag */
-  write_bytes("\0\0\0\xa1", 4);
-  write_32bit_value(obj_summary_len);
-  write_32bit_value(0); /* checksum, unused */
-  write_32bit_value(0); /* num, unused */
-  write_32bit_value(runs);
-  for (i = 3; i < obj_summary_len; ++i)
+  if (gcov_version >= 90) {
+    write_32bit_value(GCOV_TAG_OBJECT_SUMMARY);
+    write_32bit_value(2);
+    write_32bit_value(runs);
+    write_32bit_value(0); // sum_max
+  } else {
+    // Before gcov 4.8 (r190952), GCOV_TAG_SUMMARY_LENGTH was 9. r190952 set
+    // GCOV_TAG_SUMMARY_LENGTH to 22. We simply use the smallest length which
+    // can make gcov read "Runs:".
+    write_32bit_value(GCOV_TAG_PROGRAM_SUMMARY);
+    write_32bit_value(3);
     write_32bit_value(0);
-
-  /* Program summary tag */
-  write_bytes("\0\0\0\xa3", 4); /* tag indicates 1 program */
-  write_32bit_value(0); /* 0 length */
+    write_32bit_value(0);
+    write_32bit_value(runs);
+  }
 
   run_counted = 1;
 

diff  --git a/llvm/lib/ProfileData/GCOV.cpp b/llvm/lib/ProfileData/GCOV.cpp
index e8e0629f726f..242ab17e56c5 100644
--- a/llvm/lib/ProfileData/GCOV.cpp
+++ b/llvm/lib/ProfileData/GCOV.cpp
@@ -97,10 +97,12 @@ bool GCOVFile::readGCDA(GCOVBuffer &buf) {
       return false;
     uint32_t cursor = buf.getCursor();
     if (tag == GCOV_TAG_OBJECT_SUMMARY) {
+      buf.readInt(RunCount);
+      buf.readInt(dummy);
+    } else if (tag == GCOV_TAG_PROGRAM_SUMMARY) {
       buf.readInt(dummy);
       buf.readInt(dummy);
       buf.readInt(RunCount);
-    } else if (tag == GCOV_TAG_PROGRAM_SUMMARY) {
       ++ProgramCount;
     } else if (tag == GCOV_TAG_FUNCTION) {
       if (length == 0) // Placeholder

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_-a.cpp.gcov b/llvm/test/tools/llvm-cov/Inputs/test_-a.cpp.gcov
index 78ebbfc1a912..589194c1717b 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_-a.cpp.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_-a.cpp.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:test.cpp
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         -:    1:#include "test.h"
         -:    2:#include <cstdlib>

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_-a.h.gcov b/llvm/test/tools/llvm-cov/Inputs/test_-a.h.gcov
index 84fcb529d457..755d96cc5695 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_-a.h.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_-a.h.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:./test.h
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         4:    1:struct A {
         2:    1-block  0

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b.cpp.gcov b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b.cpp.gcov
index b1e658e6d2bf..7b3447345115 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b.cpp.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b.cpp.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:test.cpp
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         -:    1:#include "test.h"
         -:    2:#include <cstdlib>

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b.h.gcov b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b.h.gcov
index d85b56239d1b..010a69902b73 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b.h.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b.h.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:./test.h
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
 function _ZN1AC1Ev called 2 returned 100% blocks executed 100%
 function _ZN1AC2Ev called 2 returned 100% blocks executed 100%

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.cpp.gcov b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.cpp.gcov
index 603d14e483ba..27bc06c79eb6 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.cpp.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.cpp.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:test.cpp
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         -:    1:#include "test.h"
         -:    2:#include <cstdlib>

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.h.gcov b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.h.gcov
index e980e2101b23..a5ea6371fa03 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.h.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-c_-u.h.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:./test.h
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
 function _ZN1AC1Ev called 2 returned 100% blocks executed 100%
 function _ZN1AC2Ev called 2 returned 100% blocks executed 100%

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.cpp.gcov b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.cpp.gcov
index f9f5f307a469..e6d5aceef107 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.cpp.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.cpp.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:test.cpp
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         -:    1:#include "test.h"
         -:    2:#include <cstdlib>

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.h.gcov b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.h.gcov
index 923ac8ab64b8..6ddfe0346bb0 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.h.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_-a_-b_-u.h.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:./test.h
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
 function _ZN1AC1Ev called 2 returned 100% blocks executed 100%
 function _ZN1AC2Ev called 2 returned 100% blocks executed 100%

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov b/llvm/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov
index 9b3da2735a51..1a5aab1c36d0 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_missing.cpp.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:srcdir/./nested_dir/../test.cpp
         -:    0:Graph:test_paths.gcno
         -:    0:Data:test_paths.gcda
-        -:    0:Runs:3
+        -:    0:Runs:0
         -:    0:Programs:1
         -:    1:/*EOF*/
         -:    2:/*EOF*/

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_missing.h.gcov b/llvm/test/tools/llvm-cov/Inputs/test_missing.h.gcov
index d500e8619682..a66908b4a682 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_missing.h.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_missing.h.gcov
@@ -1,6 +1,6 @@
         -:    0:Source:srcdir/./nested_dir/../test.h
         -:    0:Graph:test_paths.gcno
         -:    0:Data:test_paths.gcda
-        -:    0:Runs:3
+        -:    0:Runs:0
         -:    0:Programs:1
         6:    1:/*EOF*/

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_no_options.cpp.gcov b/llvm/test/tools/llvm-cov/Inputs/test_no_options.cpp.gcov
index 8524c9a52138..91f74f14ebb7 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_no_options.cpp.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_no_options.cpp.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:test.cpp
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         -:    1:#include "test.h"
         -:    2:#include <cstdlib>

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_no_options.h.gcov b/llvm/test/tools/llvm-cov/Inputs/test_no_options.h.gcov
index 4ba58c9fdc4e..481f987c84ca 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_no_options.h.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_no_options.h.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:./test.h
         -:    0:Graph:test.gcno
         -:    0:Data:test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         4:    1:struct A {
         -:    2:  virtual void B();

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_objdir.cpp.gcov b/llvm/test/tools/llvm-cov/Inputs/test_objdir.cpp.gcov
index 22c8a2ad9501..7b35b8144bdf 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_objdir.cpp.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_objdir.cpp.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:test.cpp
         -:    0:Graph:objdir/test.gcno
         -:    0:Data:objdir/test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         -:    1:#include "test.h"
         -:    2:#include <cstdlib>

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_objdir.h.gcov b/llvm/test/tools/llvm-cov/Inputs/test_objdir.h.gcov
index 8208d2541805..d23d1497daa3 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_objdir.h.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_objdir.h.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:./test.h
         -:    0:Graph:objdir/test.gcno
         -:    0:Data:objdir/test.gcda
-        -:    0:Runs:2
+        -:    0:Runs:0
         -:    0:Programs:1
         4:    1:struct A {
         -:    2:  virtual void B();

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_paths.cpp.gcov b/llvm/test/tools/llvm-cov/Inputs/test_paths.cpp.gcov
index 9b89f51246c5..ffa1591d061d 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_paths.cpp.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_paths.cpp.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:srcdir/./nested_dir/../test.cpp
         -:    0:Graph:test_paths.gcno
         -:    0:Data:test_paths.gcda
-        -:    0:Runs:3
+        -:    0:Runs:0
         -:    0:Programs:1
         -:    1:#include "test.h"
         -:    2:#include <cstdlib>

diff  --git a/llvm/test/tools/llvm-cov/Inputs/test_paths.h.gcov b/llvm/test/tools/llvm-cov/Inputs/test_paths.h.gcov
index 95e90ca664c0..f8be8405c4f1 100644
--- a/llvm/test/tools/llvm-cov/Inputs/test_paths.h.gcov
+++ b/llvm/test/tools/llvm-cov/Inputs/test_paths.h.gcov
@@ -1,7 +1,7 @@
         -:    0:Source:srcdir/./nested_dir/../test.h
         -:    0:Graph:test_paths.gcno
         -:    0:Data:test_paths.gcda
-        -:    0:Runs:3
+        -:    0:Runs:0
         -:    0:Programs:1
         6:    1:struct A {
         -:    2:  virtual void B();

diff  --git a/llvm/test/tools/llvm-cov/gcov-4.7.c b/llvm/test/tools/llvm-cov/gcov-4.7.c
index f17cf174e85e..ab08883bde7e 100644
--- a/llvm/test/tools/llvm-cov/gcov-4.7.c
+++ b/llvm/test/tools/llvm-cov/gcov-4.7.c
@@ -27,11 +27,10 @@ int main() {                                      // GCOV:      #####: [[@LINE]]
 // RUN: FileCheck --input-file=%t/gcov-4.7.c.gcov --check-prefix=HEADER %s
 // RUN: FileCheck --input-file=%t/gcov-4.7.c.gcov --check-prefix=GCOV %s
 
-/// FIXME Runs:1
 // HEADER: {{^}} -:    0:Source:gcov-4.7.c
 // HEADER-NEXT:  -:    0:Graph:gcov-4.7.gcno
 // HEADER-NEXT:  -:    0:Data:gcov-4.7.gcda
-// HEADER-NEXT:  -:    0:Runs:0
+// HEADER-NEXT:  -:    0:Runs:1{{$}}
 // HEADER-NEXT:  -:    0:Programs:1
 // HEADER-NEXT:  -:    1:/// Test that llvm-cov
 

diff  --git a/llvm/test/tools/llvm-cov/gcov-8.c b/llvm/test/tools/llvm-cov/gcov-8.c
index 209144020b70..f8cdd18f99bd 100644
--- a/llvm/test/tools/llvm-cov/gcov-8.c
+++ b/llvm/test/tools/llvm-cov/gcov-8.c
@@ -27,11 +27,10 @@ int main() {                                      // GCOV:      1: [[@LINE]]:int
 // RUN: FileCheck --input-file=%t/gcov-8.c.gcov --check-prefix=HEADER %s
 // RUN: FileCheck --input-file=%t/gcov-8.c.gcov --check-prefix=GCOV %s
 
-/// FIXME Runs:1
 // HEADER: {{^}} -:    0:Source:gcov-8.c
 // HEADER-NEXT:  -:    0:Graph:gcov-8.gcno
 // HEADER-NEXT:  -:    0:Data:gcov-8.gcda
-// HEADER-NEXT:  -:    0:Runs:0
+// HEADER-NEXT:  -:    0:Runs:1{{$}}
 // HEADER-NEXT:  -:    0:Programs:1
 // HEADER-NEXT:  -:    1:/// Test that llvm-cov
 

diff  --git a/llvm/test/tools/llvm-cov/gcov-9.c b/llvm/test/tools/llvm-cov/gcov-9.c
index a5fda277af72..6e631cb078cf 100644
--- a/llvm/test/tools/llvm-cov/gcov-9.c
+++ b/llvm/test/tools/llvm-cov/gcov-9.c
@@ -27,11 +27,10 @@ int main() {                                      // GCOV:      1: [[@LINE]]:int
 // RUN: FileCheck --input-file=%t/gcov-9.c.gcov --check-prefix=HEADER %s
 // RUN: FileCheck --input-file=%t/gcov-9.c.gcov --check-prefix=GCOV %s
 
-/// FIXME Runs:1
 // HEADER: {{^}} -:    0:Source:gcov-9.c
 // HEADER-NEXT:  -:    0:Graph:gcov-9.gcno
 // HEADER-NEXT:  -:    0:Data:gcov-9.gcda
-// HEADER-NEXT:  -:    0:Runs:16777216
+// HEADER-NEXT:  -:    0:Runs:1{{$}}
 // HEADER-NEXT:  -:    1:/// Test that llvm-cov
 
 // XFAIL: host-byteorder-big-endian


        


More information about the llvm-commits mailing list