Skip to content

[flang] Support finstrument-functions flag #2

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -2811,10 +2811,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">,
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Driver/ToolChains/Flang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
2 changes: 2 additions & 0 deletions flang/include/flang/Frontend/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 8 additions & 0 deletions flang/include/flang/Optimizer/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 7 additions & 1 deletion flang/include/flang/Tools/CrossToolHelpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions flang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
3 changes: 2 additions & 1 deletion flang/lib/Optimizer/Passes/Pipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,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,
""}));

Expand Down
10 changes: 10 additions & 0 deletions flang/lib/Optimizer/Transforms/FunctionAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand Down
9 changes: 9 additions & 0 deletions flang/test/Driver/func-attr-instrument-functions.f90
Original file line number Diff line number Diff line change
@@ -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 {{.*}}