From: Fangrui Song Date: Tue, 12 May 2020 01:43:15 +0000 (-0700) Subject: [gcov] Emit GCOV_TAG_OBJECT_SUMMARY/GCOV_TAG_PROGRAM_SUMMARY correctly and fix llvm... X-Git-Tag: llvmorg-12-init~6325 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=013f06703e132c31cf3e8bdb2ae7c6b89b8f8fc2;p=platform%2Fupstream%2Fllvm.git [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. --- diff --git a/compiler-rt/lib/profile/GCDAProfiling.c b/compiler-rt/lib/profile/GCDAProfiling.c index 6833609..fe39ce9 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 e8e0629..242ab17 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 78ebbfc..589194c 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 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 84fcb52..755d96c 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 b1e658e..7b34473 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 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 d85b562..010a699 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 603d14e..27bc06c 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 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 e980e21..a5ea637 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 f9f5f30..e6d5ace 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 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 923ac8a..6ddfe03 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 9b3da27..1a5aab1 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 d500e86..a66908b 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 8524c9a..91f74f1 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 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 4ba58c9..481f987 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 22c8a2a..7b35b81 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 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 8208d25..d23d149 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 9b89f51..ffa1591 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 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 95e90ca..f8be840 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 f17cf17..ab08883 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 2091440..f8cdd18 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 a5fda277..6e631cb 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