llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang-driver Author: Nicolas Qiu Guichard (nicolas-guichard) <details> <summary>Changes</summary> GCC has a -fprofile-abs-path option to use absolute paths to source files in GCNO files. Citing GCC's documentation: > Automatically convert relative source file names to absolute path names in the .gcno files. This allows gcov to find the correct sources in projects where compilations occur with different working directories. This is particularly useful when doing unity builds where a generated source file includes many original source files, as otherwise the GCNO refers to the original source files by relative paths. When the -fprofile-abs-path flag is passed to clang/clang++, the new -coverage-notes-abs-paths flag is passed to cc1, which calls vfs::FileSystem::makeAbsolute to get the absolute path. getFilename is moved to a member function in GCOVProfiler so that it can access the GCOVOptions. This also removes the need for its VFS argument and the getVirtualFileSystem member function. --- Full diff: https://github.com/llvm/llvm-project/pull/230077.diff 8 Files Affected: - (modified) clang/include/clang/Basic/CodeGenOptions.h (+3) - (modified) clang/include/clang/Options/Options.td (+6) - (modified) clang/lib/CodeGen/BackendUtil.cpp (+1) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+6) - (added) clang/test/CodeGen/code-coverage-absolute-paths.c (+13) - (modified) clang/test/Driver/coverage.c (+8) - (modified) llvm/include/llvm/Transforms/Utils/Instrumentation.h (+3) - (modified) llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp (+18-11) ``````````diff diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index c3a23415c922a..99a76b4edbf0e 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -292,6 +292,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The filename with path we use for coverage notes files. std::string CoverageNotesFile; + /// Whether to force absolute paths in coverage notes files. + bool UseAbsolutePathsInNotesFile; + /// Regexes separated by a semi-colon to filter the files to instrument. std::string ProfileFilterFiles; diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 88fbd72f4eae5..82aba4d4da4ff 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -2020,6 +2020,10 @@ def fno_profile_use : Flag<["-"], "fno-profile-use">, def ftest_coverage : Flag<["-"], "ftest-coverage">, Group<f_Group>, HelpText<"Produce gcov notes files (*.gcno)">; def fno_test_coverage : Flag<["-"], "fno-test-coverage">, Group<f_Group>; +def fprofile_abs_path : Flag<["-"], "fprofile-abs-path">, + Group<f_Group>, Visibility<[ClangOption, CLOption]>, + HelpText<"Use absolute paths in gcov notes files (*.gcno)">; +def fno_profile_abs_path : Flag<["-"], "fno-profile-abs-path">, Group<f_Group>; def fprofile_arcs : Flag<["-"], "fprofile-arcs">, Group<f_Group>, HelpText<"Instrument code to produce gcov data files (*.gcda)">; def fno_profile_arcs : Flag<["-"], "fno-profile-arcs">, Group<f_Group>; @@ -8246,6 +8250,8 @@ def : Joined<["-"], "coverage-data-file=">, MarshallingInfoString<CodeGenOpts<"CoverageDataFile">>; def : Joined<["-"], "coverage-notes-file=">, MarshallingInfoString<CodeGenOpts<"CoverageNotesFile">>; +def : Joined<["-"], "coverage-notes-abs-paths">, + MarshallingInfoFlag<CodeGenOpts<"UseAbsolutePathsInNotesFile">>; def coverage_version_EQ : Joined<["-"], "coverage-version=">, HelpText<"Four-byte version string for gcov files.">; def dump_coverage_mapping : Flag<["-"], "dump-coverage-mapping">, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index c754c75aa59de..6ba8ebd2bc4d8 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -527,6 +527,7 @@ getGCOVOptions(const CodeGenOptions &CodeGenOpts, const LangOptions &LangOpts) { // LLVM's -default-gcov-version flag is set to something invalid. GCOVOptions Options; Options.EmitNotes = !CodeGenOpts.CoverageNotesFile.empty(); + Options.UseAbsolutePathsInNotes = CodeGenOpts.UseAbsolutePathsInNotesFile; Options.EmitData = !CodeGenOpts.CoverageDataFile.empty(); llvm::copy(CodeGenOpts.CoverageVersion, std::begin(Options.Version)); Options.NoRedZone = CodeGenOpts.DisableRedZone; diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 63e7c42549d3f..df29f8d9c98f0 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -688,6 +688,12 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C, if (EmitCovNotes) { CmdArgs.push_back( Args.MakeArgString("-coverage-notes-file=" + CoverageFilename)); + + bool UseAbsolutePathsInNotes = + Args.hasFlag(options::OPT_fprofile_abs_path, + options::OPT_fno_profile_abs_path, false); + if (UseAbsolutePathsInNotes) + CmdArgs.push_back(Args.MakeArgString("-coverage-notes-abs-paths")); } if (EmitCovData) { diff --git a/clang/test/CodeGen/code-coverage-absolute-paths.c b/clang/test/CodeGen/code-coverage-absolute-paths.c new file mode 100644 index 0000000000000..839fcda8774d5 --- /dev/null +++ b/clang/test/CodeGen/code-coverage-absolute-paths.c @@ -0,0 +1,13 @@ +// RUN: rm -rf %t && mkdir %t +// RUN: cd %S + +// RUN: %clang_cc1 -emit-llvm-bc -o /dev/null -coverage-notes-file=%t/notes-relative.gcno %{s:basename} +// RUN: FileCheck --check-prefix=RELATIVE %s --input-file %t/notes-relative.gcno -DABSOLUTE_PATH=%s + +// RUN: %clang_cc1 -emit-llvm-bc -o /dev/null -coverage-notes-file=%t/notes-absolute.gcno -coverage-notes-abs-paths %{s:basename} +// RUN: FileCheck --check-prefix=ABSOLUTE %s --input-file %t/notes-absolute.gcno -DABSOLUTE_PATH=%s + +void test() {} + +// RELATIVE-NOT: [[ABSOLUTE_PATH]] +// ABSOLUTE: [[ABSOLUTE_PATH]] diff --git a/clang/test/Driver/coverage.c b/clang/test/Driver/coverage.c index ab791ada2d351..4aee8720470d4 100644 --- a/clang/test/Driver/coverage.c +++ b/clang/test/Driver/coverage.c @@ -32,6 +32,14 @@ // PROFILE-DIR: "-coverage-data-file=abc +/// Test -fprofile-abs-path +// RUN: %clang -### -S -ftest-coverage %s 2>&1 | FileCheck --check-prefix=NO-PROFILE-ABS-PATH %s +// RUN: %clang -### -S -fprofile-abs-path %s 2>&1 | FileCheck --check-prefix=NO-PROFILE-ABS-PATH %s +// RUN: %clang -### -S -ftest-coverage -fprofile-abs-path %s 2>&1 | FileCheck --check-prefix=PROFILE-ABS-PATH %s + +// NO-PROFILE-ABS-PATH-NOT: "-coverage-notes-abs-paths" +// PROFILE-ABS-PATH: "-coverage-notes-abs-paths" + /// These should only get passed if any of --coverage, -ftest-coverage, or /// -fprofile-arcs is passed. // RUN: %clang -### -c %s 2>&1 | FileCheck --check-prefix=NO-COV %s diff --git a/llvm/include/llvm/Transforms/Utils/Instrumentation.h b/llvm/include/llvm/Transforms/Utils/Instrumentation.h index 8405245b2bc0a..e8279ae58e2cb 100644 --- a/llvm/include/llvm/Transforms/Utils/Instrumentation.h +++ b/llvm/include/llvm/Transforms/Utils/Instrumentation.h @@ -67,6 +67,9 @@ struct GCOVOptions { // Specify whether to emit .gcno files. bool EmitNotes; + // Specify whether to force absolute paths in coverage notes files. + bool UseAbsolutePathsInNotes; + // Specify whether to modify the program to emit .gcda files when run. bool EmitData; diff --git a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp index 78b5dcf21cd03..0c96adddc72cd 100644 --- a/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/GCOVProfiling.cpp @@ -76,6 +76,7 @@ static unsigned wordsOfString(StringRef s) { GCOVOptions GCOVOptions::getDefault() { GCOVOptions Options; Options.EmitNotes = true; + Options.UseAbsolutePathsInNotes = false; Options.EmitData = true; Options.NoRedZone = false; Options.Atomic = AtomicCounter; @@ -113,7 +114,7 @@ class GCOVProfiler { os->write_zeros(4 - s.size() % 4); } void writeBytes(const char *Bytes, int Size) { os->write(Bytes, Size); } - vfs::FileSystem &getVirtualFileSystem() const { return VFS; } + SmallString<128> getFilename(const DIScope *SP); private: // Create the .gcno files for the Module based on DebugInfo. @@ -216,16 +217,22 @@ static StringRef getFunctionName(const DISubprogram *SP) { /// Extract a filename for a DIScope. /// -/// Prefer relative paths in the coverage notes. Clang also may split -/// up absolute paths into a directory and filename component. When -/// the relative path doesn't exist, reconstruct the absolute path. -static SmallString<128> getFilename(const DIScope *SP, vfs::FileSystem &VFS) { +/// Unless -fprofile-abs-path has been passed, prefer relative paths in the +/// coverage notes. Clang also may split up absolute paths into a directory and +/// filename component. When the relative path doesn't exist, reconstruct the +/// absolute path. +SmallString<128> GCOVProfiler::getFilename(const DIScope *SP) { SmallString<128> Path; StringRef RelPath = SP->getFilename(); - if (VFS.exists(RelPath)) + if (VFS.exists(RelPath)) { Path = RelPath; - else + if (Options.UseAbsolutePathsInNotes) { + VFS.makeAbsolute(Path); + sys::path::remove_dots(Path, true); + } + } else { sys::path::append(Path, SP->getDirectory(), SP->getFilename()); + } return Path; } @@ -362,7 +369,7 @@ namespace { void writeOut(uint32_t CfgChecksum) { write(GCOV_TAG_FUNCTION); - SmallString<128> Filename = getFilename(SP, P->getVirtualFileSystem()); + SmallString<128> Filename = P->getFilename(SP); uint32_t BlockLen = 3 + wordsOfString(getFunctionName(SP)); BlockLen += 1 + wordsOfString(Filename) + 4; @@ -460,7 +467,7 @@ bool GCOVProfiler::isFunctionInstrumented(const Function &F) { if (FilterRe.empty() && ExcludeRe.empty()) { return true; } - SmallString<128> Filename = getFilename(F.getSubprogram(), VFS); + SmallString<128> Filename = getFilename(F.getSubprogram()); auto It = InstrumentedFiles.find(Filename); if (It != InstrumentedFiles.end()) { return It->second; @@ -795,7 +802,7 @@ bool GCOVProfiler::emitProfileNotes( // Add the function line number to the lines of the entry block // to have a counter for the function definition. uint32_t Line = SP->getLine(); - auto Filename = getFilename(SP, VFS); + auto Filename = getFilename(SP); BranchProbabilityInfo *BPI = GetBPI(F); BlockFrequencyInfo *BFI = GetBFI(F); @@ -887,7 +894,7 @@ bool GCOVProfiler::emitProfileNotes( if (SP != getDISubprogram(Scope)) continue; - GCOVLines &Lines = Block.getFile(getFilename(Loc->getScope(), VFS)); + GCOVLines &Lines = Block.getFile(getFilename(Loc->getScope())); Lines.addLine(Loc.getLine()); } Line = 0; `````````` </details> https://github.com/llvm/llvm-project/pull/230077 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
