llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-flang-driver

@llvm/pr-subscribers-clang-driver

Author: Anchu Rajendran S (anchuraj)

<details>
<summary>Changes</summary>

`f-instrument-functions` helps in profiling functions. This PR adds support for 
the option by defining values for function attributes 
`instrument_function_entry` and `instrument_function_exit`.  LLVM Backend adds 
calls to the functions `__cyg_profile_func_enter` and `__cyg_profile_func_exit` 
which can be intercepted by user to profile every function. 

LLVM Dialect support is added in 
https://github.com/llvm/llvm-project/pull/137856. These changes are to support 
https://github.com/llvm/llvm-project/issues/112330. 

---
Full diff: https://github.com/llvm/llvm-project/pull/137996.diff


9 Files Affected:

- (modified) clang/include/clang/Driver/Options.td (+6-4) 
- (modified) clang/lib/Driver/ToolChains/Flang.cpp (+2-1) 
- (modified) flang/include/flang/Frontend/CodeGenOptions.h (+2) 
- (modified) flang/include/flang/Optimizer/Transforms/Passes.td (+8) 
- (modified) flang/include/flang/Tools/CrossToolHelpers.h (+7-1) 
- (modified) flang/lib/Frontend/CompilerInvocation.cpp (+4) 
- (modified) flang/lib/Optimizer/Passes/Pipelines.cpp (+2-1) 
- (modified) flang/lib/Optimizer/Transforms/FunctionAttr.cpp (+10) 
- (added) flang/test/Driver/func-attr-instrument-functions.f90 (+9) 


``````````diff
diff --git a/clang/include/clang/Driver/Options.td 
b/clang/include/clang/Driver/Options.td
index c0f469e04375c..8a3b74c397b95 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2824,10 +2824,12 @@ def finput_charset_EQ : Joined<["-"], 
"finput-charset=">,
   Visibility<[ClangOption, FlangOption, FC1Option]>, Group<f_Group>,
   HelpText<"Specify the default character set for source files">;
 def fexec_charset_EQ : Joined<["-"], "fexec-charset=">, Group<f_Group>;
-def finstrument_functions : Flag<["-"], "finstrument-functions">, 
Group<f_Group>,
-  Visibility<[ClangOption, CC1Option]>,
-  HelpText<"Generate calls to instrument function entry and exit">,
-  MarshallingInfoFlag<CodeGenOpts<"InstrumentFunctions">>;
+def finstrument_functions
+    : Flag<["-"], "finstrument-functions">,
+      Group<f_Group>,
+      Visibility<[ClangOption, CC1Option, FlangOption, FC1Option]>,
+      HelpText<"Generate calls to instrument function entry and exit">,
+      MarshallingInfoFlag<CodeGenOpts<"InstrumentFunctions">>;
 def finstrument_functions_after_inlining : Flag<["-"], 
"finstrument-functions-after-inlining">, Group<f_Group>,
   Visibility<[ClangOption, CC1Option]>,
   HelpText<"Like -finstrument-functions, but insert the calls after inlining">,
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp 
b/clang/lib/Driver/ToolChains/Flang.cpp
index e9d5a844ab073..a407e295c09bd 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -128,7 +128,8 @@ void Flang::addOtherOptions(const ArgList &Args, 
ArgStringList &CmdArgs) const {
                    options::OPT_std_EQ, options::OPT_W_Joined,
                    options::OPT_fconvert_EQ, options::OPT_fpass_plugin_EQ,
                    options::OPT_funderscoring, options::OPT_fno_underscoring,
-                   options::OPT_funsigned, options::OPT_fno_unsigned});
+                   options::OPT_funsigned, options::OPT_fno_unsigned,
+                   options::OPT_finstrument_functions});
 
   llvm::codegenoptions::DebugInfoKind DebugInfoKind;
   if (Args.hasArg(options::OPT_gN_Group)) {
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h 
b/flang/include/flang/Frontend/CodeGenOptions.h
index 2b4e823b3fef4..93711ae382f17 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -81,6 +81,8 @@ class CodeGenOptions : public CodeGenOptionsBase {
   /// Options to add to the linker for the object file
   std::vector<std::string> DependentLibs;
 
+  bool InstrumentFunctions{false};
+
   // The RemarkKind enum class and OptRemark struct are identical to what Clang
   // has
   // TODO: Share with clang instead of re-implementing here
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td 
b/flang/include/flang/Optimizer/Transforms/Passes.td
index c59416fa2c024..9b6919eec3f73 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -393,6 +393,14 @@ def FunctionAttr : Pass<"function-attr", 
"mlir::func::FuncOp"> {
             clEnumValN(mlir::LLVM::framePointerKind::FramePointerKind::All, 
"All", ""),
             
clEnumValN(mlir::LLVM::framePointerKind::FramePointerKind::Reserved, 
"Reserved", "")
           )}]>,
+       Option<"instrumentFunctionEntry", "instrument-function-entry",
+              "std::string", /*default=*/"",
+              "Sets the name of the profiling function called during function "
+              "entry">,
+       Option<"instrumentFunctionExit", "instrument-function-exit",
+              "std::string", /*default=*/"",
+              "Sets the name of the profiling function called during function "
+              "exit">,
        Option<"noInfsFPMath", "no-infs-fp-math", "bool", /*default=*/"false",
               "Set the no-infs-fp-math attribute on functions in the module.">,
        Option<"noNaNsFPMath", "no-nans-fp-math", "bool", /*default=*/"false",
diff --git a/flang/include/flang/Tools/CrossToolHelpers.h 
b/flang/include/flang/Tools/CrossToolHelpers.h
index 1dbc18e2b348b..36828028d3239 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -102,13 +102,17 @@ struct MLIRToLLVMPassPipelineConfig : public 
FlangEPCallBacks {
     UnsafeFPMath = mathOpts.getAssociativeMath() &&
         mathOpts.getReciprocalMath() && NoSignedZerosFPMath &&
         ApproxFuncFPMath && mathOpts.getFPContractEnabled();
+    if (opts.InstrumentFunctions) {
+      InstrumentFunctionsEntry = "__cyg_profile_func_enter";
+      InstrumentFunctionsExit = "__cyg_profile_func_exit";
+    }
   }
 
   llvm::OptimizationLevel OptLevel; ///< optimisation level
   bool StackArrays = false; ///< convert memory allocations to alloca.
   bool Underscoring = true; ///< add underscores to function names.
   bool LoopVersioning = false; ///< Run the version loop pass.
-  bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR
+  bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR.
   llvm::codegenoptions::DebugInfoKind DebugInfo =
       llvm::codegenoptions::NoDebugInfo; ///< Debug info generation.
   llvm::FramePointerKind FramePointerKind =
@@ -124,6 +128,8 @@ struct MLIRToLLVMPassPipelineConfig : public 
FlangEPCallBacks {
   bool UnsafeFPMath = false; ///< Set unsafe-fp-math attribute for functions.
   bool NSWOnLoopVarInc = true; ///< Add nsw flag to loop variable increments.
   bool EnableOpenMP = false; ///< Enable OpenMP lowering.
+  std::string InstrumentFunctionsEntry = "";
+  std::string InstrumentFunctionsExit = "";
 };
 
 struct OffloadModuleOpts {
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp 
b/flang/lib/Frontend/CompilerInvocation.cpp
index 6f87a18d69c3d..ffb16b11f6af0 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -310,6 +310,10 @@ static void 
parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
        args.filtered(clang::driver::options::OPT_fembed_offload_object_EQ))
     opts.OffloadObjects.push_back(a->getValue());
 
+  if (args.hasFlag(clang::driver::options::OPT_finstrument_functions,
+                   clang::driver::options::OPT_finstrument_functions, false))
+    opts.InstrumentFunctions = true;
+
   // -flto=full/thin option.
   if (const llvm::opt::Arg *a =
           args.getLastArg(clang::driver::options::OPT_flto_EQ)) {
diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp 
b/flang/lib/Optimizer/Passes/Pipelines.cpp
index 130cbe72ec273..795ddcbd821da 100644
--- a/flang/lib/Optimizer/Passes/Pipelines.cpp
+++ b/flang/lib/Optimizer/Passes/Pipelines.cpp
@@ -349,7 +349,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager 
&pm,
     framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None;
 
   pm.addPass(fir::createFunctionAttr(
-      {framePointerKind, config.NoInfsFPMath, config.NoNaNsFPMath,
+      {framePointerKind, config.InstrumentFunctionsEntry,
+       config.InstrumentFunctionsExit, config.NoInfsFPMath, 
config.NoNaNsFPMath,
        config.ApproxFuncFPMath, config.NoSignedZerosFPMath, 
config.UnsafeFPMath,
        ""}));
 
diff --git a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp 
b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
index c79843fac4ce2..43e4c1a7af3cd 100644
--- a/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
+++ b/flang/lib/Optimizer/Transforms/FunctionAttr.cpp
@@ -28,6 +28,8 @@ namespace {
 class FunctionAttrPass : public fir::impl::FunctionAttrBase<FunctionAttrPass> {
 public:
   FunctionAttrPass(const fir::FunctionAttrOptions &options) {
+    instrumentFunctionEntry = options.instrumentFunctionEntry;
+    instrumentFunctionExit = options.instrumentFunctionExit;
     framePointerKind = options.framePointerKind;
     noInfsFPMath = options.noInfsFPMath;
     noNaNsFPMath = options.noNaNsFPMath;
@@ -72,6 +74,14 @@ void FunctionAttrPass::runOnOperation() {
 
   auto llvmFuncOpName =
       mlir::OperationName(mlir::LLVM::LLVMFuncOp::getOperationName(), context);
+  if (!instrumentFunctionEntry.empty())
+    func->setAttr(mlir::LLVM::LLVMFuncOp::getInstrumentFunctionEntryAttrName(
+                      llvmFuncOpName),
+                  mlir::StringAttr::get(context, instrumentFunctionEntry));
+  if (!instrumentFunctionExit.empty())
+    func->setAttr(mlir::LLVM::LLVMFuncOp::getInstrumentFunctionExitAttrName(
+                      llvmFuncOpName),
+                  mlir::StringAttr::get(context, instrumentFunctionExit));
   if (noInfsFPMath)
     func->setAttr(
         mlir::LLVM::LLVMFuncOp::getNoInfsFpMathAttrName(llvmFuncOpName),
diff --git a/flang/test/Driver/func-attr-instrument-functions.f90 
b/flang/test/Driver/func-attr-instrument-functions.f90
new file mode 100644
index 0000000000000..0ef81806e9fb9
--- /dev/null
+++ b/flang/test/Driver/func-attr-instrument-functions.f90
@@ -0,0 +1,9 @@
+! RUN: %flang -O1 -finstrument-functions -emit-llvm -S -o - %s 2>&1| FileCheck 
%s
+
+subroutine func
+end subroutine func
+
+! CHECK: define void @func_()
+! CHECK: {{.*}}call void @__cyg_profile_func_enter(ptr {{.*}}@func_, ptr 
{{.*}})
+! CHECK: {{.*}}call void @__cyg_profile_func_exit(ptr {{.*}}@func_, ptr {{.*}})
+! CHECK-NEXT: ret {{.*}}

``````````

</details>


https://github.com/llvm/llvm-project/pull/137996
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to