https://github.com/wlei-llvm updated https://github.com/llvm/llvm-project/pull/136333
>From 3d770595ce6568148ddfe2596f1a53dfc2ee751f Mon Sep 17 00:00:00 2001 From: wlei <w...@fb.com> Date: Fri, 18 Apr 2025 10:37:30 -0700 Subject: [PATCH 1/2] [Inverge] Support -fprofile-list for cold function coveragege --- clang/docs/UsersManual.rst | 6 +++--- clang/include/clang/Basic/CodeGenOptions.def | 2 +- clang/include/clang/Basic/CodeGenOptions.h | 2 ++ clang/include/clang/Driver/Options.td | 4 ++-- clang/lib/Basic/ProfileList.cpp | 2 ++ clang/lib/Driver/ToolChains/Clang.cpp | 1 + clang/test/CodeGen/profile-filter.c | 7 +++++++ .../test/Driver/fprofile-generate-cold-function-coverage.c | 2 +- 8 files changed, 19 insertions(+), 7 deletions(-) diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index 69256527f40c9..47bd591d20a27 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 ``[coldcov]`` representing +clang PGO, IRPGO, CSIRPGO and 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 c5990fb248689..fced5d7dcf6b7 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 e39a73bdb13ac..60001cfc62218 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. + ProfileIRColdCov, // IR level 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 830d3459a1320..a76f90efc4a51 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -7679,9 +7679,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,coldcov">, NormalizedValuesScope<"CodeGenOptions">, - NormalizedValues<["ProfileNone", "ProfileClangInstr", "ProfileIRInstr", "ProfileCSIRInstr"]>, + NormalizedValues<["ProfileNone", "ProfileClangInstr", "ProfileIRInstr", "ProfileCSIRInstr", "ProfileIRColdCov"]>, 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..0991867e1ac3a 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::ProfileIRColdCov: + return "coldcov"; } llvm_unreachable("Unhandled CodeGenOptions::ProfileInstrKind enum"); } diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 67a800a643cbe..d9e7a6561856d 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=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..d62871d95c393 100644 --- a/clang/test/CodeGen/profile-filter.c +++ b/clang/test/CodeGen/profile-filter.c @@ -9,6 +9,9 @@ // 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 +// RUN: echo -e "[coldcov]\nfun:test*\n!fun:test2" > %t-cold-func.list +// RUN: %clang_cc1 -fprofile-instrument=coldcov -fprofile-list=%t-cold-func.list -emit-llvm %s -o - | FileCheck %s --check-prefix=COLDCOV + // 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 @@ -36,6 +39,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 +60,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..834150415e28d 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=coldcov" // CHECK-NOT: "-fprofile-instrument-path= // RUN: %clang -### -c -fprofile-generate-cold-function-coverage=dir %s 2>&1 | FileCheck %s --check-prefix=CHECK-EQ >From 6089e4f6d2af087da547d1ca1ecf0e042f7df754 Mon Sep 17 00:00:00 2001 From: wlei <w...@fb.com> Date: Wed, 7 May 2025 15:53:53 -0700 Subject: [PATCH 2/2] add sample- prefix and improve test --- clang/docs/UsersManual.rst | 6 ++-- clang/include/clang/Basic/CodeGenOptions.h | 4 +-- clang/include/clang/Driver/Options.td | 4 +-- clang/lib/Basic/ProfileList.cpp | 4 +-- clang/lib/Driver/ToolChains/Clang.cpp | 2 +- clang/test/CodeGen/profile-filter.c | 40 +++++++++++++++------- 6 files changed, 37 insertions(+), 23 deletions(-) diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index e7380b5f0e5f6..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]``, ``[csllvm]``, and ``[coldcov]`` representing -clang PGO, IRPGO, CSIRPGO and cold function coverage, 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.h b/clang/include/clang/Basic/CodeGenOptions.h index 4ea5700d75c93..e716b59a119fc 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -86,8 +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. - ProfileIRColdCov, // IR level cold function coverage 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 36e439a328724..7e5fd2d2103a4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -7732,9 +7732,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,coldcov">, + HelpText<"Enable PGO instrumentation">, Values<"none,clang,llvm,csllvm,sample-coldcov">, NormalizedValuesScope<"CodeGenOptions">, - NormalizedValues<["ProfileNone", "ProfileClangInstr", "ProfileIRInstr", "ProfileCSIRInstr", "ProfileIRColdCov"]>, + 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 0991867e1ac3a..01b8d7a073432 100644 --- a/clang/lib/Basic/ProfileList.cpp +++ b/clang/lib/Basic/ProfileList.cpp @@ -81,8 +81,8 @@ static StringRef getSectionName(CodeGenOptions::ProfileInstrKind Kind) { return "llvm"; case CodeGenOptions::ProfileCSIRInstr: return "csllvm"; - case CodeGenOptions::ProfileIRColdCov: - return "coldcov"; + 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 bc540566e7ccf..415c699f4eb6a 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -628,7 +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=coldcov"); + 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 d62871d95c393..cc26e2b37d2b8 100644 --- a/clang/test/CodeGen/profile-filter.c +++ b/clang/test/CodeGen/profile-filter.c @@ -1,23 +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 "[coldcov]\nfun:test*\n!fun:test2" > %t-cold-func.list -// RUN: %clang_cc1 -fprofile-instrument=coldcov -fprofile-list=%t-cold-func.list -emit-llvm %s -o - | FileCheck %s --check-prefix=COLDCOV +//--- section.list +[clang] +fun:test1 +[llvm] +fun:test2 -// 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 +//--- cold-func.list +[sample-coldcov] +fun:test* +!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 +//--- exclude.list +fun:test* +!fun:test1 +//--- exclude-only.list +!fun:test1 + +//--- main.c unsigned i; // CHECK: test1 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits