[flang-commits] [flang] dd499f8 - [Flang][Driver]Add support for option '-fpseudo-probe-for-profiling' in flang (#205046)

via flang-commits flang-commits at lists.llvm.org
Wed Jun 24 23:05:38 PDT 2026


Author: Kaviya Rajendiran
Date: 2026-06-25T11:35:32+05:30
New Revision: dd499f88bf4d304baf0db1d6d4d84ad5bea8d7ad

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

LOG: [Flang][Driver]Add support for option '-fpseudo-probe-for-profiling' in flang (#205046)

Added support for option `-fpseudo-probe-for-profiling` in flang.

- When the option `-fpseudo-probe-for-profiling` is passed, the compiler
sets the` PseudoProbeForProfiling` flag and triggers the
`SampleProfileProbePass`. This pass inserts `llvm.pseudoprobe(..)`
intrinsic calls and `!llvm.pseudo_probe_desc` metadata into the IR.

Added: 
    flang/test/Driver/fpseudo-probe-for-profiling.f90
    flang/test/Integration/pseudo-probe-for-profiling.f90

Modified: 
    clang/include/clang/Options/Options.td
    clang/lib/Driver/ToolChains/Flang.cpp
    flang/include/flang/Frontend/CodeGenOptions.def
    flang/lib/Frontend/CompilerInvocation.cpp
    flang/lib/Frontend/FrontendActions.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td
index 4fc9f4d4c3472..3c2091013d152 100644
--- a/clang/include/clang/Options/Options.td
+++ b/clang/include/clang/Options/Options.td
@@ -1944,7 +1944,7 @@ defm pseudo_probe_for_profiling
                   CodeGenOpts<"PseudoProbeForProfiling">, DefaultFalse,
                   PosFlag<SetTrue, [], [ClangOption], "Emit">,
                   NegFlag<SetFalse, [], [ClangOption], "Do not emit">,
-                  BothFlags<[], [ClangOption, CC1Option, CLOption],
+                  BothFlags<[], [ClangOption, CC1Option, CLOption, FlangOption, FC1Option],
                             " pseudo probes for sample profiling">>;
 def fprofile_list_EQ : Joined<["-"], "fprofile-list=">,
     Group<f_Group>, Visibility<[ClangOption, CC1Option, CLOption]>,

diff  --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 1d74a34583311..ea4df1db38ec8 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -1022,6 +1022,11 @@ static void addPGOAndCoverageFlags(const ToolChain &TC, const JobAction &JA,
         A->render(Args, CmdArgs);
     }
   }
+
+  //-fpseudo-probe-for-profiling
+  if (Args.hasFlag(options::OPT_fpseudo_probe_for_profiling,
+                   options::OPT_fno_pseudo_probe_for_profiling, false))
+    CmdArgs.push_back("-fpseudo-probe-for-profiling");
 }
 
 void Flang::ConstructJob(Compilation &C, const JobAction &JA,

diff  --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 37931c0ffecc1..a5907b6edbd97 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -58,6 +58,7 @@ CODEGENOPT(UnrollLoops, 1, 0) ///< Enable loop unrolling
 CODEGENOPT(AliasAnalysis, 1, 0) ///< Enable alias analysis pass
 CODEGENOPT(DwarfVersion, 3, 0) ///< Dwarf version
 CODEGENOPT(DebugInfoForProfiling, 1, 0)  ///< Emit extra debug info to make sample profile more accurate.
+CODEGENOPT(PseudoProbeForProfiling, 1, 0) ///< Emit pseudo probes for sample profiling.
 
 CODEGENOPT(Underscoring, 1, 1)
 ENUM_CODEGENOPT(FPMaxminBehavior, Fortran::common::FPMaxminBehavior, 2, Fortran::common::FPMaxminBehavior::Legacy)

diff  --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index ab961416441fe..0f1ace5d62667 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -488,6 +488,11 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
   opts.SampleProfileFile =
       args.getLastArgValue(clang::options::OPT_fprofile_sample_use_EQ);
 
+  if (args.hasFlag(clang::options::OPT_fpseudo_probe_for_profiling,
+                   clang::options::OPT_fno_pseudo_probe_for_profiling, false)) {
+    opts.PseudoProbeForProfiling = 1;
+  }
+
   // -mcmodel option.
   if (const llvm::opt::Arg *a =
           args.getLastArg(clang::options::OPT_mcmodel_EQ)) {

diff  --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index 426dea4869001..5fe876595d5c0 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -984,18 +984,26 @@ void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
         opts.ProfileInstrumentUsePath, "", opts.ProfileRemappingFile,
         opts.MemoryProfileUsePath, llvm::PGOOptions::IRUse, CSAction,
         llvm::PGOOptions::ColdFuncOpt::Default, opts.DebugInfoForProfiling);
-  } else if (opts.DebugInfoForProfiling) {
-    // -fdebug-info-for-profiling
-    pgoOpt = llvm::PGOOptions("", "", "", /*MemoryProfile=*/"",
-                              llvm::PGOOptions::NoAction,
-                              llvm::PGOOptions::NoCSAction,
-                              llvm::PGOOptions::ColdFuncOpt::Default, true);
   } else if (!opts.SampleProfileFile.empty()) {
     pgoOpt = llvm::PGOOptions(
         opts.SampleProfileFile, "", opts.ProfileRemappingFile,
         opts.MemoryProfileUsePath, llvm::PGOOptions::SampleUse,
         llvm::PGOOptions::NoCSAction, llvm::PGOOptions::ColdFuncOpt::Default,
-        opts.DebugInfoForProfiling, /*PseudoProbeForProfiling=*/false);
+        opts.DebugInfoForProfiling, opts.PseudoProbeForProfiling);
+  } else if (opts.PseudoProbeForProfiling) {
+    pgoOpt = llvm::PGOOptions(
+        /*ProfileFile=*/"", /*CSProfileGenFile=*/"",
+        /*ProfileRemappingFile=*/"",
+        /*MemoryProfile=*/"", llvm::PGOOptions::NoAction,
+        llvm::PGOOptions::NoCSAction, llvm::PGOOptions::ColdFuncOpt::Default,
+        opts.DebugInfoForProfiling, /*PseudoProbeForProfiling=*/true);
+  } else if (opts.DebugInfoForProfiling) {
+    pgoOpt = llvm::PGOOptions(/*ProfileFile=*/"", /*CSProfileGenFile=*/"",
+                              /*ProfileRemappingFile=*/"", /*MemoryProfile=*/"",
+                              llvm::PGOOptions::NoAction,
+                              llvm::PGOOptions::NoCSAction,
+                              llvm::PGOOptions::ColdFuncOpt::Default,
+                              /*DebugInfoForProfiling=*/true);
   }
 
   llvm::StandardInstrumentations si(llvmModule->getContext(),

diff  --git a/flang/test/Driver/fpseudo-probe-for-profiling.f90 b/flang/test/Driver/fpseudo-probe-for-profiling.f90
new file mode 100644
index 0000000000000..8d5fc72d314be
--- /dev/null
+++ b/flang/test/Driver/fpseudo-probe-for-profiling.f90
@@ -0,0 +1,15 @@
+! Test to check the option "-fpseudo-probe-for-profiling".
+
+! RUN: %flang -### %s 2>&1 | FileCheck %s --check-prefix=NO-PROBE
+! RUN: %flang -### -fpseudo-probe-for-profiling %s 2>&1 | FileCheck %s --check-prefix=PROBE
+! RUN: %flang -### -fno-pseudo-probe-for-profiling %s 2>&1 | FileCheck %s --check-prefix=NO-PROBE
+! RUN: %flang -### -fpseudo-probe-for-profiling -fno-pseudo-probe-for-profiling %s 2>&1 | FileCheck %s --check-prefix=NO-PROBE
+! RUN: %flang -### -fpseudo-probe-for-profiling -fno-pseudo-probe-for-profiling -fpseudo-probe-for-profiling %s 2>&1 | FileCheck %s --check-prefix=PROBE
+
+! PROBE: "-fpseudo-probe-for-profiling"
+! NO-PROBE-NOT: "-fpseudo-probe-for-profiling"
+
+subroutine test
+    implicit none
+    print *, 1
+end subroutine test

diff  --git a/flang/test/Integration/pseudo-probe-for-profiling.f90 b/flang/test/Integration/pseudo-probe-for-profiling.f90
new file mode 100644
index 0000000000000..a11cb4502dcf1
--- /dev/null
+++ b/flang/test/Integration/pseudo-probe-for-profiling.f90
@@ -0,0 +1,33 @@
+! Test -fpseudo-probe-for-profiling option runs SampleProfileProbePass and emits llvm.pseudoprobe intrinsic calls.
+!
+! RUN: %flang_fc1 -emit-llvm -fdebug-pass-manager -fpseudo-probe-for-profiling -o /dev/null %s 2>&1 | FileCheck %s --check-prefix=PROBE-PASS
+! RUN: %flang_fc1 -emit-llvm -O0 -fpseudo-probe-for-profiling -o - %s | FileCheck %s --check-prefix=PROBE
+! RUN: %flang_fc1 -emit-llvm -O2 -fpseudo-probe-for-profiling -o - %s | FileCheck %s --check-prefix=PROBE
+
+! Test that -fdebug-info-for-profiling combined with -fpseudo-probe-for-profiling still emits pseudo-probes and debug info.
+! RUN: %flang_fc1 -emit-llvm -O2 -debug-info-kind=standalone \
+! RUN:   -fdebug-info-for-profiling -fpseudo-probe-for-profiling -o - %s | FileCheck %s --check-prefix=PROBE-AND-DEBUG
+
+! PROBE-PASS: Running pass: SampleProfileProbePass on {{.*}}
+
+! PROBE-LABEL: define void @foo
+! PROBE: call void @llvm.pseudoprobe(i64 [[#GUID:]], i64 1, i32 0, i64 -1)
+! PROBE: call void @llvm.pseudoprobe(i64 [[#GUID]], i64 2, i32 0, i64 -1)
+! PROBE: call void @llvm.pseudoprobe(i64 [[#GUID]], i64 4, i32 0, i64 -1)
+! PROBE: call void @llvm.pseudoprobe(i64 [[#GUID]], i64 6, i32 0, i64 -1)
+! PROBE: !llvm.pseudo_probe_desc = !{
+
+! PROBE-AND-DEBUG: call void @llvm.pseudoprobe
+! PROBE-AND-DEBUG: !llvm.pseudo_probe_desc = !{
+! PROBE-AND-DEBUG: !DICompileUnit({{.*}}debugInfoForProfiling: true{{.*}})
+! PROBE-AND-DEBUG: !DILexicalBlockFile({{.*}}discriminator:
+
+subroutine foo(x)
+   implicit none
+   integer, intent(in) :: x
+   if (x == 0) then
+      call bar
+   else
+      call go
+   end if
+end subroutine foo


        


More information about the flang-commits mailing list