-
Notifications
You must be signed in to change notification settings - Fork 12k
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
[Flang][Clang] Add support for frame pointers in Flang Driver #72146
Conversation
@llvm/pr-subscribers-clang Author: Radu Salavat (Radu2k) ChangesAdd support for frame pointers in Flang. Patch is 22.74 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/72146.diff 13 Files Affected:
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d1b67a448b2a59b..bf99786d017b318 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3147,7 +3147,8 @@ def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>,
def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>;
def fno_objc_weak : Flag<["-"], "fno-objc-weak">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>;
-def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>;
+def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>;
defm operator_names : BoolFOption<"operator-names",
LangOpts<"CXXOperatorNames">, Default<cplusplus.KeyPath>,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
@@ -3273,6 +3274,7 @@ defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blo
BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>,
HelpText<"Omit the frame pointer from functions that don't need it. "
"Some stack unwinding cases, such as profilers and sanitizers, may prefer specifying -fno-omit-frame-pointer. "
"On many targets, -O1 and higher omit the frame pointer by default. "
@@ -6752,10 +6754,7 @@ def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">,
def mdebug_pass : Separate<["-"], "mdebug-pass">,
HelpText<"Enable additional debug output">,
MarshallingInfoString<CodeGenOpts<"DebugPass">>;
-def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
- HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">,
- NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
- MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
+
def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">,
HelpText<"Use IEEE 754 quadruple-precision for long double">,
MarshallingInfoFlag<LangOpts<"PPCIEEELongDouble">>;
@@ -7368,6 +7367,11 @@ def pic_level : Separate<["-"], "pic-level">,
def pic_is_pie : Flag<["-"], "pic-is-pie">,
HelpText<"File is for a position independent executable">,
MarshallingInfoFlag<LangOpts<"PIE">>;
+
+def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
+ HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">,
+ NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
+ MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
} // let Visibility = [CC1Option, FC1Option]
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3b98c7ae6e6ec66..3273bd1d2c0c6fa 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -409,139 +409,6 @@ static bool ShouldEnableAutolink(const ArgList &Args, const ToolChain &TC,
Default);
}
-static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
- switch (Triple.getArch()){
- default:
- return false;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- // ARM Darwin targets require a frame pointer to be always present to aid
- // offline debugging via backtraces.
- return Triple.isOSDarwin();
- }
-}
-
-static bool useFramePointerForTargetByDefault(const ArgList &Args,
- const llvm::Triple &Triple) {
- if (Args.hasArg(options::OPT_pg) && !Args.hasArg(options::OPT_mfentry))
- return true;
-
- if (Triple.isAndroid()) {
- switch (Triple.getArch()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- case llvm::Triple::riscv64:
- return true;
- default:
- break;
- }
- }
-
- switch (Triple.getArch()) {
- case llvm::Triple::xcore:
- case llvm::Triple::wasm32:
- case llvm::Triple::wasm64:
- case llvm::Triple::msp430:
- // XCore never wants frame pointers, regardless of OS.
- // WebAssembly never wants frame pointers.
- return false;
- case llvm::Triple::ppc:
- case llvm::Triple::ppcle:
- case llvm::Triple::ppc64:
- case llvm::Triple::ppc64le:
- case llvm::Triple::riscv32:
- case llvm::Triple::riscv64:
- case llvm::Triple::sparc:
- case llvm::Triple::sparcel:
- case llvm::Triple::sparcv9:
- case llvm::Triple::amdgcn:
- case llvm::Triple::r600:
- case llvm::Triple::csky:
- case llvm::Triple::loongarch32:
- case llvm::Triple::loongarch64:
- return !areOptimizationsEnabled(Args);
- default:
- break;
- }
-
- if (Triple.isOSFuchsia() || Triple.isOSNetBSD()) {
- return !areOptimizationsEnabled(Args);
- }
-
- if (Triple.isOSLinux() || Triple.isOSHurd()) {
- switch (Triple.getArch()) {
- // Don't use a frame pointer on linux if optimizing for certain targets.
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::systemz:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- return !areOptimizationsEnabled(Args);
- default:
- return true;
- }
- }
-
- if (Triple.isOSWindows()) {
- switch (Triple.getArch()) {
- case llvm::Triple::x86:
- return !areOptimizationsEnabled(Args);
- case llvm::Triple::x86_64:
- return Triple.isOSBinFormatMachO();
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- // Windows on ARM builds with FPO disabled to aid fast stack walking
- return true;
- default:
- // All other supported Windows ISAs use xdata unwind information, so frame
- // pointers are not generally useful.
- return false;
- }
- }
-
- return true;
-}
-
-static CodeGenOptions::FramePointerKind
-getFramePointerKind(const ArgList &Args, const llvm::Triple &Triple) {
- // We have 4 states:
- //
- // 00) leaf retained, non-leaf retained
- // 01) leaf retained, non-leaf omitted (this is invalid)
- // 10) leaf omitted, non-leaf retained
- // (what -momit-leaf-frame-pointer was designed for)
- // 11) leaf omitted, non-leaf omitted
- //
- // "omit" options taking precedence over "no-omit" options is the only way
- // to make 3 valid states representable
- Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
- options::OPT_fno_omit_frame_pointer);
- bool OmitFP = A && A->getOption().matches(options::OPT_fomit_frame_pointer);
- bool NoOmitFP =
- A && A->getOption().matches(options::OPT_fno_omit_frame_pointer);
- bool OmitLeafFP =
- Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
- options::OPT_mno_omit_leaf_frame_pointer,
- Triple.isAArch64() || Triple.isPS() || Triple.isVE() ||
- (Triple.isAndroid() && Triple.isRISCV64()));
- if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) ||
- (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) {
- if (OmitLeafFP)
- return CodeGenOptions::FramePointerKind::NonLeaf;
- return CodeGenOptions::FramePointerKind::All;
- }
- return CodeGenOptions::FramePointerKind::None;
-}
-
/// Add a CC1 option to specify the debug compilation directory.
static const char *addDebugCompDirArg(const ArgList &Args,
ArgStringList &CmdArgs,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 5d2cd1959b06925..f81bca14363a22a 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -24,6 +24,7 @@
#include "MSP430.h"
#include "Solaris.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
@@ -71,6 +72,146 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ if (Args.hasArg(clang::driver::options::OPT_pg) &&
+ !Args.hasArg(clang::driver::options::OPT_mfentry))
+ return true;
+
+ if (Triple.isAndroid()) {
+ switch (Triple.getArch()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::riscv64:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ switch (Triple.getArch()) {
+ case llvm::Triple::xcore:
+ case llvm::Triple::wasm32:
+ case llvm::Triple::wasm64:
+ case llvm::Triple::msp430:
+ // XCore never wants frame pointers, regardless of OS.
+ // WebAssembly never wants frame pointers.
+ return false;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppcle:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcel:
+ case llvm::Triple::sparcv9:
+ case llvm::Triple::amdgcn:
+ case llvm::Triple::r600:
+ case llvm::Triple::csky:
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ default:
+ break;
+ }
+
+ if (Triple.isOSFuchsia() || Triple.isOSNetBSD()) {
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ }
+
+ //if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI ||
+ if (Triple.isOSLinux() || Triple.isOSHurd()) {
+ switch (Triple.getArch()) {
+ // Don't use a frame pointer on linux if optimizing for certain targets.
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::systemz:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ default:
+ return true;
+ }
+ }
+
+ if (Triple.isOSWindows()) {
+ switch (Triple.getArch()) {
+ case llvm::Triple::x86:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ case llvm::Triple::x86_64:
+ return Triple.isOSBinFormatMachO();
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ // Windows on ARM builds with FPO disabled to aid fast stack walking
+ return true;
+ default:
+ // All other supported Windows ISAs use xdata unwind information, so frame
+ // pointers are not generally useful.
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
+ switch (Triple.getArch()) {
+ default:
+ return false;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ // ARM Darwin targets require a frame pointer to be always present to aid
+ // offline debugging via backtraces.
+ return Triple.isOSDarwin();
+ }
+}
+
+clang::CodeGenOptions::FramePointerKind
+getFramePointerKind(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ // We have 4 states:
+ //
+ // 00) leaf retained, non-leaf retained
+ // 01) leaf retained, non-leaf omitted (this is invalid)
+ // 10) leaf omitted, non-leaf retained
+ // (what -momit-leaf-frame-pointer was designed for)
+ // 11) leaf omitted, non-leaf omitted
+ //
+ // "omit" options taking precedence over "no-omit" options is the only way
+ // to make 3 valid states representable
+ llvm::opt::Arg *A =
+ Args.getLastArg(clang::driver::options::OPT_fomit_frame_pointer,
+ clang::driver::options::OPT_fno_omit_frame_pointer);
+
+ bool OmitFP = A && A->getOption().matches(
+ clang::driver::options::OPT_fomit_frame_pointer);
+ bool NoOmitFP = A && A->getOption().matches(
+ clang::driver::options::OPT_fno_omit_frame_pointer);
+ bool OmitLeafFP =
+ Args.hasFlag(clang::driver::options::OPT_momit_leaf_frame_pointer,
+ clang::driver::options::OPT_mno_omit_leaf_frame_pointer,
+ Triple.isAArch64() || Triple.isPS() || Triple.isVE() ||
+ (Triple.isAndroid() && Triple.isRISCV64()));
+ if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) ||
+ (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) {
+ if (OmitLeafFP)
+ return clang::CodeGenOptions::FramePointerKind::NonLeaf;
+ return clang::CodeGenOptions::FramePointerKind::All;
+ }
+ return clang::CodeGenOptions::FramePointerKind::None;
+}
+
+
static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs,
const StringRef PluginOptPrefix) {
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 0a0951c5386e601..abe8948c5387dce 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/InputInfo.h"
#include "clang/Driver/Multilib.h"
@@ -215,4 +216,7 @@ void addOpenMPDeviceRTL(const Driver &D, const llvm::opt::ArgList &DriverArgs,
} // end namespace driver
} // end namespace clang
+clang::CodeGenOptions::FramePointerKind getFramePointerKind(
+ const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
+
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 8bdd920c3dcbb79..d53bed8e6c1f3b1 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -9,6 +9,7 @@
#include "Flang.h"
#include "CommonArgs.h"
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Driver/Options.h"
#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Support/FileSystem.h"
@@ -606,6 +607,24 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
// Forward -Xflang arguments to -fc1
Args.AddAllArgValues(CmdArgs, options::OPT_Xflang);
+ CodeGenOptions::FramePointerKind FPKeepKind =
+ getFramePointerKind(Args, Triple);
+
+ const char *FPKeepKindStr = nullptr;
+ switch (FPKeepKind) {
+ case CodeGenOptions::FramePointerKind::None:
+ FPKeepKindStr = "-mframe-pointer=none";
+ break;
+ case CodeGenOptions::FramePointerKind::NonLeaf:
+ FPKeepKindStr = "-mframe-pointer=non-leaf";
+ break;
+ case CodeGenOptions::FramePointerKind::All:
+ FPKeepKindStr = "-mframe-pointer=all";
+ break;
+ }
+ assert(FPKeepKindStr && "unknown FramePointerKind");
+ CmdArgs.push_back(FPKeepKindStr);
+
// Forward -mllvm options to the LLVM option parser. In practice, this means
// forwarding to `-fc1` as that's where the LLVM parser is run.
for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 72e7bdab12a14da..d9e6cdfda8598bb 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -38,6 +38,7 @@ CODEGENOPT(Underscoring, 1, 1)
ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use.
ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate
ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use
+ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index a3c39bda10667be..9ccd567678be95f 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -49,6 +49,29 @@ class CodeGenOptionsBase {
class CodeGenOptions : public CodeGenOptionsBase {
public:
+ //Added
+ ///*
+ enum class FramePointerKind {
+ None, // Omit all frame pointers.
+ NonLeaf, // Keep non-leaf frame pointers.
+ All, // Keep all frame pointers.
+ };
+
+ static llvm::StringRef getFramePointerKindName(FramePointerKind Kind) {
+ switch (Kind) {
+ case FramePointerKind::None:
+ return "none";
+ case FramePointerKind::NonLeaf:
+ return "non-leaf";
+ case FramePointerKind::All:
+ return "all";
+ }
+
+ llvm_unreachable("invalid FramePointerKind");
+ };
+ //
+ //*/
+
/// The paths to the pass plugins that were registered using -fpass-plugin.
std::vector<std::string> LLVMPassPlugins;
diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h
index ddec70fa9824c52..7fc5776a61abc5d 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -44,6 +44,8 @@ struct MLIRToLLVMPassPipelineConfig {
bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR
llvm::codegenoptions::DebugInfoKind DebugInfo =
llvm::codegenoptions::NoDebugInfo; ///< Debug info generation.
+ llvm::FramePointerKind FramePointer =
+ llvm::FramePointerKind::None; ///< FramePointerInfo
unsigned VScaleMin = 0; ///< SVE vector range minimum.
unsigned VScaleMax = 0; ///< SVE vector range maximum.
};
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 334da3ac287e3bf..4340981ae9d642a 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -247,6 +247,19 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
clang::driver::options::OPT_fno_alias_analysis,
/*default=*/false);
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) {
+ llvm::StringRef s = a->getValue();
+ assert(s == "none" || s == "non-leaf"|| s == "all");
+ if (s == "none")
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::None);
+ else
+ if (s == "non-leaf")
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::NonLeaf);
+ else
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::All);
+ }
+
for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ))
opts.LLVMPassPlugins.push_back(a->getValue());
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index d7ca7b66584dd52..06273a07e84f2a0 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -783,6 +783,11 @@ void CodeGenAction::generateLLVMIR() {
llvmModule->setPIELevel(
static_cast<llvm::PIELevel::Level>(opts.PICLevel));
}
+
+ // Set FramePointer LLVM module flag.
+ llvmModule->setFramePointer(
+ static_cast<llvm::FramePointerKind>(opts.getFramePointer()));
+
}
bool CodeGenAction::setUpTargetMachine() {
diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90
index b276f1906e1a457..57a1710709940f3 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -74,6 +74,7 @@
! CHECK-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default)
! CHECK-NEXT: -fno-version-loops-for-stride
! CHECK-NEXT: Do not create unit-strided loops (default)
+! CHECK-NEXT: -fomit-frame-pointer Omit the frame pointer from functions that don't need it. Some...
[truncated]
|
@llvm/pr-subscribers-clang-driver Author: Radu Salavat (Radu2k) ChangesAdd support for frame pointers in Flang. Patch is 22.74 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/72146.diff 13 Files Affected:
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d1b67a448b2a59b..bf99786d017b318 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3147,7 +3147,8 @@ def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>,
def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>;
def fno_objc_weak : Flag<["-"], "fno-objc-weak">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>;
-def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>;
+def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>;
defm operator_names : BoolFOption<"operator-names",
LangOpts<"CXXOperatorNames">, Default<cplusplus.KeyPath>,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
@@ -3273,6 +3274,7 @@ defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blo
BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>,
HelpText<"Omit the frame pointer from functions that don't need it. "
"Some stack unwinding cases, such as profilers and sanitizers, may prefer specifying -fno-omit-frame-pointer. "
"On many targets, -O1 and higher omit the frame pointer by default. "
@@ -6752,10 +6754,7 @@ def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">,
def mdebug_pass : Separate<["-"], "mdebug-pass">,
HelpText<"Enable additional debug output">,
MarshallingInfoString<CodeGenOpts<"DebugPass">>;
-def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
- HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">,
- NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
- MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
+
def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">,
HelpText<"Use IEEE 754 quadruple-precision for long double">,
MarshallingInfoFlag<LangOpts<"PPCIEEELongDouble">>;
@@ -7368,6 +7367,11 @@ def pic_level : Separate<["-"], "pic-level">,
def pic_is_pie : Flag<["-"], "pic-is-pie">,
HelpText<"File is for a position independent executable">,
MarshallingInfoFlag<LangOpts<"PIE">>;
+
+def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
+ HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">,
+ NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
+ MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
} // let Visibility = [CC1Option, FC1Option]
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3b98c7ae6e6ec66..3273bd1d2c0c6fa 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -409,139 +409,6 @@ static bool ShouldEnableAutolink(const ArgList &Args, const ToolChain &TC,
Default);
}
-static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
- switch (Triple.getArch()){
- default:
- return false;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- // ARM Darwin targets require a frame pointer to be always present to aid
- // offline debugging via backtraces.
- return Triple.isOSDarwin();
- }
-}
-
-static bool useFramePointerForTargetByDefault(const ArgList &Args,
- const llvm::Triple &Triple) {
- if (Args.hasArg(options::OPT_pg) && !Args.hasArg(options::OPT_mfentry))
- return true;
-
- if (Triple.isAndroid()) {
- switch (Triple.getArch()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- case llvm::Triple::riscv64:
- return true;
- default:
- break;
- }
- }
-
- switch (Triple.getArch()) {
- case llvm::Triple::xcore:
- case llvm::Triple::wasm32:
- case llvm::Triple::wasm64:
- case llvm::Triple::msp430:
- // XCore never wants frame pointers, regardless of OS.
- // WebAssembly never wants frame pointers.
- return false;
- case llvm::Triple::ppc:
- case llvm::Triple::ppcle:
- case llvm::Triple::ppc64:
- case llvm::Triple::ppc64le:
- case llvm::Triple::riscv32:
- case llvm::Triple::riscv64:
- case llvm::Triple::sparc:
- case llvm::Triple::sparcel:
- case llvm::Triple::sparcv9:
- case llvm::Triple::amdgcn:
- case llvm::Triple::r600:
- case llvm::Triple::csky:
- case llvm::Triple::loongarch32:
- case llvm::Triple::loongarch64:
- return !areOptimizationsEnabled(Args);
- default:
- break;
- }
-
- if (Triple.isOSFuchsia() || Triple.isOSNetBSD()) {
- return !areOptimizationsEnabled(Args);
- }
-
- if (Triple.isOSLinux() || Triple.isOSHurd()) {
- switch (Triple.getArch()) {
- // Don't use a frame pointer on linux if optimizing for certain targets.
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::systemz:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- return !areOptimizationsEnabled(Args);
- default:
- return true;
- }
- }
-
- if (Triple.isOSWindows()) {
- switch (Triple.getArch()) {
- case llvm::Triple::x86:
- return !areOptimizationsEnabled(Args);
- case llvm::Triple::x86_64:
- return Triple.isOSBinFormatMachO();
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- // Windows on ARM builds with FPO disabled to aid fast stack walking
- return true;
- default:
- // All other supported Windows ISAs use xdata unwind information, so frame
- // pointers are not generally useful.
- return false;
- }
- }
-
- return true;
-}
-
-static CodeGenOptions::FramePointerKind
-getFramePointerKind(const ArgList &Args, const llvm::Triple &Triple) {
- // We have 4 states:
- //
- // 00) leaf retained, non-leaf retained
- // 01) leaf retained, non-leaf omitted (this is invalid)
- // 10) leaf omitted, non-leaf retained
- // (what -momit-leaf-frame-pointer was designed for)
- // 11) leaf omitted, non-leaf omitted
- //
- // "omit" options taking precedence over "no-omit" options is the only way
- // to make 3 valid states representable
- Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
- options::OPT_fno_omit_frame_pointer);
- bool OmitFP = A && A->getOption().matches(options::OPT_fomit_frame_pointer);
- bool NoOmitFP =
- A && A->getOption().matches(options::OPT_fno_omit_frame_pointer);
- bool OmitLeafFP =
- Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
- options::OPT_mno_omit_leaf_frame_pointer,
- Triple.isAArch64() || Triple.isPS() || Triple.isVE() ||
- (Triple.isAndroid() && Triple.isRISCV64()));
- if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) ||
- (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) {
- if (OmitLeafFP)
- return CodeGenOptions::FramePointerKind::NonLeaf;
- return CodeGenOptions::FramePointerKind::All;
- }
- return CodeGenOptions::FramePointerKind::None;
-}
-
/// Add a CC1 option to specify the debug compilation directory.
static const char *addDebugCompDirArg(const ArgList &Args,
ArgStringList &CmdArgs,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 5d2cd1959b06925..f81bca14363a22a 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -24,6 +24,7 @@
#include "MSP430.h"
#include "Solaris.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
@@ -71,6 +72,146 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ if (Args.hasArg(clang::driver::options::OPT_pg) &&
+ !Args.hasArg(clang::driver::options::OPT_mfentry))
+ return true;
+
+ if (Triple.isAndroid()) {
+ switch (Triple.getArch()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::riscv64:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ switch (Triple.getArch()) {
+ case llvm::Triple::xcore:
+ case llvm::Triple::wasm32:
+ case llvm::Triple::wasm64:
+ case llvm::Triple::msp430:
+ // XCore never wants frame pointers, regardless of OS.
+ // WebAssembly never wants frame pointers.
+ return false;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppcle:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcel:
+ case llvm::Triple::sparcv9:
+ case llvm::Triple::amdgcn:
+ case llvm::Triple::r600:
+ case llvm::Triple::csky:
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ default:
+ break;
+ }
+
+ if (Triple.isOSFuchsia() || Triple.isOSNetBSD()) {
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ }
+
+ //if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI ||
+ if (Triple.isOSLinux() || Triple.isOSHurd()) {
+ switch (Triple.getArch()) {
+ // Don't use a frame pointer on linux if optimizing for certain targets.
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::systemz:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ default:
+ return true;
+ }
+ }
+
+ if (Triple.isOSWindows()) {
+ switch (Triple.getArch()) {
+ case llvm::Triple::x86:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ case llvm::Triple::x86_64:
+ return Triple.isOSBinFormatMachO();
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ // Windows on ARM builds with FPO disabled to aid fast stack walking
+ return true;
+ default:
+ // All other supported Windows ISAs use xdata unwind information, so frame
+ // pointers are not generally useful.
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
+ switch (Triple.getArch()) {
+ default:
+ return false;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ // ARM Darwin targets require a frame pointer to be always present to aid
+ // offline debugging via backtraces.
+ return Triple.isOSDarwin();
+ }
+}
+
+clang::CodeGenOptions::FramePointerKind
+getFramePointerKind(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ // We have 4 states:
+ //
+ // 00) leaf retained, non-leaf retained
+ // 01) leaf retained, non-leaf omitted (this is invalid)
+ // 10) leaf omitted, non-leaf retained
+ // (what -momit-leaf-frame-pointer was designed for)
+ // 11) leaf omitted, non-leaf omitted
+ //
+ // "omit" options taking precedence over "no-omit" options is the only way
+ // to make 3 valid states representable
+ llvm::opt::Arg *A =
+ Args.getLastArg(clang::driver::options::OPT_fomit_frame_pointer,
+ clang::driver::options::OPT_fno_omit_frame_pointer);
+
+ bool OmitFP = A && A->getOption().matches(
+ clang::driver::options::OPT_fomit_frame_pointer);
+ bool NoOmitFP = A && A->getOption().matches(
+ clang::driver::options::OPT_fno_omit_frame_pointer);
+ bool OmitLeafFP =
+ Args.hasFlag(clang::driver::options::OPT_momit_leaf_frame_pointer,
+ clang::driver::options::OPT_mno_omit_leaf_frame_pointer,
+ Triple.isAArch64() || Triple.isPS() || Triple.isVE() ||
+ (Triple.isAndroid() && Triple.isRISCV64()));
+ if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) ||
+ (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) {
+ if (OmitLeafFP)
+ return clang::CodeGenOptions::FramePointerKind::NonLeaf;
+ return clang::CodeGenOptions::FramePointerKind::All;
+ }
+ return clang::CodeGenOptions::FramePointerKind::None;
+}
+
+
static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs,
const StringRef PluginOptPrefix) {
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 0a0951c5386e601..abe8948c5387dce 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/InputInfo.h"
#include "clang/Driver/Multilib.h"
@@ -215,4 +216,7 @@ void addOpenMPDeviceRTL(const Driver &D, const llvm::opt::ArgList &DriverArgs,
} // end namespace driver
} // end namespace clang
+clang::CodeGenOptions::FramePointerKind getFramePointerKind(
+ const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
+
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 8bdd920c3dcbb79..d53bed8e6c1f3b1 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -9,6 +9,7 @@
#include "Flang.h"
#include "CommonArgs.h"
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Driver/Options.h"
#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Support/FileSystem.h"
@@ -606,6 +607,24 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
// Forward -Xflang arguments to -fc1
Args.AddAllArgValues(CmdArgs, options::OPT_Xflang);
+ CodeGenOptions::FramePointerKind FPKeepKind =
+ getFramePointerKind(Args, Triple);
+
+ const char *FPKeepKindStr = nullptr;
+ switch (FPKeepKind) {
+ case CodeGenOptions::FramePointerKind::None:
+ FPKeepKindStr = "-mframe-pointer=none";
+ break;
+ case CodeGenOptions::FramePointerKind::NonLeaf:
+ FPKeepKindStr = "-mframe-pointer=non-leaf";
+ break;
+ case CodeGenOptions::FramePointerKind::All:
+ FPKeepKindStr = "-mframe-pointer=all";
+ break;
+ }
+ assert(FPKeepKindStr && "unknown FramePointerKind");
+ CmdArgs.push_back(FPKeepKindStr);
+
// Forward -mllvm options to the LLVM option parser. In practice, this means
// forwarding to `-fc1` as that's where the LLVM parser is run.
for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 72e7bdab12a14da..d9e6cdfda8598bb 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -38,6 +38,7 @@ CODEGENOPT(Underscoring, 1, 1)
ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use.
ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate
ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use
+ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index a3c39bda10667be..9ccd567678be95f 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -49,6 +49,29 @@ class CodeGenOptionsBase {
class CodeGenOptions : public CodeGenOptionsBase {
public:
+ //Added
+ ///*
+ enum class FramePointerKind {
+ None, // Omit all frame pointers.
+ NonLeaf, // Keep non-leaf frame pointers.
+ All, // Keep all frame pointers.
+ };
+
+ static llvm::StringRef getFramePointerKindName(FramePointerKind Kind) {
+ switch (Kind) {
+ case FramePointerKind::None:
+ return "none";
+ case FramePointerKind::NonLeaf:
+ return "non-leaf";
+ case FramePointerKind::All:
+ return "all";
+ }
+
+ llvm_unreachable("invalid FramePointerKind");
+ };
+ //
+ //*/
+
/// The paths to the pass plugins that were registered using -fpass-plugin.
std::vector<std::string> LLVMPassPlugins;
diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h
index ddec70fa9824c52..7fc5776a61abc5d 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -44,6 +44,8 @@ struct MLIRToLLVMPassPipelineConfig {
bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR
llvm::codegenoptions::DebugInfoKind DebugInfo =
llvm::codegenoptions::NoDebugInfo; ///< Debug info generation.
+ llvm::FramePointerKind FramePointer =
+ llvm::FramePointerKind::None; ///< FramePointerInfo
unsigned VScaleMin = 0; ///< SVE vector range minimum.
unsigned VScaleMax = 0; ///< SVE vector range maximum.
};
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 334da3ac287e3bf..4340981ae9d642a 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -247,6 +247,19 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
clang::driver::options::OPT_fno_alias_analysis,
/*default=*/false);
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) {
+ llvm::StringRef s = a->getValue();
+ assert(s == "none" || s == "non-leaf"|| s == "all");
+ if (s == "none")
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::None);
+ else
+ if (s == "non-leaf")
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::NonLeaf);
+ else
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::All);
+ }
+
for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ))
opts.LLVMPassPlugins.push_back(a->getValue());
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index d7ca7b66584dd52..06273a07e84f2a0 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -783,6 +783,11 @@ void CodeGenAction::generateLLVMIR() {
llvmModule->setPIELevel(
static_cast<llvm::PIELevel::Level>(opts.PICLevel));
}
+
+ // Set FramePointer LLVM module flag.
+ llvmModule->setFramePointer(
+ static_cast<llvm::FramePointerKind>(opts.getFramePointer()));
+
}
bool CodeGenAction::setUpTargetMachine() {
diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90
index b276f1906e1a457..57a1710709940f3 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -74,6 +74,7 @@
! CHECK-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default)
! CHECK-NEXT: -fno-version-loops-for-stride
! CHECK-NEXT: Do not create unit-strided loops (default)
+! CHECK-NEXT: -fomit-frame-pointer Omit the frame pointer from functions that don't need it. Some...
[truncated]
|
@llvm/pr-subscribers-flang-driver Author: Radu Salavat (Radu2k) ChangesAdd support for frame pointers in Flang. Patch is 22.74 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/72146.diff 13 Files Affected:
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index d1b67a448b2a59b..bf99786d017b318 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3147,7 +3147,8 @@ def fno_ms_compatibility : Flag<["-"], "fno-ms-compatibility">, Group<f_Group>,
def fno_objc_legacy_dispatch : Flag<["-"], "fno-objc-legacy-dispatch">, Group<f_Group>;
def fno_objc_weak : Flag<["-"], "fno-objc-weak">, Group<f_Group>,
Visibility<[ClangOption, CC1Option]>;
-def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>;
+def fno_omit_frame_pointer : Flag<["-"], "fno-omit-frame-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>;
defm operator_names : BoolFOption<"operator-names",
LangOpts<"CXXOperatorNames">, Default<cplusplus.KeyPath>,
NegFlag<SetFalse, [], [ClangOption, CC1Option],
@@ -3273,6 +3274,7 @@ defm objc_avoid_heapify_local_blocks : BoolFOption<"objc-avoid-heapify-local-blo
BothFlags<[], [CC1Option], " to avoid heapifying local blocks">>;
def fomit_frame_pointer : Flag<["-"], "fomit-frame-pointer">, Group<f_Group>,
+ Visibility<[ClangOption, FlangOption]>,
HelpText<"Omit the frame pointer from functions that don't need it. "
"Some stack unwinding cases, such as profilers and sanitizers, may prefer specifying -fno-omit-frame-pointer. "
"On many targets, -O1 and higher omit the frame pointer by default. "
@@ -6752,10 +6754,7 @@ def new_struct_path_tbaa : Flag<["-"], "new-struct-path-tbaa">,
def mdebug_pass : Separate<["-"], "mdebug-pass">,
HelpText<"Enable additional debug output">,
MarshallingInfoString<CodeGenOpts<"DebugPass">>;
-def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
- HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">,
- NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
- MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
+
def mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">,
HelpText<"Use IEEE 754 quadruple-precision for long double">,
MarshallingInfoFlag<LangOpts<"PPCIEEELongDouble">>;
@@ -7368,6 +7367,11 @@ def pic_level : Separate<["-"], "pic-level">,
def pic_is_pie : Flag<["-"], "pic-is-pie">,
HelpText<"File is for a position independent executable">,
MarshallingInfoFlag<LangOpts<"PIE">>;
+
+def mframe_pointer_EQ : Joined<["-"], "mframe-pointer=">,
+ HelpText<"Specify which frame pointers to retain.">, Values<"all,non-leaf,none">,
+ NormalizedValuesScope<"CodeGenOptions::FramePointerKind">, NormalizedValues<["All", "NonLeaf", "None"]>,
+ MarshallingInfoEnum<CodeGenOpts<"FramePointer">, "None">;
} // let Visibility = [CC1Option, FC1Option]
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 3b98c7ae6e6ec66..3273bd1d2c0c6fa 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -409,139 +409,6 @@ static bool ShouldEnableAutolink(const ArgList &Args, const ToolChain &TC,
Default);
}
-static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
- switch (Triple.getArch()){
- default:
- return false;
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- // ARM Darwin targets require a frame pointer to be always present to aid
- // offline debugging via backtraces.
- return Triple.isOSDarwin();
- }
-}
-
-static bool useFramePointerForTargetByDefault(const ArgList &Args,
- const llvm::Triple &Triple) {
- if (Args.hasArg(options::OPT_pg) && !Args.hasArg(options::OPT_mfentry))
- return true;
-
- if (Triple.isAndroid()) {
- switch (Triple.getArch()) {
- case llvm::Triple::aarch64:
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- case llvm::Triple::riscv64:
- return true;
- default:
- break;
- }
- }
-
- switch (Triple.getArch()) {
- case llvm::Triple::xcore:
- case llvm::Triple::wasm32:
- case llvm::Triple::wasm64:
- case llvm::Triple::msp430:
- // XCore never wants frame pointers, regardless of OS.
- // WebAssembly never wants frame pointers.
- return false;
- case llvm::Triple::ppc:
- case llvm::Triple::ppcle:
- case llvm::Triple::ppc64:
- case llvm::Triple::ppc64le:
- case llvm::Triple::riscv32:
- case llvm::Triple::riscv64:
- case llvm::Triple::sparc:
- case llvm::Triple::sparcel:
- case llvm::Triple::sparcv9:
- case llvm::Triple::amdgcn:
- case llvm::Triple::r600:
- case llvm::Triple::csky:
- case llvm::Triple::loongarch32:
- case llvm::Triple::loongarch64:
- return !areOptimizationsEnabled(Args);
- default:
- break;
- }
-
- if (Triple.isOSFuchsia() || Triple.isOSNetBSD()) {
- return !areOptimizationsEnabled(Args);
- }
-
- if (Triple.isOSLinux() || Triple.isOSHurd()) {
- switch (Triple.getArch()) {
- // Don't use a frame pointer on linux if optimizing for certain targets.
- case llvm::Triple::arm:
- case llvm::Triple::armeb:
- case llvm::Triple::thumb:
- case llvm::Triple::thumbeb:
- case llvm::Triple::mips64:
- case llvm::Triple::mips64el:
- case llvm::Triple::mips:
- case llvm::Triple::mipsel:
- case llvm::Triple::systemz:
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- return !areOptimizationsEnabled(Args);
- default:
- return true;
- }
- }
-
- if (Triple.isOSWindows()) {
- switch (Triple.getArch()) {
- case llvm::Triple::x86:
- return !areOptimizationsEnabled(Args);
- case llvm::Triple::x86_64:
- return Triple.isOSBinFormatMachO();
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- // Windows on ARM builds with FPO disabled to aid fast stack walking
- return true;
- default:
- // All other supported Windows ISAs use xdata unwind information, so frame
- // pointers are not generally useful.
- return false;
- }
- }
-
- return true;
-}
-
-static CodeGenOptions::FramePointerKind
-getFramePointerKind(const ArgList &Args, const llvm::Triple &Triple) {
- // We have 4 states:
- //
- // 00) leaf retained, non-leaf retained
- // 01) leaf retained, non-leaf omitted (this is invalid)
- // 10) leaf omitted, non-leaf retained
- // (what -momit-leaf-frame-pointer was designed for)
- // 11) leaf omitted, non-leaf omitted
- //
- // "omit" options taking precedence over "no-omit" options is the only way
- // to make 3 valid states representable
- Arg *A = Args.getLastArg(options::OPT_fomit_frame_pointer,
- options::OPT_fno_omit_frame_pointer);
- bool OmitFP = A && A->getOption().matches(options::OPT_fomit_frame_pointer);
- bool NoOmitFP =
- A && A->getOption().matches(options::OPT_fno_omit_frame_pointer);
- bool OmitLeafFP =
- Args.hasFlag(options::OPT_momit_leaf_frame_pointer,
- options::OPT_mno_omit_leaf_frame_pointer,
- Triple.isAArch64() || Triple.isPS() || Triple.isVE() ||
- (Triple.isAndroid() && Triple.isRISCV64()));
- if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) ||
- (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) {
- if (OmitLeafFP)
- return CodeGenOptions::FramePointerKind::NonLeaf;
- return CodeGenOptions::FramePointerKind::All;
- }
- return CodeGenOptions::FramePointerKind::None;
-}
-
/// Add a CC1 option to specify the debug compilation directory.
static const char *addDebugCompDirArg(const ArgList &Args,
ArgStringList &CmdArgs,
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index 5d2cd1959b06925..f81bca14363a22a 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -24,6 +24,7 @@
#include "MSP430.h"
#include "Solaris.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/ObjCRuntime.h"
#include "clang/Basic/Version.h"
@@ -71,6 +72,146 @@ using namespace clang::driver::tools;
using namespace clang;
using namespace llvm::opt;
+static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ if (Args.hasArg(clang::driver::options::OPT_pg) &&
+ !Args.hasArg(clang::driver::options::OPT_mfentry))
+ return true;
+
+ if (Triple.isAndroid()) {
+ switch (Triple.getArch()) {
+ case llvm::Triple::aarch64:
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::riscv64:
+ return true;
+ default:
+ break;
+ }
+ }
+
+ switch (Triple.getArch()) {
+ case llvm::Triple::xcore:
+ case llvm::Triple::wasm32:
+ case llvm::Triple::wasm64:
+ case llvm::Triple::msp430:
+ // XCore never wants frame pointers, regardless of OS.
+ // WebAssembly never wants frame pointers.
+ return false;
+ case llvm::Triple::ppc:
+ case llvm::Triple::ppcle:
+ case llvm::Triple::ppc64:
+ case llvm::Triple::ppc64le:
+ case llvm::Triple::riscv32:
+ case llvm::Triple::riscv64:
+ case llvm::Triple::sparc:
+ case llvm::Triple::sparcel:
+ case llvm::Triple::sparcv9:
+ case llvm::Triple::amdgcn:
+ case llvm::Triple::r600:
+ case llvm::Triple::csky:
+ case llvm::Triple::loongarch32:
+ case llvm::Triple::loongarch64:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ default:
+ break;
+ }
+
+ if (Triple.isOSFuchsia() || Triple.isOSNetBSD()) {
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ }
+
+ //if (Triple.isOSLinux() || Triple.getOS() == llvm::Triple::CloudABI ||
+ if (Triple.isOSLinux() || Triple.isOSHurd()) {
+ switch (Triple.getArch()) {
+ // Don't use a frame pointer on linux if optimizing for certain targets.
+ case llvm::Triple::arm:
+ case llvm::Triple::armeb:
+ case llvm::Triple::thumb:
+ case llvm::Triple::thumbeb:
+ case llvm::Triple::mips64:
+ case llvm::Triple::mips64el:
+ case llvm::Triple::mips:
+ case llvm::Triple::mipsel:
+ case llvm::Triple::systemz:
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ default:
+ return true;
+ }
+ }
+
+ if (Triple.isOSWindows()) {
+ switch (Triple.getArch()) {
+ case llvm::Triple::x86:
+ return !clang::driver::tools::areOptimizationsEnabled(Args);
+ case llvm::Triple::x86_64:
+ return Triple.isOSBinFormatMachO();
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ // Windows on ARM builds with FPO disabled to aid fast stack walking
+ return true;
+ default:
+ // All other supported Windows ISAs use xdata unwind information, so frame
+ // pointers are not generally useful.
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) {
+ switch (Triple.getArch()) {
+ default:
+ return false;
+ case llvm::Triple::arm:
+ case llvm::Triple::thumb:
+ // ARM Darwin targets require a frame pointer to be always present to aid
+ // offline debugging via backtraces.
+ return Triple.isOSDarwin();
+ }
+}
+
+clang::CodeGenOptions::FramePointerKind
+getFramePointerKind(const llvm::opt::ArgList &Args,
+ const llvm::Triple &Triple) {
+ // We have 4 states:
+ //
+ // 00) leaf retained, non-leaf retained
+ // 01) leaf retained, non-leaf omitted (this is invalid)
+ // 10) leaf omitted, non-leaf retained
+ // (what -momit-leaf-frame-pointer was designed for)
+ // 11) leaf omitted, non-leaf omitted
+ //
+ // "omit" options taking precedence over "no-omit" options is the only way
+ // to make 3 valid states representable
+ llvm::opt::Arg *A =
+ Args.getLastArg(clang::driver::options::OPT_fomit_frame_pointer,
+ clang::driver::options::OPT_fno_omit_frame_pointer);
+
+ bool OmitFP = A && A->getOption().matches(
+ clang::driver::options::OPT_fomit_frame_pointer);
+ bool NoOmitFP = A && A->getOption().matches(
+ clang::driver::options::OPT_fno_omit_frame_pointer);
+ bool OmitLeafFP =
+ Args.hasFlag(clang::driver::options::OPT_momit_leaf_frame_pointer,
+ clang::driver::options::OPT_mno_omit_leaf_frame_pointer,
+ Triple.isAArch64() || Triple.isPS() || Triple.isVE() ||
+ (Triple.isAndroid() && Triple.isRISCV64()));
+ if (NoOmitFP || mustUseNonLeafFramePointerForTarget(Triple) ||
+ (!OmitFP && useFramePointerForTargetByDefault(Args, Triple))) {
+ if (OmitLeafFP)
+ return clang::CodeGenOptions::FramePointerKind::NonLeaf;
+ return clang::CodeGenOptions::FramePointerKind::All;
+ }
+ return clang::CodeGenOptions::FramePointerKind::None;
+}
+
+
static void renderRpassOptions(const ArgList &Args, ArgStringList &CmdArgs,
const StringRef PluginOptPrefix) {
if (const Arg *A = Args.getLastArg(options::OPT_Rpass_EQ))
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.h b/clang/lib/Driver/ToolChains/CommonArgs.h
index 0a0951c5386e601..abe8948c5387dce 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.h
+++ b/clang/lib/Driver/ToolChains/CommonArgs.h
@@ -9,6 +9,7 @@
#ifndef LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
#define LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/InputInfo.h"
#include "clang/Driver/Multilib.h"
@@ -215,4 +216,7 @@ void addOpenMPDeviceRTL(const Driver &D, const llvm::opt::ArgList &DriverArgs,
} // end namespace driver
} // end namespace clang
+clang::CodeGenOptions::FramePointerKind getFramePointerKind(
+ const llvm::opt::ArgList &Args, const llvm::Triple &Triple);
+
#endif // LLVM_CLANG_LIB_DRIVER_TOOLCHAINS_COMMONARGS_H
diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp
index 8bdd920c3dcbb79..d53bed8e6c1f3b1 100644
--- a/clang/lib/Driver/ToolChains/Flang.cpp
+++ b/clang/lib/Driver/ToolChains/Flang.cpp
@@ -9,6 +9,7 @@
#include "Flang.h"
#include "CommonArgs.h"
+#include "clang/Basic/CodeGenOptions.h"
#include "clang/Driver/Options.h"
#include "llvm/Frontend/Debug/Options.h"
#include "llvm/Support/FileSystem.h"
@@ -606,6 +607,24 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA,
// Forward -Xflang arguments to -fc1
Args.AddAllArgValues(CmdArgs, options::OPT_Xflang);
+ CodeGenOptions::FramePointerKind FPKeepKind =
+ getFramePointerKind(Args, Triple);
+
+ const char *FPKeepKindStr = nullptr;
+ switch (FPKeepKind) {
+ case CodeGenOptions::FramePointerKind::None:
+ FPKeepKindStr = "-mframe-pointer=none";
+ break;
+ case CodeGenOptions::FramePointerKind::NonLeaf:
+ FPKeepKindStr = "-mframe-pointer=non-leaf";
+ break;
+ case CodeGenOptions::FramePointerKind::All:
+ FPKeepKindStr = "-mframe-pointer=all";
+ break;
+ }
+ assert(FPKeepKindStr && "unknown FramePointerKind");
+ CmdArgs.push_back(FPKeepKindStr);
+
// Forward -mllvm options to the LLVM option parser. In practice, this means
// forwarding to `-fc1` as that's where the LLVM parser is run.
for (const Arg *A : Args.filtered(options::OPT_mllvm)) {
diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def
index 72e7bdab12a14da..d9e6cdfda8598bb 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.def
+++ b/flang/include/flang/Frontend/CodeGenOptions.def
@@ -38,6 +38,7 @@ CODEGENOPT(Underscoring, 1, 1)
ENUM_CODEGENOPT(RelocationModel, llvm::Reloc::Model, 3, llvm::Reloc::PIC_) ///< Name of the relocation model to use.
ENUM_CODEGENOPT(DebugInfo, llvm::codegenoptions::DebugInfoKind, 4, llvm::codegenoptions::NoDebugInfo) ///< Level of debug info to generate
ENUM_CODEGENOPT(VecLib, llvm::driver::VectorLibrary, 3, llvm::driver::VectorLibrary::NoLibrary) ///< Vector functions library to use
+ENUM_CODEGENOPT(FramePointer, FramePointerKind, 2, FramePointerKind::None) /// frame-pointer: all,non-leaf,none
#undef CODEGENOPT
#undef ENUM_CODEGENOPT
diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h
index a3c39bda10667be..9ccd567678be95f 100644
--- a/flang/include/flang/Frontend/CodeGenOptions.h
+++ b/flang/include/flang/Frontend/CodeGenOptions.h
@@ -49,6 +49,29 @@ class CodeGenOptionsBase {
class CodeGenOptions : public CodeGenOptionsBase {
public:
+ //Added
+ ///*
+ enum class FramePointerKind {
+ None, // Omit all frame pointers.
+ NonLeaf, // Keep non-leaf frame pointers.
+ All, // Keep all frame pointers.
+ };
+
+ static llvm::StringRef getFramePointerKindName(FramePointerKind Kind) {
+ switch (Kind) {
+ case FramePointerKind::None:
+ return "none";
+ case FramePointerKind::NonLeaf:
+ return "non-leaf";
+ case FramePointerKind::All:
+ return "all";
+ }
+
+ llvm_unreachable("invalid FramePointerKind");
+ };
+ //
+ //*/
+
/// The paths to the pass plugins that were registered using -fpass-plugin.
std::vector<std::string> LLVMPassPlugins;
diff --git a/flang/include/flang/Tools/CrossToolHelpers.h b/flang/include/flang/Tools/CrossToolHelpers.h
index ddec70fa9824c52..7fc5776a61abc5d 100644
--- a/flang/include/flang/Tools/CrossToolHelpers.h
+++ b/flang/include/flang/Tools/CrossToolHelpers.h
@@ -44,6 +44,8 @@ struct MLIRToLLVMPassPipelineConfig {
bool AliasAnalysis = false; ///< Add TBAA tags to generated LLVMIR
llvm::codegenoptions::DebugInfoKind DebugInfo =
llvm::codegenoptions::NoDebugInfo; ///< Debug info generation.
+ llvm::FramePointerKind FramePointer =
+ llvm::FramePointerKind::None; ///< FramePointerInfo
unsigned VScaleMin = 0; ///< SVE vector range minimum.
unsigned VScaleMax = 0; ///< SVE vector range maximum.
};
diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp
index 334da3ac287e3bf..4340981ae9d642a 100644
--- a/flang/lib/Frontend/CompilerInvocation.cpp
+++ b/flang/lib/Frontend/CompilerInvocation.cpp
@@ -247,6 +247,19 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts,
clang::driver::options::OPT_fno_alias_analysis,
/*default=*/false);
+ if (const llvm::opt::Arg *a =
+ args.getLastArg(clang::driver::options::OPT_mframe_pointer_EQ)) {
+ llvm::StringRef s = a->getValue();
+ assert(s == "none" || s == "non-leaf"|| s == "all");
+ if (s == "none")
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::None);
+ else
+ if (s == "non-leaf")
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::NonLeaf);
+ else
+ opts.setFramePointer(CodeGenOptions::FramePointerKind::All);
+ }
+
for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ))
opts.LLVMPassPlugins.push_back(a->getValue());
diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index d7ca7b66584dd52..06273a07e84f2a0 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -783,6 +783,11 @@ void CodeGenAction::generateLLVMIR() {
llvmModule->setPIELevel(
static_cast<llvm::PIELevel::Level>(opts.PICLevel));
}
+
+ // Set FramePointer LLVM module flag.
+ llvmModule->setFramePointer(
+ static_cast<llvm::FramePointerKind>(opts.getFramePointer()));
+
}
bool CodeGenAction::setUpTargetMachine() {
diff --git a/flang/test/Driver/driver-help-hidden.f90 b/flang/test/Driver/driver-help-hidden.f90
index b276f1906e1a457..57a1710709940f3 100644
--- a/flang/test/Driver/driver-help-hidden.f90
+++ b/flang/test/Driver/driver-help-hidden.f90
@@ -74,6 +74,7 @@
! CHECK-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default)
! CHECK-NEXT: -fno-version-loops-for-stride
! CHECK-NEXT: Do not create unit-strided loops (default)
+! CHECK-NEXT: -fomit-frame-pointer Omit the frame pointer from functions that don't need it. Some...
[truncated]
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small fix.
b9a8d57
to
0b0f02e
Compare
Could you add some tests? In e.g. "driver-help.f90" we merely test that a flag is visible. |
…nnecessary frontend integration
I see that you added frame-pointer-codegen.f90, but that does not test how flags added in this patch impact code-gen. Please add a test that will demonstrate how this flag impacts the generated code. |
CmdArgs.push_back("-lrt"); | ||
CmdArgs.push_back("-lrt"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the following changes in this file are unrelated and merely formatting fixes. Please, could you reduce the noise and revert these? I am happy for you to submit them as a separate PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I guess it isn't wrong, it feels weird do declare all of the storage on the front end driver side, but never set them (the member of the CodeGenOpttions class, the changes in Frontend/CodeGenOptions.h, adding it to MLIRToLLVMPassPipelineConfig).
This might be a bit nitpicky but I would either remove these changes or add frontend driver code to read the argument and set it in the MLIRToLLVMPassPipelineConfig and CodeGenOptions (although this would be untestable so others may disagree).
With regard to the front end driver stuff, I don't know if we gain anything by adding a flang specific definition of the enum in CodeGenOptions.h, as we will just convert to an llvm::FramePointerKind to populate MLIRToLLVMPassPipelineConfig. If you're sure that the llvm version is the one you want to use in MLIRToLLVMPassPipelineConfig, then just use that same type in flang::CodeGenOptions too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the update. See my previous comment about the changes to MLIRToLLVMPassPipelineConfig
and CodeGenOptions.def
.
@@ -49,6 +49,7 @@ class CodeGenOptionsBase { | |||
class CodeGenOptions : public CodeGenOptionsBase { | |||
|
|||
public: | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: unrelated change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, thanks!
But please fix code formatting before merging |
Merged manually ea4eb69 |
Add support for frame pointers in Flang.