CODEGENOPT(Backchain , 1, 0) ///< -mbackchain
CODEGENOPT(ControlFlowGuardNoChecks , 1, 0) ///< -cfguard-no-checks
CODEGENOPT(ControlFlowGuard , 1, 0) ///< -cfguard
-CODEGENOPT(CoverageExtraChecksum, 1, 0) ///< Whether we need a second checksum for functions in GCNO files.
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.
HelpText<"Emit coverage notes to this filename.">;
def coverage_notes_file_EQ : Joined<["-"], "coverage-notes-file=">,
Alias<coverage_notes_file>;
-def coverage_cfg_checksum : Flag<["-"], "coverage-cfg-checksum">,
- HelpText<"Emit CFG checksum for functions in .gcno files.">;
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=">,
#include "clang/Basic/CodeGenOptions.def"
RelocationModel = llvm::Reloc::PIC_;
- memcpy(CoverageVersion, "402*", 4);
+ memcpy(CoverageVersion, "407*", 4);
}
bool CodeGenOptions::isNoBuiltinFunc(const char *Name) const {
Options.EmitNotes = CodeGenOpts.EmitGcovNotes;
Options.EmitData = CodeGenOpts.EmitGcovArcs;
llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version));
- Options.UseCfgChecksum = CodeGenOpts.CoverageExtraChecksum;
Options.NoRedZone = CodeGenOpts.DisableRedZone;
Options.Filter = CodeGenOpts.ProfileFilterFiles;
Options.Exclude = CodeGenOpts.ProfileExcludeFiles;
std::string(Args.getLastArgValue(OPT_coverage_data_file));
Opts.CoverageNotesFile =
std::string(Args.getLastArgValue(OPT_coverage_notes_file));
- Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum);
Opts.ProfileFilterFiles =
std::string(Args.getLastArgValue(OPT_fprofile_filter_files_EQ));
Opts.ProfileExcludeFiles =
-// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data %s -o - | FileCheck %s
+/// We support coverage versions 4.2 and 4.7.
+/// 4.7 (default, compatible with gcov 7) enables cfg_checksum.
+// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-version='402*' %s -o - | \
+// RUN: FileCheck --check-prefixes=CHECK,402 %s
+// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-version='407*' %s -o - | \
+// RUN: FileCheck --check-prefixes=CHECK,407 %s
+// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data %s -o - | \
+// RUN: FileCheck --check-prefixes=CHECK,407 %s
+
// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-notes-file=aaa.gcno -coverage-data-file=bbb.gcda -dwarf-column-info -debug-info-kind=limited -dwarf-version=4 %s -o - | FileCheck %s --check-prefix GCOV_FILE_INFO
// RUN: %clang_cc1 -emit-llvm-bc -o /dev/null -fexperimental-new-pass-manager -fdebug-pass-manager -femit-coverage-data %s 2>&1 | FileCheck --check-prefix=NEWPM %s
return b * 2;
}
+// 402: private unnamed_addr constant [5 x i8] c"*204\00"
+// 407: private unnamed_addr constant [5 x i8] c"*704\00"
+
// CHECK: @__llvm_internal_gcov_emit_function_args.0 = internal unnamed_addr constant [2 x %0]
-// CHECK-SAME: [%0 zeroinitializer, %0 { i32 1, i32 0, i8 0, i32 0 }]
+// CHECK-SAME: [%0 zeroinitializer, %0 { i32 1, i32 0, i32 0 }]
// Check that the noredzone flag is set on the generated functions.
static uint64_t cur_pos = 0;
static uint64_t file_size = 0;
static int new_file = 0;
+static int gcov_version;
#if defined(_WIN32)
static HANDLE mmap_handle = NULL;
#endif
}
/* gcda file, version, stamp checksum. */
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ gcov_version = version[3] >= 'A'
+ ? (version[3] - 'A') * 100 + (version[2] - '0') * 10 +
+ version[1] - '0'
+ : (version[3] - '0') * 10 + version[1] - '0';
+#else
+ gcov_version = version[0] >= 'A'
+ ? (version[0] - 'A') * 100 + (version[1] - '0') * 10 +
+ version[2] - '0'
+ : (version[0] - '0') * 10 + version[2] - '0';
+#endif
+
write_bytes("adcg", 4);
write_bytes(version, 4);
write_32bit_value(checksum);
COMPILER_RT_VISIBILITY
void llvm_gcda_emit_function(uint32_t ident, uint32_t func_checksum,
- uint8_t use_extra_checksum,
uint32_t cfg_checksum) {
uint32_t len = 2;
+ int use_extra_checksum = gcov_version >= 47;
if (use_extra_checksum)
len++;
// gcc's gcov-io.h
char Version[4];
- // Emit a "cfg checksum" that follows the "line number checksum" of a
- // function. This affects both .gcno and .gcda files.
- bool UseCfgChecksum;
-
// Add the 'noredzone' attribute to added runtime library calls.
bool NoRedZone;
#define DEBUG_TYPE "insert-gcov-profiling"
-static cl::opt<std::string>
-DefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden,
- cl::ValueRequired);
+static cl::opt<std::string> DefaultGCOVVersion("default-gcov-version",
+ cl::init("407*"), cl::Hidden,
+ cl::ValueRequired);
static cl::opt<bool> DefaultExitBlockBeforeBody("gcov-exit-block-before-body",
cl::init(false), cl::Hidden);
GCOVOptions Options;
Options.EmitNotes = true;
Options.EmitData = true;
- Options.UseCfgChecksum = false;
Options.NoRedZone = false;
Options.ExitBlockBeforeBody = DefaultExitBlockBeforeBody;
++It;
EntryBlock.splitBasicBlock(It);
- Funcs.push_back(std::make_unique<GCOVFunction>(SP, &F, &out, FunctionIdent++,
- Options.UseCfgChecksum,
- Options.ExitBlockBeforeBody));
+ bool UseCfgChecksum = strncmp(Options.Version, "407", 3) >= 0;
+ Funcs.push_back(std::make_unique<GCOVFunction>(
+ SP, &F, &out, FunctionIdent++, UseCfgChecksum,
+ Options.ExitBlockBeforeBody));
GCOVFunction &Func = *Funcs.back();
// Add the function line number to the lines of the entry block
Type *Args[] = {
Type::getInt32Ty(*Ctx), // uint32_t ident
Type::getInt32Ty(*Ctx), // uint32_t func_checksum
- Type::getInt8Ty(*Ctx), // uint8_t use_extra_checksum
Type::getInt32Ty(*Ctx), // uint32_t cfg_checksum
};
FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false);
AttributeList AL;
if (auto AK = TLI->getExtAttrForI32Param(false)) {
AL = AL.addParamAttribute(*Ctx, 0, AK);
+ AL = AL.addParamAttribute(*Ctx, 1, AK);
AL = AL.addParamAttribute(*Ctx, 2, AK);
- AL = AL.addParamAttribute(*Ctx, 3, AK);
- AL = AL.addParamAttribute(*Ctx, 4, AK);
}
return M->getOrInsertFunction("llvm_gcda_emit_function", FTy);
}
// walk to write out everything.
StructType *StartFileCallArgsTy = StructType::create(
{Builder.getInt8PtrTy(), Builder.getInt8PtrTy(), Builder.getInt32Ty()});
- StructType *EmitFunctionCallArgsTy =
- StructType::create({Builder.getInt32Ty(), Builder.getInt32Ty(),
- Builder.getInt8Ty(), Builder.getInt32Ty()});
+ StructType *EmitFunctionCallArgsTy = StructType::create(
+ {Builder.getInt32Ty(), Builder.getInt32Ty(), Builder.getInt32Ty()});
StructType *EmitArcsCallArgsTy = StructType::create(
{Builder.getInt32Ty(), Builder.getInt64Ty()->getPointerTo()});
StructType *FileInfoTy =
EmitFunctionCallArgsTy,
{Builder.getInt32(j),
Builder.getInt32(FuncChecksum),
- Builder.getInt8(Options.UseCfgChecksum),
Builder.getInt32(CfgChecksum)}));
GlobalVariable *GV = CountersBySP[j].first;
EmitFunctionCallArgsPtr, 1)),
Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(2),
Builder.CreateStructGEP(EmitFunctionCallArgsTy,
- EmitFunctionCallArgsPtr, 2)),
- Builder.CreateLoad(EmitFunctionCallArgsTy->getElementType(3),
- Builder.CreateStructGEP(EmitFunctionCallArgsTy,
EmitFunctionCallArgsPtr,
- 3))});
+ 2))});
if (auto AK = TLI->getExtAttrForI32Param(false)) {
EmitFunctionCall->addParamAttr(0, AK);
EmitFunctionCall->addParamAttr(1, AK);
EmitFunctionCall->addParamAttr(2, AK);
- EmitFunctionCall->addParamAttr(3, AK);
}
auto *EmitArcsCallArgsPtr =
Builder.CreateInBoundsGEP(EmitArcsCallArgsTy, EmitArcsCallArgsArray, JV);
; GCDA-NEXT: %[[EMIT_FUN_ARG_1_PTR:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %[[EMIT_FUN_ARGS]], i32 0, i32 1
; GCDA-NEXT: %[[EMIT_FUN_ARG_1:.*]] = load i32, i32* %[[EMIT_FUN_ARG_1_PTR]]
; GCDA-NEXT: %[[EMIT_FUN_ARG_2_PTR:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %[[EMIT_FUN_ARGS]], i32 0, i32 2
-; GCDA-NEXT: %[[EMIT_FUN_ARG_2:.*]] = load i8, i8* %[[EMIT_FUN_ARG_2_PTR]]
-; GCDA-NEXT: %[[EMIT_FUN_ARG_3_PTR:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %[[EMIT_FUN_ARGS]], i32 0, i32 3
-; GCDA-NEXT: %[[EMIT_FUN_ARG_3:.*]] = load i32, i32* %[[EMIT_FUN_ARG_3_PTR]]
+; GCDA-NEXT: %[[EMIT_FUN_ARG_2:.*]] = load i32, i32* %[[EMIT_FUN_ARG_2_PTR]]
; GCDA-NEXT: call void @llvm_gcda_emit_function(i32 %[[EMIT_FUN_ARG_0]],
; GCDA-SAME: i32 %[[EMIT_FUN_ARG_1]],
-; GCDA-SAME: i8 %[[EMIT_FUN_ARG_2]],
-; GCDA-SAME: i32 %[[EMIT_FUN_ARG_3]])
+; GCDA-SAME: i32 %[[EMIT_FUN_ARG_2]])
; GCDA-NEXT: %[[EMIT_ARCS_ARGS:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %[[EMIT_ARCS_ARGS_ARRAY]], i32 %[[JV]]
; GCDA-NEXT: %[[EMIT_ARCS_ARG_0_PTR:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %[[EMIT_ARCS_ARGS]], i32 0, i32 0
; GCDA-NEXT: %[[EMIT_ARCS_ARG_0:.*]] = load i32, i32* %[[EMIT_ARCS_ARG_0_PTR]]
; 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.204'
+; RUN: head -c8 %t/version.gcno | grep '^oncg.704'
; 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=407* -disable-output < %t/2
-; RUN: head -c8 %t/version.gcno | grep '^oncg.704'
+; RUN: opt -insert-gcov-profiling -default-gcov-version='402*' -disable-output < %t/2
+; RUN: head -c8 %t/version.gcno | grep '^oncg.204'
; RUN: rm %t/version.gcno
; RUN: opt -passes=insert-gcov-profiling -disable-output < %t/2
-; RUN: head -c8 %t/version.gcno | grep '^oncg.204'
+; RUN: head -c8 %t/version.gcno | grep '^oncg.704'
; 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=407* -disable-output < %t/2
-; RUN: head -c8 %t/version.gcno | grep '^oncg.704'
+; RUN: opt -passes=insert-gcov-profiling -default-gcov-version='402*' -disable-output < %t/2
+; RUN: head -c8 %t/version.gcno | grep '^oncg.204'
; RUN: rm %t/version.gcno
define void @test() !dbg !5 {