[clang] [InstrProf] Add frontend temporal profiling flag (PR #122385)

Ellis Hoag via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 9 19:09:38 PST 2025


https://github.com/ellishg updated https://github.com/llvm/llvm-project/pull/122385

>From 28e1eb2d0383bf417f8f769f6964eacb02a45477 Mon Sep 17 00:00:00 2001
From: Ellis Hoag <ellis.sparky.hoag at gmail.com>
Date: Thu, 9 Jan 2025 14:51:13 -0800
Subject: [PATCH 1/2] [InstrProf] Add frontent temporal profiling flag

---
 clang/include/clang/Driver/Options.td                 |  5 ++++-
 clang/lib/Driver/ToolChains/Clang.cpp                 | 11 ++++++++++-
 clang/test/Driver/clang_f_opts.c                      |  2 +-
 .../fprofile-generate-temporal-instrumentation.c      |  7 +++++++
 4 files changed, 22 insertions(+), 3 deletions(-)
 create mode 100644 clang/test/Driver/fprofile-generate-temporal-instrumentation.c

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 52823430919de4..7df5141499552c 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1796,6 +1796,9 @@ def fprofile_generate_cold_function_coverage : Flag<["-"], "fprofile-generate-co
 def fprofile_generate_cold_function_coverage_EQ : Joined<["-"], "fprofile-generate-cold-function-coverage=">,
     Group<f_Group>, Visibility<[ClangOption, CLOption]>, MetaVarName<"<directory>">,
     HelpText<"Generate instrumented code to collect coverage info for cold functions into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
+def fprofile_generate_temporal_instrumentation : Flag<["-"], "fprofile-generate-temporal-instrumentation">,
+    Group<f_Group>, Visibility<[ClangOption, CLOption]>,
+    HelpText<"Generate instrumented code to collect temporal information. See this RFC for details: https://discourse.llvm.org/t/rfc-temporal-profiling-extension-for-irpgo/68068">;
 def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
     Group<f_Group>, Visibility<[ClangOption, CLOption]>,
     HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
@@ -1891,7 +1894,7 @@ defm pseudo_probe_for_profiling : BoolFOption<"pseudo-probe-for-profiling",
           " pseudo probes for sample profiling">>;
 def forder_file_instrumentation : Flag<["-"], "forder-file-instrumentation">,
     Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
-    HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var). Deprecated, please use temporal profiling.">;
+    HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var). Deprecated, please use -fprofile-generate-temporal-instrumentation">;
 def fprofile_list_EQ : Joined<["-"], "fprofile-list=">,
     Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
     HelpText<"Filename defining the list of functions/files to instrument. "
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index a0002371da2f1b..a196bceba1f2d3 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -662,6 +662,15 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
     CmdArgs.push_back("--pgo-function-entry-coverage");
   }
 
+  if (auto *A = Args.getLastArg(
+          options::OPT_fprofile_generate_temporal_instrumentation)) {
+    if (!PGOGenerateArg && !CSPGOGenerateArg)
+      D.Diag(clang::diag::err_drv_argument_only_allowed_with)
+          << A->getSpelling() << "-fprofile-generate or -fcs-profile-generate";
+    CmdArgs.push_back("-mllvm");
+    CmdArgs.push_back("--pgo-temporal-instrumentation");
+  }
+
   Arg *PGOGenArg = nullptr;
   if (PGOGenerateArg) {
     assert(!CSPGOGenerateArg);
@@ -8050,7 +8059,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
           Args.getLastArg(options::OPT_forder_file_instrumentation)) {
     D.Diag(diag::warn_drv_deprecated_arg)
         << A->getAsString(Args) << /*hasReplacement=*/true
-        << "-mllvm -pgo-temporal-instrumentation";
+        << "-fprofile-generate-temporal-instrumentation";
     CmdArgs.push_back("-forder-file-instrumentation");
     // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is
     // on, we need to pass these flags as linker flags and that will be handled
diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index 2b72068eae1eeb..7448076cf367e5 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -424,7 +424,7 @@
 // CHECK-WARNING-DAG: optimization flag '-fno-devirtualize-speculatively' is not supported
 // CHECK-WARNING-DAG: the flag '-fslp-vectorize-aggressive' has been deprecated and will be ignored
 // CHECK-WARNING-DAG: the flag '-fno-slp-vectorize-aggressive' has been deprecated and will be ignored
-// CHECK-WARNING-DAG: argument '-forder-file-instrumentation' is deprecated, use '-mllvm -pgo-temporal-instrumentation' instead
+// CHECK-WARNING-DAG: argument '-forder-file-instrumentation' is deprecated, use '-fprofile-generate-temporal-instrumentation' instead
 
 // Test that we mute the warning on these
 // RUN: %clang -### -finline-limit=1000 -Wno-invalid-command-line-argument              \
diff --git a/clang/test/Driver/fprofile-generate-temporal-instrumentation.c b/clang/test/Driver/fprofile-generate-temporal-instrumentation.c
new file mode 100644
index 00000000000000..e4e5b5f49bcacf
--- /dev/null
+++ b/clang/test/Driver/fprofile-generate-temporal-instrumentation.c
@@ -0,0 +1,7 @@
+// RUN: %clang -### -c -fprofile-generate -fprofile-generate-temporal-instrumentation %s 2>&1 | FileCheck %s
+// RUN: %clang -### -c -fcs-profile-generate -fprofile-generate-temporal-instrumentation %s 2>&1 | FileCheck %s
+// RUN: not %clang -### -c -fprofile-generate-temporal-instrumentation %s 2>&1 | FileCheck %s --check-prefix=ERR
+
+// CHECK: "-mllvm" "--pgo-temporal-instrumentation"
+
+// ERR: '-fprofile-generate-temporal-instrumentation' only allowed with '-fprofile-generate or -fcs-profile-generate'

>From c71ba78b212465cf9200c557be2b714b4e163179 Mon Sep 17 00:00:00 2001
From: Ellis Hoag <ellis.sparky.hoag at gmail.com>
Date: Thu, 9 Jan 2025 19:09:18 -0800
Subject: [PATCH 2/2] Rename flag

---
 clang/docs/UsersManual.rst                    | 32 +++++++++++++++++++
 clang/include/clang/Driver/Options.td         |  6 ++--
 clang/lib/Driver/ToolChains/Clang.cpp         |  5 ++-
 clang/test/Driver/clang_f_opts.c              |  2 +-
 ...rofile-generate-temporal-instrumentation.c |  7 ----
 .../test/Driver/fprofile-generate-temporal.c  |  7 ++++
 6 files changed, 45 insertions(+), 14 deletions(-)
 delete mode 100644 clang/test/Driver/fprofile-generate-temporal-instrumentation.c
 create mode 100644 clang/test/Driver/fprofile-generate-temporal.c

diff --git a/clang/docs/UsersManual.rst b/clang/docs/UsersManual.rst
index 8af9f5be644a02..e53a74327dc8ce 100644
--- a/clang/docs/UsersManual.rst
+++ b/clang/docs/UsersManual.rst
@@ -3035,6 +3035,38 @@ indexed format, regardeless whether it is produced by frontend or the IR pass.
   overhead. ``prefer-atomic`` will be transformed to ``atomic`` when supported
   by the target, or ``single`` otherwise.
 
+.. option:: -fprofile-generate-temporal
+
+  Enables the temporal profiling extension for IRPGO to improve startup time by
+  reducing ``.text`` section page faults. To do this, we instrument function
+  timestamps to measure when each function is called for the first time and use
+  this data to generate a function order to improve startup.
+
+  The profile is generated as normal.
+
+  .. code-block:: console
+
+    $ clang++ -O2 -fprofile-generate -fprofile-generate-temporal code.cc -o code
+    $ ./code
+    $ llvm-profdata merge -o code.profdata yyy/zzz
+
+  Using the resulting profile, we can either generate a function order to pass
+  to the linker.
+
+  .. code-block:: console
+
+    $ llvm-profdata order code.profdata -o code.orderfile
+    $ clang++ -O2 -Wl,--symbol-ordering-file=code.orderfile code.cc -o code
+
+  Or it can be passed to the linker directly.
+
+  .. code-block:: console
+
+    $ clang++ -O2 -Wl,--irpgo-profile=code.profdata,--bp-startup-sort=function code.cc -o code
+
+  For more information, please read the RFC:
+  https://discourse.llvm.org/t/rfc-temporal-profiling-extension-for-irpgo/68068
+
 Fine Tuning Profile Collection
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 7df5141499552c..d6326f28c814d4 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1796,9 +1796,9 @@ def fprofile_generate_cold_function_coverage : Flag<["-"], "fprofile-generate-co
 def fprofile_generate_cold_function_coverage_EQ : Joined<["-"], "fprofile-generate-cold-function-coverage=">,
     Group<f_Group>, Visibility<[ClangOption, CLOption]>, MetaVarName<"<directory>">,
     HelpText<"Generate instrumented code to collect coverage info for cold functions into <directory>/default.profraw (overridden by LLVM_PROFILE_FILE env var)">;
-def fprofile_generate_temporal_instrumentation : Flag<["-"], "fprofile-generate-temporal-instrumentation">,
+def fprofile_generate_temporal : Flag<["-"], "fprofile-generate-temporal">,
     Group<f_Group>, Visibility<[ClangOption, CLOption]>,
-    HelpText<"Generate instrumented code to collect temporal information. See this RFC for details: https://discourse.llvm.org/t/rfc-temporal-profiling-extension-for-irpgo/68068">;
+    HelpText<"Generate instrumented code to collect temporal information">;
 def fprofile_instr_generate : Flag<["-"], "fprofile-instr-generate">,
     Group<f_Group>, Visibility<[ClangOption, CLOption]>,
     HelpText<"Generate instrumented code to collect execution counts into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var)">;
@@ -1894,7 +1894,7 @@ defm pseudo_probe_for_profiling : BoolFOption<"pseudo-probe-for-profiling",
           " pseudo probes for sample profiling">>;
 def forder_file_instrumentation : Flag<["-"], "forder-file-instrumentation">,
     Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
-    HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var). Deprecated, please use -fprofile-generate-temporal-instrumentation">;
+    HelpText<"Generate instrumented code to collect order file into default.profraw file (overridden by '=' form of option or LLVM_PROFILE_FILE env var). Deprecated, please use -fprofile-generate-temporal">;
 def fprofile_list_EQ : Joined<["-"], "fprofile-list=">,
     Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,
     HelpText<"Filename defining the list of functions/files to instrument. "
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index a196bceba1f2d3..dbda66a13c7034 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -662,8 +662,7 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, Compilation &C,
     CmdArgs.push_back("--pgo-function-entry-coverage");
   }
 
-  if (auto *A = Args.getLastArg(
-          options::OPT_fprofile_generate_temporal_instrumentation)) {
+  if (auto *A = Args.getLastArg(options::OPT_fprofile_generate_temporal)) {
     if (!PGOGenerateArg && !CSPGOGenerateArg)
       D.Diag(clang::diag::err_drv_argument_only_allowed_with)
           << A->getSpelling() << "-fprofile-generate or -fcs-profile-generate";
@@ -8059,7 +8058,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
           Args.getLastArg(options::OPT_forder_file_instrumentation)) {
     D.Diag(diag::warn_drv_deprecated_arg)
         << A->getAsString(Args) << /*hasReplacement=*/true
-        << "-fprofile-generate-temporal-instrumentation";
+        << "-fprofile-generate-temporal";
     CmdArgs.push_back("-forder-file-instrumentation");
     // Enable order file instrumentation when ThinLTO is not on. When ThinLTO is
     // on, we need to pass these flags as linker flags and that will be handled
diff --git a/clang/test/Driver/clang_f_opts.c b/clang/test/Driver/clang_f_opts.c
index 7448076cf367e5..60ae8d28644bf4 100644
--- a/clang/test/Driver/clang_f_opts.c
+++ b/clang/test/Driver/clang_f_opts.c
@@ -424,7 +424,7 @@
 // CHECK-WARNING-DAG: optimization flag '-fno-devirtualize-speculatively' is not supported
 // CHECK-WARNING-DAG: the flag '-fslp-vectorize-aggressive' has been deprecated and will be ignored
 // CHECK-WARNING-DAG: the flag '-fno-slp-vectorize-aggressive' has been deprecated and will be ignored
-// CHECK-WARNING-DAG: argument '-forder-file-instrumentation' is deprecated, use '-fprofile-generate-temporal-instrumentation' instead
+// CHECK-WARNING-DAG: argument '-forder-file-instrumentation' is deprecated, use '-fprofile-generate-temporal' instead
 
 // Test that we mute the warning on these
 // RUN: %clang -### -finline-limit=1000 -Wno-invalid-command-line-argument              \
diff --git a/clang/test/Driver/fprofile-generate-temporal-instrumentation.c b/clang/test/Driver/fprofile-generate-temporal-instrumentation.c
deleted file mode 100644
index e4e5b5f49bcacf..00000000000000
--- a/clang/test/Driver/fprofile-generate-temporal-instrumentation.c
+++ /dev/null
@@ -1,7 +0,0 @@
-// RUN: %clang -### -c -fprofile-generate -fprofile-generate-temporal-instrumentation %s 2>&1 | FileCheck %s
-// RUN: %clang -### -c -fcs-profile-generate -fprofile-generate-temporal-instrumentation %s 2>&1 | FileCheck %s
-// RUN: not %clang -### -c -fprofile-generate-temporal-instrumentation %s 2>&1 | FileCheck %s --check-prefix=ERR
-
-// CHECK: "-mllvm" "--pgo-temporal-instrumentation"
-
-// ERR: '-fprofile-generate-temporal-instrumentation' only allowed with '-fprofile-generate or -fcs-profile-generate'
diff --git a/clang/test/Driver/fprofile-generate-temporal.c b/clang/test/Driver/fprofile-generate-temporal.c
new file mode 100644
index 00000000000000..0f3f8bddeeae80
--- /dev/null
+++ b/clang/test/Driver/fprofile-generate-temporal.c
@@ -0,0 +1,7 @@
+// RUN: %clang -### -c -fprofile-generate -fprofile-generate-temporal %s 2>&1 | FileCheck %s
+// RUN: %clang -### -c -fcs-profile-generate -fprofile-generate-temporal %s 2>&1 | FileCheck %s
+// RUN: not %clang -### -c -fprofile-generate-temporal %s 2>&1 | FileCheck %s --check-prefix=ERR
+
+// CHECK: "-mllvm" "--pgo-temporal-instrumentation"
+
+// ERR: '-fprofile-generate-temporal' only allowed with '-fprofile-generate or -fcs-profile-generate'



More information about the cfe-commits mailing list