https://github.com/anchuraj updated https://github.com/llvm/llvm-project/pull/137996
>From bb486c5e7cbe7b1c4a87469e06ca51bf49ddd081 Mon Sep 17 00:00:00 2001 From: Anchu Rajendran <asudh...@amd.com> Date: Tue, 29 Apr 2025 14:41:55 -0500 Subject: [PATCH 1/3] [flang] Support flag -finstrument-functions --- clang/include/clang/Driver/Options.td | 10 ++++++---- clang/lib/Driver/ToolChains/Flang.cpp | 3 ++- flang/include/flang/Frontend/CodeGenOptions.h | 2 ++ flang/include/flang/Optimizer/Transforms/Passes.td | 8 ++++++++ flang/include/flang/Tools/CrossToolHelpers.h | 8 +++++++- flang/lib/Frontend/CompilerInvocation.cpp | 4 ++++ flang/lib/Optimizer/Passes/Pipelines.cpp | 3 ++- flang/lib/Optimizer/Transforms/FunctionAttr.cpp | 10 ++++++++++ flang/test/Driver/func-attr-instrument-functions.f90 | 9 +++++++++ 9 files changed, 50 insertions(+), 7 deletions(-) create mode 100644 flang/test/Driver/func-attr-instrument-functions.f90 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 {{.*}} >From 88d258f0b2672cecd6a35909a664d7bd29e0132d Mon Sep 17 00:00:00 2001 From: Anchu Rajendran <asudh...@amd.com> Date: Wed, 30 Apr 2025 15:41:14 -0500 Subject: [PATCH 2/3] Address review comments --- flang/include/flang/Tools/CrossToolHelpers.h | 12 ++++++++---- flang/lib/Frontend/CompilerInvocation.cpp | 3 +-- flang/lib/Optimizer/Passes/Pipelines.cpp | 4 ++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h index 36828028d3239..118695bbe2626 100644 --- a/flang/include/flang/Tools/CrossToolHelpers.h +++ b/flang/include/flang/Tools/CrossToolHelpers.h @@ -103,8 +103,8 @@ struct MLIRToLLVMPassPipelineConfig : public FlangEPCallBacks { mathOpts.getReciprocalMath() && NoSignedZerosFPMath && ApproxFuncFPMath && mathOpts.getFPContractEnabled(); if (opts.InstrumentFunctions) { - InstrumentFunctionsEntry = "__cyg_profile_func_enter"; - InstrumentFunctionsExit = "__cyg_profile_func_exit"; + InstrumentFunctionEntry = "__cyg_profile_func_enter"; + InstrumentFunctionExit = "__cyg_profile_func_exit"; } } @@ -128,8 +128,12 @@ 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 = ""; + std::string InstrumentFunctionEntry = + ""; ///< Name of the instrument-function that is called on each + ///< function-entry + std::string InstrumentFunctionExit = + ""; ///< Name of the instrument-function that is called on each + ///< function-exit }; struct OffloadModuleOpts { diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index ffb16b11f6af0..03b9d87824369 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -310,8 +310,7 @@ 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)) + if (args.hasArg(clang::driver::options::OPT_finstrument_functions)) opts.InstrumentFunctions = true; // -flto=full/thin option. diff --git a/flang/lib/Optimizer/Passes/Pipelines.cpp b/flang/lib/Optimizer/Passes/Pipelines.cpp index 795ddcbd821da..a3ef473ea39b7 100644 --- a/flang/lib/Optimizer/Passes/Pipelines.cpp +++ b/flang/lib/Optimizer/Passes/Pipelines.cpp @@ -349,8 +349,8 @@ void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm, framePointerKind = mlir::LLVM::framePointerKind::FramePointerKind::None; pm.addPass(fir::createFunctionAttr( - {framePointerKind, config.InstrumentFunctionsEntry, - config.InstrumentFunctionsExit, config.NoInfsFPMath, config.NoNaNsFPMath, + {framePointerKind, config.InstrumentFunctionEntry, + config.InstrumentFunctionExit, config.NoInfsFPMath, config.NoNaNsFPMath, config.ApproxFuncFPMath, config.NoSignedZerosFPMath, config.UnsafeFPMath, ""})); >From 3a00558f985edee03f9b5a720fc36908c65b495f Mon Sep 17 00:00:00 2001 From: Anchu Rajendran <asudh...@amd.com> Date: Wed, 30 Apr 2025 16:28:42 -0500 Subject: [PATCH 3/3] R3: Address review comments --- flang/include/flang/Frontend/CodeGenOptions.h | 1 + 1 file changed, 1 insertion(+) diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 93711ae382f17..6786a5b8b5fa3 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -81,6 +81,7 @@ class CodeGenOptions : public CodeGenOptionsBase { /// Options to add to the linker for the object file std::vector<std::string> DependentLibs; + /// Indicates whether -finstrument-functions is passed bool InstrumentFunctions{false}; // The RemarkKind enum class and OptRemark struct are identical to what Clang _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits