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