gcov 4.8 (r189778) moved the exit block from the last to the second.
The .gcda format is compatible with 4.7 but
* decoding libgcov 4.7 produced .gcda with gcov [4.7,8) can mistake the
exit block, emit bogus `%s:'%s' has arcs from exit block\n` warnings,
and print wrong `" returned %s` for branch statistics (-b).
* decoding libgcov 4.8 produced .gcda with gcov 4.7 has similar issues.
Also, rename "return block" to "exit block" because the latter is the
appropriate term.
CODEGENOPT(Backchain , 1, 0) ///< -mbackchain
CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks
CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard
-CODEGENOPT(CoverageExitBlockBeforeBody, 1, 0) ///< Whether to emit the exit block before the body blocks in GCNO files.
CODEGENOPT(CXAAtExit , 1, 1) ///< Use __cxa_atexit for calling destructors.
CODEGENOPT(RegisterGlobalDtorsWithAtExit, 1, 1) ///< Use atexit or __cxa_atexit to register global destructors.
CODEGENOPT(CXXCtorDtorAliases, 1, 0) ///< Emit complete ctors/dtors as linker
HelpText<"Emit coverage notes to this filename.">;
def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">,
Alias<coverage_notes_file>;
-def coverage_exit_block_before_body : Flag<["-"], "coverage-exit-block-before-body">,
- HelpText<"Emit the exit block before the body blocks in .gcno files.">;
def coverage_version_EQ : Joined<["-"], "coverage-version=">,
HelpText<"Four-byte version string for gcov files.">;
def test_coverage : Flag<["-"], "test-coverage">,
#include "clang/Basic/CodeGenOptions.def"
RelocationModel = llvm::Reloc::PIC_;
- memcpy(CoverageVersion, "407*", 4);
+ memcpy(CoverageVersion, "408*", 4);
}
bool CodeGenOptions::isNoBuiltinFunc(const char *Name) const {
Options.NoRedZone = CodeGenOpts.DisableRedZone;
Options.Filter = CodeGenOpts.ProfileFilterFiles;
Options.Exclude = CodeGenOpts.ProfileExcludeFiles;
- Options.ExitBlockBeforeBody = CodeGenOpts.CoverageExitBlockBeforeBody;
return Options;
}
std::string(Args.getLastArgValue(OPT_fprofile_filter_files_EQ));
Opts.ProfileExcludeFiles =
std::string(Args.getLastArgValue(OPT_fprofile_exclude_files_EQ));
- Opts.CoverageExitBlockBeforeBody =
- Args.hasArg(OPT_coverage_exit_block_before_body);
if (Args.hasArg(OPT_coverage_version_EQ)) {
StringRef CoverageVersion = Args.getLastArgValue(OPT_coverage_version_EQ);
if (CoverageVersion.size() != 4) {
namespace GCOV {
-enum GCOVVersion { V402, V407, V800, V900 };
+enum GCOVVersion { V402, V407, V408, V800, V900 };
/// A struct for passing gcov options between functions.
struct Options {
// PR gcov-profile/48463
Version = GCOV::V800;
return true;
- } else if (Major > 4 || (Major == 4 && Minor >= 7)) {
- // r173147
+ } else if (Major > 4 || (Major == 4 && Minor >= 8)) {
+ // r189778: the exit block moved from the last to the second.
+ Version = GCOV::V408;
+ return true;
+ } else if (Major == 4 && Minor >= 7) {
+ // r173147: split checksum into cfg checksum and line checksum.
Version = GCOV::V407;
return true;
} else {
// Add the 'noredzone' attribute to added runtime library calls.
bool NoRedZone;
- // Emit the exit block immediately after the start block, rather than after
- // all of the function body's blocks.
- bool ExitBlockBeforeBody;
-
// Regexes separated by a semi-colon to filter the files to instrument.
std::string Filter;
#define DEBUG_TYPE "insert-gcov-profiling"
static cl::opt<std::string> DefaultGCOVVersion("default-gcov-version",
- cl::init("407*"), cl::Hidden,
+ cl::init("408*"), cl::Hidden,
cl::ValueRequired);
-static cl::opt<bool> DefaultExitBlockBeforeBody("gcov-exit-block-before-body",
- cl::init(false), cl::Hidden);
GCOVOptions GCOVOptions::getDefault() {
GCOVOptions Options;
Options.EmitNotes = true;
Options.EmitData = true;
Options.NoRedZone = false;
- Options.ExitBlockBeforeBody = DefaultExitBlockBeforeBody;
if (DefaultGCOVVersion.size() != 4) {
llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") +
EntryBlock.splitBasicBlock(It);
bool UseCfgChecksum = strncmp(Options.Version, "407", 3) >= 0;
+ bool ExitBlockBeforeBody = strncmp(Options.Version, "408", 3) >= 0;
Funcs.push_back(std::make_unique<GCOVFunction>(
- SP, &F, &out, FunctionIdent++, UseCfgChecksum,
- Options.ExitBlockBeforeBody));
+ SP, &F, &out, FunctionIdent++, UseCfgChecksum, ExitBlockBeforeBody));
GCOVFunction &Func = *Funcs.back();
// Add the function line number to the lines of the entry block
; Inject metadata to set the .gcno file location
; RUN: rm -rf %t && mkdir -p %t
-; RUN: echo '!19 = !{!"%/t/return-block.ll", !0}' > %t/1
+; RUN: echo '!19 = !{!"%/t/exit-block.ll", !0}' > %t/1
; RUN: cat %s %t/1 > %t/2
-; By default, the return block is last.
+; By default, the exit block is the second.
; RUN: opt -insert-gcov-profiling -disable-output %t/2
-; RUN: llvm-cov gcov -n -dump %t/return-block.gcno 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=RETURN-LAST %s
+; RUN: llvm-cov gcov -n -dump %t/exit-block.gcno 2>&1 | FileCheck --check-prefixes=CHECK,EXIT-SECOND %s
-; But we can optionally emit it second, to match newer gcc versions.
-; RUN: opt -insert-gcov-profiling -gcov-exit-block-before-body -disable-output %t/2
-; RUN: llvm-cov gcov -n -dump %t/return-block.gcno 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=RETURN-SECOND %s
-; RUN: rm %t/return-block.gcno
+; But we can optionally emit it last, to match GCC<4.8 (r189778).
+; RUN: opt -insert-gcov-profiling -default-gcov-version='407*' -disable-output %t/2
+; RUN: llvm-cov gcov -n -dump %t/exit-block.gcno 2>&1 | FileCheck --check-prefixes=CHECK,EXIT-LAST %s
+; RUN: rm %t/exit-block.gcno
-; By default, the return block is last.
+; By default, the exit block is the second.
; RUN: opt -passes=insert-gcov-profiling -disable-output %t/2
-; RUN: llvm-cov gcov -n -dump %t/return-block.gcno 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=RETURN-LAST %s
+; RUN: llvm-cov gcov -n -dump %t/exit-block.gcno 2>&1 | FileCheck --check-prefixes=CHECK,EXIT-SECOND %s
-; But we can optionally emit it second, to match newer gcc versions.
-; RUN: opt -passes=insert-gcov-profiling -gcov-exit-block-before-body -disable-output %t/2
-; RUN: llvm-cov gcov -n -dump %t/return-block.gcno 2>&1 | FileCheck -check-prefix=CHECK -check-prefix=RETURN-SECOND %s
+; But we can optionally emit it last, to match GCC<4.8 (r189778).
+; RUN: opt -passes=insert-gcov-profiling -default-gcov-version='407*' -disable-output %t/2
+; RUN: llvm-cov gcov -n -dump %t/exit-block.gcno 2>&1 | FileCheck --check-prefixes=CHECK,EXIT-LAST %s
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"
!llvm.ident = !{!13}
!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.6.0 (trunk 223182)", isOptimized: true, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !2, globals: !8, imports: !2)
-!1 = !DIFile(filename: ".../llvm/test/Transforms/GCOVProfiling/return-block.ll", directory: "")
+!1 = !DIFile(filename: ".../llvm/test/Transforms/GCOVProfiling/exit-block.ll", directory: "")
!2 = !{}
!4 = distinct !DISubprogram(name: "test", line: 5, isLocal: false, isDefinition: true, isOptimized: true, unit: !0, scopeLine: 5, file: !1, scope: !5, type: !6, retainedNodes: !2)
-!5 = !DIFile(filename: ".../llvm/test/Transforms/GCOVProfiling/return-block.ll", directory: "")
+!5 = !DIFile(filename: ".../llvm/test/Transforms/GCOVProfiling/exit-block.ll", directory: "")
!6 = !DISubroutineType(types: !7)
!7 = !{null}
!8 = !{!9}
; There should be no destination edges for the exit block.
; CHECK: Block : 1 Counter : 0
-; RETURN-LAST: Destination Edges
-; RETURN-SECOND-NOT: Destination Edges
+; EXIT-LAST: Destination Edges
+; EXIT-SECOND-NOT: Destination Edges
; CHECK: Block : 2 Counter : 0
; CHECK: Block : 4 Counter : 0
-; RETURN-LAST-NOT: Destination Edges
-; RETURN-SECOND: Destination Edges
+; EXIT-LAST-NOT: Destination Edges
+; EXIT-SECOND: Destination Edges
; CHECK-NOT: Block :
; RUN: echo '!9 = !{!"%/t/version.ll", !0}' > %t/1
; RUN: cat %s %t/1 > %t/2
; RUN: opt -insert-gcov-profiling -disable-output < %t/2
-; RUN: head -c8 %t/version.gcno | grep '^oncg.704'
+; RUN: head -c8 %t/version.gcno | grep '^oncg.804'
; RUN: rm %t/version.gcno
; RUN: not --crash opt -insert-gcov-profiling -default-gcov-version=asdfasdf -disable-output < %t/2
; RUN: opt -insert-gcov-profiling -default-gcov-version='402*' -disable-output < %t/2
; RUN: rm %t/version.gcno
; RUN: opt -passes=insert-gcov-profiling -disable-output < %t/2
-; RUN: head -c8 %t/version.gcno | grep '^oncg.704'
+; RUN: head -c8 %t/version.gcno | grep '^oncg.804'
; RUN: rm %t/version.gcno
; RUN: not --crash opt -passes=insert-gcov-profiling -default-gcov-version=asdfasdf -disable-output < %t/2
; RUN: opt -passes=insert-gcov-profiling -default-gcov-version='402*' -disable-output < %t/2