[clang] [flang] [flang][flang-driver] Support flag -finstrument-functions (PR #137996)
Anchu Rajendran S via cfe-commits
cfe-commits at lists.llvm.org
Thu May 1 09:34:25 PDT 2025
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 <asudhaku at amd.com>
Date: Tue, 29 Apr 2025 14:41:55 -0500
Subject: [PATCH 1/4] [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 <asudhaku at amd.com>
Date: Wed, 30 Apr 2025 15:41:14 -0500
Subject: [PATCH 2/4] 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 <asudhaku at amd.com>
Date: Wed, 30 Apr 2025 16:28:42 -0500
Subject: [PATCH 3/4] 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
>From 47bb3c1f1783f947fc65973a1f4c525cf779a0ac Mon Sep 17 00:00:00 2001
From: Anchu Rajendran <asudhaku at amd.com>
Date: Thu, 1 May 2025 10:16:56 -0500
Subject: [PATCH 4/4] R4: Addressing review comments
---
flang/include/flang/Frontend/CodeGenOptions.def | 2 ++
flang/include/flang/Frontend/CodeGenOptions.h | 3 ---
flang/lib/Frontend/CompilerInvocation.cpp | 2 +-
3 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 57830bf51a1b3..d9dbd274e83e5 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -24,6 +24,8 @@ CODEGENOPT(OptimizationLevel, 2, 0) ///< The -O[0-3] option specified.
CODEGENOPT(DebugPassManager, 1, 0) ///< Prints debug information for the new
///< pass manager.
+CODEGENOPT(InstrumentFunctions, 1, 0) ///< Set when -finstrument_functions is
+ ///< enabled on the compile step.
CODEGENOPT(IsPIE, 1, 0) ///< PIE level is the same as PIC Level.
CODEGENOPT(PICLevel, 2, 0) ///< PIC level of the LLVM module.
CODEGENOPT(PrepareForFullLTO , 1, 0) ///< Set when -flto is enabled on the
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index 6786a5b8b5fa3..2b4e823b3fef4 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -81,9 +81,6 @@ 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
// has
// TODO: Share with clang instead of re-implementing here
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 03b9d87824369..d6ba644b1400d 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -311,7 +311,7 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
opts.OffloadObjects.push_back(a->getValue());
if (args.hasArg(clang::driver::options::OPT_finstrument_functions))
- opts.InstrumentFunctions = true;
+ opts.InstrumentFunctions = 1;
// -flto=full/thin option.
if (const llvm::opt::Arg *a =
More information about the cfe-commits
mailing list