forked from OSchip/llvm-project
[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.
This commit is contained in:
parent
2e9f1153c5
commit
013f06703e
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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%
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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%
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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%
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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*/
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue