Author: nicholas Date: Wed Aug 31 18:04:32 2016 New Revision: 280306 URL: http://llvm.org/viewvc/llvm-project?rev=280306&view=rev Log: Add -fprofile-dir= to clang.
-fprofile-dir=path allows the user to specify where .gcda files should be emitted when the program is run. In particular, this is the first flag that causes the .gcno and .o files to have different paths, LLVM is extended to support this. -fprofile-dir= does not change the file name in the .gcno (and thus where lcov looks for the source) but it does change the name in the .gcda (and thus where the runtime library writes the .gcda file). It's different from a GCOV_PREFIX because a user can observe that the GCOV_PREFIX_STRIP will strip paths off of -fprofile-dir= but not off of a supplied GCOV_PREFIX. To implement this we split -coverage-file into -coverage-data-file and -coverage-notes-file to specify the two different names. The !llvm.gcov metadata node grows from a 2-element form {string coverage-file, node dbg.cu} to 3-elements, {string coverage-notes-file, string coverage-data-file, node dbg.cu}. In the 3-element form, the file name is already "mangled" with .gcno/.gcda suffixes, while the 2-element form left that to the middle end pass. Modified: cfe/trunk/include/clang/Driver/CC1Options.td cfe/trunk/include/clang/Driver/Options.td cfe/trunk/include/clang/Frontend/CodeGenOptions.h cfe/trunk/lib/CodeGen/CodeGenModule.cpp cfe/trunk/lib/Driver/Tools.cpp cfe/trunk/lib/Frontend/CompilerInvocation.cpp cfe/trunk/test/CodeGen/code-coverage.c cfe/trunk/test/Driver/clang_f_opts.c cfe/trunk/test/Driver/coverage_no_integrated_as.c Modified: cfe/trunk/include/clang/Driver/CC1Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/CC1Options.td (original) +++ cfe/trunk/include/clang/Driver/CC1Options.td Wed Aug 31 18:04:32 2016 @@ -192,9 +192,14 @@ def femit_coverage_notes : Flag<["-"], " HelpText<"Emit a gcov coverage notes file when compiling.">; def femit_coverage_data: Flag<["-"], "femit-coverage-data">, HelpText<"Instrument the program to emit gcov coverage data when run.">; -def coverage_file : Separate<["-"], "coverage-file">, - HelpText<"Emit coverage data to this filename. The extension will be replaced.">; -def coverage_file_EQ : Joined<["-"], "coverage-file=">, Alias<coverage_file>; +def coverage_data_file : Separate<["-"], "coverage-data-file">, + HelpText<"Emit coverage data to this filename.">; +def coverage_data_file_EQ : Joined<["-"], "coverage-data-file=">, + Alias<coverage_data_file>; +def coverage_notes_file : Separate<["-"], "coverage-notes-file">, + 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_no_function_names_in_data : Flag<["-"], "coverage-no-function-names-in-data">, Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Wed Aug 31 18:04:32 2016 @@ -2117,7 +2117,7 @@ multiclass BooleanFFlag<string name> { defm : BooleanFFlag<"keep-inline-functions">, Group<clang_ignored_gcc_optimization_f_Group>; -def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<clang_ignored_gcc_optimization_f_Group>; +def fprofile_dir : Joined<["-"], "fprofile-dir=">, Group<f_Group>; def fuse_ld_EQ : Joined<["-"], "fuse-ld=">, Group<f_Group>; Modified: cfe/trunk/include/clang/Frontend/CodeGenOptions.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CodeGenOptions.h?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/include/clang/Frontend/CodeGenOptions.h (original) +++ cfe/trunk/include/clang/Frontend/CodeGenOptions.h Wed Aug 31 18:04:32 2016 @@ -99,9 +99,13 @@ public: /// The code model to use (-mcmodel). std::string CodeModel; - /// The filename with path we use for coverage files. The extension will be - /// replaced. - std::string CoverageFile; + /// The filename with path we use for coverage data files. The runtime + /// allows further manipulation with the GCOV_PREFIX and GCOV_PREFIX_STRIP + /// environment variables. + std::string CoverageDataFile; + + /// The filename with path we use for coverage notes files. + std::string CoverageNotesFile; /// The version string to put into coverage files. char CoverageVersion[4]; Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original) +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Wed Aug 31 18:04:32 2016 @@ -4208,18 +4208,24 @@ void CodeGenModule::EmitTargetMetadata() } void CodeGenModule::EmitCoverageFile() { - if (!getCodeGenOpts().CoverageFile.empty()) { - if (llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu")) { - llvm::NamedMDNode *GCov = TheModule.getOrInsertNamedMetadata("llvm.gcov"); - llvm::LLVMContext &Ctx = TheModule.getContext(); - llvm::MDString *CoverageFile = - llvm::MDString::get(Ctx, getCodeGenOpts().CoverageFile); - for (int i = 0, e = CUNode->getNumOperands(); i != e; ++i) { - llvm::MDNode *CU = CUNode->getOperand(i); - llvm::Metadata *Elts[] = {CoverageFile, CU}; - GCov->addOperand(llvm::MDNode::get(Ctx, Elts)); - } - } + if (getCodeGenOpts().CoverageDataFile.empty() && + getCodeGenOpts().CoverageNotesFile.empty()) + return; + + llvm::NamedMDNode *CUNode = TheModule.getNamedMetadata("llvm.dbg.cu"); + if (!CUNode) + return; + + llvm::NamedMDNode *GCov = TheModule.getOrInsertNamedMetadata("llvm.gcov"); + llvm::LLVMContext &Ctx = TheModule.getContext(); + auto *CoverageDataFile = + llvm::MDString::get(Ctx, getCodeGenOpts().CoverageDataFile); + auto *CoverageNotesFile = + llvm::MDString::get(Ctx, getCodeGenOpts().CoverageNotesFile); + for (int i = 0, e = CUNode->getNumOperands(); i != e; ++i) { + llvm::MDNode *CU = CUNode->getOperand(i); + llvm::Metadata *Elts[] = {CoverageNotesFile, CoverageDataFile, CU}; + GCov->addOperand(llvm::MDNode::get(Ctx, Elts)); } } Modified: cfe/trunk/lib/Driver/Tools.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Tools.cpp (original) +++ cfe/trunk/lib/Driver/Tools.cpp Wed Aug 31 18:04:32 2016 @@ -3622,13 +3622,13 @@ static void addPGOAndCoverageFlags(Compi if (C.getArgs().hasArg(options::OPT_c) || C.getArgs().hasArg(options::OPT_S)) { if (Output.isFilename()) { - CmdArgs.push_back("-coverage-file"); - SmallString<128> CoverageFilename; - if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) { - CoverageFilename = FinalOutput->getValue(); - } else { - CoverageFilename = llvm::sys::path::filename(Output.getBaseInput()); - } + CmdArgs.push_back("-coverage-notes-file"); + SmallString<128> OutputFilename; + if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o)) + OutputFilename = FinalOutput->getValue(); + else + OutputFilename = llvm::sys::path::filename(Output.getBaseInput()); + SmallString<128> CoverageFilename = OutputFilename; if (llvm::sys::path::is_relative(CoverageFilename)) { SmallString<128> Pwd; if (!llvm::sys::fs::current_path(Pwd)) { @@ -3636,7 +3636,23 @@ static void addPGOAndCoverageFlags(Compi CoverageFilename.swap(Pwd); } } + llvm::sys::path::replace_extension(CoverageFilename, "gcno"); CmdArgs.push_back(Args.MakeArgString(CoverageFilename)); + + // Leave -fprofile-dir= an unused argument unless .gcda emission is + // enabled. To be polite, with '-fprofile-arcs -fno-profile-arcs' consider + // the flag used. There is no -fno-profile-dir, so the user has no + // targeted way to suppress the warning. + if (Args.hasArg(options::OPT_fprofile_arcs) || + Args.hasArg(options::OPT_coverage)) { + CmdArgs.push_back("-coverage-data-file"); + if (Arg *FProfileDir = Args.getLastArg(options::OPT_fprofile_dir)) { + CoverageFilename = FProfileDir->getValue(); + llvm::sys::path::append(CoverageFilename, OutputFilename); + } + llvm::sys::path::replace_extension(CoverageFilename, "gcda"); + CmdArgs.push_back(Args.MakeArgString(CoverageFilename)); + } } } } Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original) +++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Wed Aug 31 18:04:32 2016 @@ -639,7 +639,8 @@ static bool ParseCodeGenArgs(CodeGenOpti Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes); if (Opts.EmitGcovArcs || Opts.EmitGcovNotes) { - Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file); + Opts.CoverageDataFile = Args.getLastArgValue(OPT_coverage_data_file); + Opts.CoverageNotesFile = Args.getLastArgValue(OPT_coverage_notes_file); Opts.CoverageExtraChecksum = Args.hasArg(OPT_coverage_cfg_checksum); Opts.CoverageNoFunctionNamesInData = Args.hasArg(OPT_coverage_no_function_names_in_data); Modified: cfe/trunk/test/CodeGen/code-coverage.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/code-coverage.c?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/test/CodeGen/code-coverage.c (original) +++ cfe/trunk/test/CodeGen/code-coverage.c Wed Aug 31 18:04:32 2016 @@ -1,5 +1,6 @@ // RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data %s -o - | FileCheck %s // RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-no-function-names-in-data %s -o - | FileCheck %s --check-prefix WITHOUTNAMES +// RUN: %clang_cc1 -emit-llvm -disable-red-zone -femit-coverage-data -coverage-notes-file=aaa.gcno -coverage-data-file=bbb.gcda %s -o - | FileCheck %s --check-prefix GCOV_FILE_INFO // <rdar://problem/12843084> @@ -28,3 +29,6 @@ int test1(int a) { // CHECK: void @__llvm_gcov_init() unnamed_addr [[NRZ]] // CHECK: attributes [[NRZ]] = { {{.*}}noredzone{{.*}} } + +// GCOV_FILE_INFO: !llvm.gcov = !{![[GCOV:[0-9]+]]} +// GCOV_FILE_INFO: ![[GCOV]] = !{!"aaa.gcno", !"bbb.gcda", !{{[0-9]+}}} Modified: cfe/trunk/test/Driver/clang_f_opts.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/clang_f_opts.c?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/test/Driver/clang_f_opts.c (original) +++ cfe/trunk/test/Driver/clang_f_opts.c Wed Aug 31 18:04:32 2016 @@ -66,6 +66,16 @@ // CHECK-PROFILE-ARCS: "-femit-coverage-data" // CHECK-NO-PROFILE-ARCS-NOT: "-femit-coverage-data" +// RUN: %clang -### -S -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-UNUSED %s +// RUN: %clang -### -S -ftest-coverage -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-UNUSED %s +// RUN: %clang -### -S -fprofile-arcs -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR %s +// RUN: %clang -### -S --coverage -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR %s +// RUN: %clang -### -S -fprofile-arcs -fno-profile-arcs -fprofile-dir=abc %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-DIR-NEITHER %s +// CHECK-PROFILE-DIR: "-coverage-data-file" "abc +// CHECK-PROFILE-DIR-UNUSED: argument unused +// CHECK-PROFILE-DIR-UNUSED-NOT: "-coverage-data-file" "abc +// CHECK-PROFILE-DIR-NEITHER-NOT: argument unused + // RUN: %clang -### -S -fprofile-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-LLVM %s // RUN: %clang -### -S -fprofile-instr-generate %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE %s // RUN: %clang -### -S -fprofile-generate=/some/dir %s 2>&1 | FileCheck -check-prefix=CHECK-PROFILE-GENERATE-DIR %s @@ -212,7 +222,6 @@ // RUN: -fdefer-pop -fno-defer-pop \ // RUN: -fprefetch-loop-arrays -fno-prefetch-loop-arrays \ // RUN: -fprofile-correction -fno-profile-correction \ -// RUN: -fprofile-dir=bar \ // RUN: -fprofile-values -fno-profile-values \ // RUN: -frounding-math -fno-rounding-math \ // RUN: -fsee -fno-see \ @@ -290,7 +299,6 @@ // RUN: -fkeep-inline-functions \ // RUN: -fno-keep-inline-functions \ // RUN: -freorder-blocks \ -// RUN: -fprofile-dir=/rand/dir \ // RUN: -falign-functions \ // RUN: -falign-functions=1 \ // RUN: -ffloat-store \ @@ -357,7 +365,6 @@ // CHECK-WARNING-DAG: optimization flag '-fkeep-inline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-fno-keep-inline-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-freorder-blocks' is not supported -// CHECK-WARNING-DAG: optimization flag '-fprofile-dir=/rand/dir' is not supported // CHECK-WARNING-DAG: optimization flag '-falign-functions' is not supported // CHECK-WARNING-DAG: optimization flag '-falign-functions=1' is not supported // CHECK-WARNING-DAG: optimization flag '-ffloat-store' is not supported Modified: cfe/trunk/test/Driver/coverage_no_integrated_as.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/coverage_no_integrated_as.c?rev=280306&r1=280305&r2=280306&view=diff ============================================================================== --- cfe/trunk/test/Driver/coverage_no_integrated_as.c (original) +++ cfe/trunk/test/Driver/coverage_no_integrated_as.c Wed Aug 31 18:04:32 2016 @@ -17,7 +17,7 @@ // RUN: %clang -### -c -fprofile-arcs -no-integrated-as %s -o foo/bar.o 2>&1 | FileCheck -check-prefix=CHECK-GCNO-LOCATION-REL-PATH %s -// CHECK-GCNO-DEFAULT-LOCATION: "-coverage-file" "{{.*}}{{/|\\\\}}coverage_no_integrated_as.c" -// CHECK-GCNO-DEFAULT-LOCATION-NOT: "-coverage-file" "/tmp/{{.*}}/coverage_no_integrated_as.c" -// CHECK-GCNO-LOCATION: "-coverage-file" "{{.*}}/foo/bar.o" -// CHECK-GCNO-LOCATION-REL-PATH: "-coverage-file" "{{.*}}{{/|\\\\}}foo/bar.o" +// CHECK-GCNO-DEFAULT-LOCATION: "-coverage-notes-file" "{{.*}}{{/|\\\\}}coverage_no_integrated_as.c" +// CHECK-GCNO-DEFAULT-LOCATION-NOT: "-coverage-notes-file" "/tmp/{{.*}}/coverage_no_integrated_as.c" +// CHECK-GCNO-LOCATION: "-coverage-notes-file" "{{.*}}/foo/bar.gcno" +// CHECK-GCNO-LOCATION-REL-PATH: "-coverage-notes-file" "{{.*}}{{/|\\\\}}foo/bar.gcno" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits