Skip to content

[Coverage] Support -fprofile-list for cold function coverage #136333

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 8, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions clang/docs/UsersManual.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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 "
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Basic/ProfileList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
7 changes: 7 additions & 0 deletions clang/test/CodeGen/profile-filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// RUN: %clang_cc1 -fprofile-instrument=coldcov -fprofile-list=%t-cold-func.list -emit-llvm %s -o - | FileCheck %s --check-prefix=COLDCOV
// RUN: %clang_cc1 -fprofile-instrument=coldcov -fprofile-list=%t-cold-func.list -emit-llvm %s -o - | FileCheck %s --check-prefix=COLDCOV --implicit-check-not=noprofile

Can we do this to avoid the CHECK-NOT lines?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is also a explicit check noprofile ("// COLDCOV: noprofile"), so I guess implicit-check-not doesn't work here.


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know the rest of the test uses echo, but it should be simple enough to use split-file for at least this case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

improved the test with split-file, thanks!

// 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

Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading