Skip to content

Commit

Permalink
[gcov] Emit GCOV_TAG_OBJECT_SUMMARY/GCOV_TAG_PROGRAM_SUMMARY correctl…
Browse files Browse the repository at this point in the history
…y 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.
  • Loading branch information
MaskRay committed May 12, 2020
1 parent 2e9f115 commit 013f067
Show file tree
Hide file tree
Showing 21 changed files with 54 additions and 48 deletions.
57 changes: 32 additions & 25 deletions compiler-rt/lib/profile/GCDAProfiling.c
Expand Up @@ -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 ---
*/
Expand Down Expand Up @@ -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;
Expand All @@ -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;

Expand Down
4 changes: 3 additions & 1 deletion llvm/lib/ProfileData/GCOV.cpp
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion 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>
Expand Down
2 changes: 1 addition & 1 deletion 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
Expand Down
2 changes: 1 addition & 1 deletion 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>
Expand Down
2 changes: 1 addition & 1 deletion 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%
Expand Down
2 changes: 1 addition & 1 deletion 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>
Expand Down
2 changes: 1 addition & 1 deletion 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%
Expand Down
2 changes: 1 addition & 1 deletion 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>
Expand Down
2 changes: 1 addition & 1 deletion 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%
Expand Down
2 changes: 1 addition & 1 deletion 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*/
Expand Down
2 changes: 1 addition & 1 deletion 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*/
2 changes: 1 addition & 1 deletion 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>
Expand Down
2 changes: 1 addition & 1 deletion 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();
Expand Down
2 changes: 1 addition & 1 deletion 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>
Expand Down
2 changes: 1 addition & 1 deletion 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();
Expand Down
2 changes: 1 addition & 1 deletion 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>
Expand Down
2 changes: 1 addition & 1 deletion 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();
Expand Down
3 changes: 1 addition & 2 deletions llvm/test/tools/llvm-cov/gcov-4.7.c
Expand Up @@ -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

Expand Down
3 changes: 1 addition & 2 deletions llvm/test/tools/llvm-cov/gcov-8.c
Expand Up @@ -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

Expand Down
3 changes: 1 addition & 2 deletions llvm/test/tools/llvm-cov/gcov-9.c
Expand Up @@ -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

0 comments on commit 013f067

Please sign in to comment.