From af58684f272046f293a9f469f03d23bd2b138349 Mon Sep 17 00:00:00 2001 From: Ellis Hoag Date: Thu, 14 Jul 2022 11:40:53 -0700 Subject: [PATCH] [InstrProf] Add options to profile function groups Add two options, `-fprofile-function-groups=N` and `-fprofile-selected-function-group=i` used to partition functions into `N` groups and only instrument the functions in group `i`. Similar options were added to xray in https://reviews.llvm.org/D87953 and the goal is the same; to reduce instrumented size overhead by spreading the overhead across multiple builds. Raw profiles from different groups can be added like normal using the `llvm-profdata merge` command. Reviewed By: ianlevesque Differential Revision: https://reviews.llvm.org/D129594 --- clang/docs/ClangCommandLineReference.rst | 4 +++ clang/docs/UsersManual.rst | 26 ++++++++++++++++++ clang/include/clang/Basic/CodeGenOptions.def | 4 +++ clang/include/clang/Driver/Options.td | 9 +++++++ clang/lib/CodeGen/CodeGenFunction.cpp | 2 +- clang/lib/CodeGen/CodeGenModule.cpp | 19 +++++++++++-- clang/lib/CodeGen/CodeGenModule.h | 12 ++++++--- clang/lib/Driver/ToolChains/Clang.cpp | 21 +++++++++++++++ clang/test/CodeGen/profile-function-groups.c | 24 +++++++++++++++++ compiler-rt/test/profile/instrprof-groups.c | 28 ++++++++++++++++++++ 10 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 clang/test/CodeGen/profile-function-groups.c create mode 100644 compiler-rt/test/profile/instrprof-groups.c diff --git a/clang/docs/ClangCommandLineReference.rst b/clang/docs/ClangCommandLineReference.rst index 776b84da9657..216872b60cdc 100644 --- a/clang/docs/ClangCommandLineReference.rst +++ b/clang/docs/ClangCommandLineReference.rst @@ -2329,6 +2329,10 @@ Use instrumentation data for profile-guided optimization Filename defining the list of functions/files to instrument +.. option:: -fprofile-function-groups=, -fprofile-selected-function-group= + +Partition functions into groups and select only functions in group to be instrumented + .. option:: -fprofile-remapping-file= Use the remappings described in to match the profile data against names in the program diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst index e12dc72407b1..c2767d65adbf 100644 --- a/clang/docs/UsersManual.rst +++ b/clang/docs/UsersManual.rst @@ -2513,6 +2513,32 @@ When the file contains only excludes, all files and functions except for the excluded ones will be instrumented. Otherwise, only the files and functions specified will be instrumented. +Instrument function groups +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Sometimes it is desirable to minimize the size overhead of instrumented +binaries. One way to do this is to partition functions into groups and only +instrument functions in a specified group. This can be done using the +`-fprofile-function-groups` and `-fprofile-selected-function-group` options. + +.. option:: -fprofile-function-groups=, -fprofile-selected-function-group= + + The following uses 3 groups + + .. code-block:: console + + $ clang++ -Oz -fprofile-generate=group_0/ -fprofile-function-groups=3 -fprofile-selected-function-group=0 code.cc -o code.0 + $ clang++ -Oz -fprofile-generate=group_1/ -fprofile-function-groups=3 -fprofile-selected-function-group=1 code.cc -o code.1 + $ clang++ -Oz -fprofile-generate=group_2/ -fprofile-function-groups=3 -fprofile-selected-function-group=2 code.cc -o code.2 + + After collecting raw profiles from the three binaries, they can be merged into + a single profile like normal. + + .. code-block:: console + + $ llvm-profdata merge -output=code.profdata group_*/*.profraw + + Profile remapping ^^^^^^^^^^^^^^^^^ diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index b1d394edd04a..ef7957979dcc 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -213,6 +213,10 @@ CODEGENOPT(AtomicProfileUpdate , 1, 0) ///< Set -fprofile-update=atomic ENUM_CODEGENOPT(ProfileInstr, ProfileInstrKind, 2, 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 +/// instrumented. Selected group numbers can be 0 to N-1 inclusive. +VALUE_CODEGENOPT(ProfileTotalFunctionGroups, 32, 1) +VALUE_CODEGENOPT(ProfileSelectedFunctionGroup, 32, 0) CODEGENOPT(CoverageMapping , 1, 0) ///< Generate coverage mapping regions to ///< enable code coverage analysis. CODEGENOPT(DumpCoverageMapping , 1, 0) ///< Dump the generated coverage mapping diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 532d7780c529..404effb4e1de 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1333,6 +1333,15 @@ def fprofile_list_EQ : Joined<["-"], "fprofile-list=">, Group, Flags<[CC1Option, CoreOption]>, HelpText<"Filename defining the list of functions/files to instrument">, MarshallingInfoStringVector>; +def fprofile_function_groups : Joined<["-"], "fprofile-function-groups=">, + Group, Flags<[CC1Option]>, MetaVarName<"">, + HelpText<"Partition functions into N groups and select only functions in group i to be instrumented using -fprofile-selected-function-group">, + MarshallingInfoInt, "1">; +def fprofile_selected_function_group : + Joined<["-"], "fprofile-selected-function-group=">, Group, + Flags<[CC1Option]>, MetaVarName<"">, + HelpText<"Partition functions into N groups using -fprofile-function-groups and select only functions in group i to be instrumented. The valid range is 0 to N-1 inclusive">, + MarshallingInfoInt>; def fswift_async_fp_EQ : Joined<["-"], "fswift-async-fp=">, Group, Flags<[CC1Option, CC1AsOption, CoreOption]>, MetaVarName<"