[clang] b836f96 - [Coverage] Support -fprofile-list for cold function coverage (#136333)

via cfe-commits cfe-commits at lists.llvm.org
Thu May 8 10:51:42 PDT 2025


Author: Lei Wang
Date: 2025-05-08T10:51:38-07:00
New Revision: b836f96b8f51daa76f6387de364603db0fe553a7

URL: https://github.com/llvm/llvm-project/commit/b836f96b8f51daa76f6387de364603db0fe553a7
DIFF: https://github.com/llvm/llvm-project/commit/b836f96b8f51daa76f6387de364603db0fe553a7.diff

LOG: [Coverage] Support -fprofile-list for cold function coverage (#136333)

Add a new instrumentation section type `[sample-coldcov]` to
support`-fprofile-list` for sample pgo based cold function coverage.
Note that the current cold function coverage is based on sampling PGO
pipeline, which is incompatible with the existing [llvm] option(see
[PGOOptions](https://github.com/llvm/llvm-project/blob/main/llvm/include/llvm/Support/PGOOptions.h#L27-L43)),
so we can't reuse the IR-PGO(-fprofile-instrument=llvm) flag.

Added: 
    

Modified: 
    clang/docs/UsersManual.rst
    clang/include/clang/Basic/CodeGenOptions.def
    clang/include/clang/Basic/CodeGenOptions.h
    clang/include/clang/Driver/Options.td
    clang/lib/Basic/ProfileList.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/test/CodeGen/profile-filter.c
    clang/test/Driver/fprofile-generate-cold-function-coverage.c

Removed: 
    


################################################################################
diff  --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 6c2053e01da8b..6f804a10748d8 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -3394,9 +3394,9 @@ This can be done using the ``-fprofile-list`` option.
 
     $ clang++ -O2 -fprofile-instr-generate -fcoverage-mapping -fprofile-list=fun.list -fprofile-list=code.list code.cc -o code
 
-Supported sections are ``[clang]``, ``[llvm]``, and ``[csllvm]`` representing
-clang PGO, IRPGO, and CSIRPGO, respectively. Supported prefixes are ``function``
-and ``source``. Supported categories are ``allow``, ``skip``, and ``forbid``.
+Supported sections are ``[clang]``, ``[llvm]``, ``[csllvm]``, and ``[sample-coldcov]`` representing
+clang PGO, IRPGO, CSIRPGO and sample PGO based cold function coverage, respectively. Supported prefixes 
+are ``function`` and ``source``. Supported categories are ``allow``, ``skip``, and ``forbid``.
 ``skip`` adds the ``skipprofile`` attribute while ``forbid`` adds the
 ``noprofile`` attribute to the appropriate function. Use
 ``default:<allow|skip|forbid>`` to specify the default category.

diff  --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 452b1e325afb2..40140cc135d89 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -223,7 +223,7 @@ AFFECTING_VALUE_CODEGENOPT(OptimizeSize, 2, 0) ///< If -Os (==1) or -Oz (==2) is
 CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic
 CODEGENOPT(ContinuousProfileSync, 1, 0) ///< Enable continuous instrumentation profiling
 /// Choose profile instrumenation kind or no instrumentation.
-ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, ProfileNone)
+ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 4, ProfileNone)
 /// Choose profile kind for PGO use compilation.
 ENUM_CODEGENOPT(ProfileUse, ProfileInstrKind, 2, ProfileNone)
 /// Partition functions into N groups and select only functions in group i to be

diff  --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h
index e3fa6a55e7608..e716b59a119fc 100644
--- a/clang/include/clang/Basic/CodeGenOptions.h
+++ b/clang/include/clang/Basic/CodeGenOptions.h
@@ -86,6 +86,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
                        // to use with PGO.
     ProfileIRInstr,    // IR level PGO instrumentation in LLVM.
     ProfileCSIRInstr, // IR level PGO context sensitive instrumentation in LLVM.
+    ProfileIRSampleColdCov, // IR level sample pgo based cold function coverage
+                            // instrumentation in LLVM.
   };
 
   enum EmbedBitcodeKind {

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index c8bd81bdf1e43..a3bbf4c154cb1 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -7733,9 +7733,9 @@ def fpatchable_function_entry_section_EQ
       HelpText<"Use Section instead of __patchable_function_entries">,
       MarshallingInfoString<CodeGenOpts<"PatchableFunctionEntrySection">>;
 def fprofile_instrument_EQ : Joined<["-"], "fprofile-instrument=">,
-    HelpText<"Enable PGO instrumentation">, Values<"none,clang,llvm,csllvm">,
+    HelpText<"Enable PGO instrumentation">, Values<"none,clang,llvm,csllvm,sample-coldcov">,
     NormalizedValuesScope<"CodeGenOptions">,
-    NormalizedValues<["ProfileNone", "ProfileClangInstr", "ProfileIRInstr", "ProfileCSIRInstr"]>,
+    NormalizedValues<["ProfileNone", "ProfileClangInstr", "ProfileIRInstr", "ProfileCSIRInstr", "ProfileIRSampleColdCov"]>,
     MarshallingInfoEnum<CodeGenOpts<"ProfileInstr">, "ProfileNone">;
 def fprofile_instrument_path_EQ : Joined<["-"], "fprofile-instrument-path=">,
     HelpText<"Generate instrumented code to collect execution counts into "

diff  --git a/clang/lib/Basic/ProfileList.cpp b/clang/lib/Basic/ProfileList.cpp
index 8fa16e2eb069a..01b8d7a073432 100644
--- a/clang/lib/Basic/ProfileList.cpp
+++ b/clang/lib/Basic/ProfileList.cpp
@@ -81,6 +81,8 @@ static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) {
     return "llvm";
   case CodeGenOptions::ProfileCSIRInstr:
     return "csllvm";
+  case CodeGenOptions::ProfileIRSampleColdCov:
+    return "sample-coldcov";
   }
   llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum");
 }

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index f87549baff5e1..415c699f4eb6a 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -628,6 +628,7 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
     CmdArgs.push_back("--pgo-instrument-cold-function-only");
     CmdArgs.push_back("-mllvm");
     CmdArgs.push_back("--pgo-function-entry-coverage");
+    CmdArgs.push_back("-fprofile-instrument=sample-coldcov");
   }
 
   if (auto *A = Args.getLastArg(options::OPT_ftemporal_profile)) {

diff  --git a/clang/test/CodeGen/profile-filter.c b/clang/test/CodeGen/profile-filter.c
index e33e4a0a60b3d..cc26e2b37d2b8 100644
--- a/clang/test/CodeGen/profile-filter.c
+++ b/clang/test/CodeGen/profile-filter.c
@@ -1,20 +1,37 @@
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm %s -o - | FileCheck %s
+// RUN: rm -rf %t && split-file %s %t
 
-// RUN: echo "fun:test1" > %t-func.list
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fprofile-list=%t-func.list -emit-llvm %s -o - | FileCheck %s --check-prefix=FUNC
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm %t/main.c -o - | FileCheck %s
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fprofile-list=%t/func.list -emit-llvm %t/main.c -o - | FileCheck %s --check-prefix=FUNC
 
-// RUN: echo "src:%s" | sed -e 's/\\/\\\\/g' > %t-file.list
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fprofile-list=%t-file.list -emit-llvm %s -o - | FileCheck %s --check-prefix=FILE
+// RUN: echo "src:%t/main.c" | sed -e 's/\\/\\\\/g' > %t-file.list
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fprofile-list=%t-file.list -emit-llvm %t/main.c -o - | FileCheck %s --check-prefix=FILE
+// RUN: %clang_cc1 -fprofile-instrument=llvm -fprofile-list=%t/section.list -emit-llvm %t/main.c -o - | FileCheck %s --check-prefix=SECTION
+// RUN: %clang_cc1 -fprofile-instrument=sample-coldcov -fprofile-list=%t/cold-func.list -emit-llvm %t/main.c -o - | FileCheck %s --check-prefix=COLDCOV 
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fprofile-list=%t/exclude.list -emit-llvm %t/main.c -o - | FileCheck %s --check-prefix=EXCLUDE
+// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fprofile-list=%t/exclude-only.list -emit-llvm %t/main.c -o - | FileCheck %s --check-prefix=EXCLUDE
 
-// RUN: echo -e "[clang]\nfun:test1\n[llvm]\nfun:test2" > %t-section.list
-// RUN: %clang_cc1 -fprofile-instrument=llvm -fprofile-list=%t-section.list -emit-llvm %s -o - | FileCheck %s --check-prefix=SECTION
+//--- func.list
+fun:test1
 
-// RUN: echo -e "fun:test*\n!fun:test1" > %t-exclude.list
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fprofile-list=%t-exclude.list -emit-llvm %s -o - | FileCheck %s --check-prefix=EXCLUDE
+//--- section.list
+[clang]
+fun:test1
+[llvm]
+fun:test2
 
-// RUN: echo "!fun:test1" > %t-exclude-only.list
-// RUN: %clang_cc1 -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -fprofile-list=%t-exclude-only.list -emit-llvm %s -o - | FileCheck %s --check-prefix=EXCLUDE
+//--- cold-func.list
+[sample-coldcov]
+fun:test*
+!fun:test2
 
+//--- exclude.list
+fun:test*
+!fun:test1
+
+//--- exclude-only.list
+!fun:test1
+
+//--- main.c
 unsigned i;
 
 // CHECK: test1
@@ -36,6 +53,8 @@ unsigned i;
 // SECTION: @test1
 // EXCLUDE: noprofile
 // EXCLUDE: @test1
+// COLDCOV-NOT: noprofile
+// COLDCOV: @test1
 unsigned test1(void) {
   // CHECK: %pgocount = load i64, ptr @__profc_{{_?}}test1
   // FUNC: %pgocount = load i64, ptr @__profc_{{_?}}test1
@@ -55,6 +74,8 @@ unsigned test1(void) {
 // SECTION: @test2
 // EXCLUDE-NOT: noprofile
 // EXCLUDE: @test2
+// COLDCOV: noprofile
+// COLDCOV: @test2
 unsigned test2(void) {
   // CHECK: %pgocount = load i64, ptr @__profc_{{_?}}test2
   // FUNC-NOT: %pgocount = load i64, ptr @__profc_{{_?}}test2

diff  --git a/clang/test/Driver/fprofile-generate-cold-function-coverage.c b/clang/test/Driver/fprofile-generate-cold-function-coverage.c
index 135acf2e736f7..b42ed26329c02 100644
--- a/clang/test/Driver/fprofile-generate-cold-function-coverage.c
+++ b/clang/test/Driver/fprofile-generate-cold-function-coverage.c
@@ -2,7 +2,7 @@
 // CHECK: "--instrument-cold-function-only-path=default_%m.profraw" 
 // CHECK: "--pgo-instrument-cold-function-only"
 // CHECK: "--pgo-function-entry-coverage"
-// CHECK-NOT:  "-fprofile-instrument"
+// CHECK:  "-fprofile-instrument=sample-coldcov"
 // CHECK-NOT:  "-fprofile-instrument-path=
 
 // RUN: %clang -### -c -fprofile-generate-cold-function-coverage=dir %s 2>&1 | FileCheck %s --check-prefix=CHECK-EQ


        


More information about the cfe-commits mailing list