https://github.com/Radu2k updated https://github.com/llvm/llvm-project/pull/72146
>From 0b0f02eab4dc02adf79461bc865be6f7580938cf Mon Sep 17 00:00:00 2001 From: Radu2k <radusalava...@gmail.com> Date: Mon, 13 Nov 2023 17:49:06 +0000 Subject: [PATCH 1/7] [Flang][Clang] Add support for frame pointers in Flang --- clang/include/clang/Driver/Options.td | 14 +- clang/lib/Driver/ToolChains/Clang.cpp | 133 ----------------- clang/lib/Driver/ToolChains/CommonArgs.cpp | 141 ++++++++++++++++++ clang/lib/Driver/ToolChains/CommonArgs.h | 4 + clang/lib/Driver/ToolChains/Flang.cpp | 19 +++ .../include/flang/Frontend/CodeGenOptions.def | 1 + flang/include/flang/Frontend/CodeGenOptions.h | 23 +++ flang/include/flang/Tools/CrossToolHelpers.h | 2 + flang/lib/Frontend/CompilerInvocation.cpp | 13 ++ flang/lib/Frontend/FrontendActions.cpp | 5 + flang/test/Driver/driver-help-hidden.f90 | 1 + flang/test/Driver/driver-help.f90 | 2 + flang/test/Driver/frontend-forwarding.f90 | 2 + 13 files changed, 222 insertions(+), 138 deletions(-) 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 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. -m[no-]omit-leaf-frame-pointer takes precedence for leaf functions ! CHECK-NEXT: -fopenacc Enable OpenACC ! CHECK-NEXT: -fopenmp-assume-no-nested-parallelism ! CHECK-NEXT: Assert no nested parallel regions in the GPU diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index ea9c892bd621058..a6c4012362c1e22 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -207,6 +207,7 @@ ! HELP-FC1-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default) ! HELP-FC1-NEXT: -fno-version-loops-for-stride ! HELP-FC1-NEXT: Do not create unit-strided loops (default) +! HELP-FC1-NEXT: -fomit-frame-pointer 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. -m[no-]omit-leaf-frame-pointer takes precedence for leaf functions ! HELP-FC1-NEXT: -fopenacc Enable OpenACC ! HELP-FC1-NEXT: -fopenmp-host-ir-file-path <value> ! HELP-FC1-NEXT: Path to the IR file produced by the frontend for the host. @@ -233,6 +234,7 @@ ! HELP-FC1-NEXT: -load <dsopath> Load the named plugin (dynamic shared object) ! HELP-FC1-NEXT: -menable-no-infs Allow optimization to assume there are no infinities. ! HELP-FC1-NEXT: -menable-no-nans Allow optimization to assume there are no NaNs. +! HELP-FC1-NEXT: -mframe-pointer=<value> Specify which frame pointers to retain. ! HELP-FC1-NEXT: -mllvm <value> Additional arguments to forward to LLVM's option processing ! HELP-FC1-NEXT: -mmlir <value> Additional arguments to forward to MLIR's option processing ! HELP-FC1-NEXT: -module-dir <dir> Put MODULE files in <dir> diff --git a/flang/test/Driver/frontend-forwarding.f90 b/flang/test/Driver/frontend-forwarding.f90 index 20455791c9ff4d6..8e9c9b78c3c10a4 100644 --- a/flang/test/Driver/frontend-forwarding.f90 +++ b/flang/test/Driver/frontend-forwarding.f90 @@ -14,6 +14,7 @@ ! RUN: -fno-signed-zeros \ ! RUN: -fassociative-math \ ! RUN: -freciprocal-math \ +! RUN: -fomit-frame-pointer \ ! RUN: -fpass-plugin=Bye%pluginext \ ! RUN: -fversion-loops-for-stride \ ! RUN: -flang-experimental-polymorphism \ @@ -60,5 +61,6 @@ ! CHECK: "-Reverything" ! CHECK: "-Rno-everything" ! CHECK: "-Rpass=inline" +! CHECK: "-mframe-pointer=none" ! CHECK: "-mllvm" "-print-before-all" ! CHECK: "-save-temps=obj" >From 287bb689ab0bb94ebf63333aebb0891b3412cfd1 Mon Sep 17 00:00:00 2001 From: Radu2k <radusalava...@gmail.com> Date: Tue, 14 Nov 2023 11:16:29 +0000 Subject: [PATCH 2/7] Clang-format issues resolved --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 2 -- clang/lib/Driver/ToolChains/CommonArgs.h | 4 ++-- clang/lib/Driver/ToolChains/Flang.cpp | 2 +- flang/include/flang/Frontend/CodeGenOptions.h | 11 ++++------- flang/lib/Frontend/CompilerInvocation.cpp | 10 +++++----- flang/lib/Frontend/FrontendActions.cpp | 3 +-- flang/test/Driver/driver-help.f90 | 2 +- 7 files changed, 14 insertions(+), 20 deletions(-) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index f81bca14363a22a..c85d87f9d856293 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -123,7 +123,6 @@ static bool useFramePointerForTargetByDefault(const llvm::opt::ArgList &Args, 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. @@ -211,7 +210,6 @@ getFramePointerKind(const llvm::opt::ArgList &Args, 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 abe8948c5387dce..25d68345a9f9ebf 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.h +++ b/clang/lib/Driver/ToolChains/CommonArgs.h @@ -216,7 +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); +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 d53bed8e6c1f3b1..0b584941ecb0b83 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -608,7 +608,7 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, Args.AddAllArgValues(CmdArgs, options::OPT_Xflang); CodeGenOptions::FramePointerKind FPKeepKind = - getFramePointerKind(Args, Triple); + getFramePointerKind(Args, Triple); const char *FPKeepKindStr = nullptr; switch (FPKeepKind) { diff --git a/flang/include/flang/Frontend/CodeGenOptions.h b/flang/include/flang/Frontend/CodeGenOptions.h index 9ccd567678be95f..420ee1727c444cc 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -49,12 +49,11 @@ class CodeGenOptionsBase { class CodeGenOptions : public CodeGenOptionsBase { public: - //Added - ///* + /// The type of frame pointer used enum class FramePointerKind { - None, // Omit all frame pointers. - NonLeaf, // Keep non-leaf frame pointers. - All, // Keep all frame pointers. + None, // Omit all frame pointers. + NonLeaf, // Keep non-leaf frame pointers. + All, // Keep all frame pointers. }; static llvm::StringRef getFramePointerKindName(FramePointerKind Kind) { @@ -69,8 +68,6 @@ class CodeGenOptions : public CodeGenOptionsBase { 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/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 4340981ae9d642a..ab9727cbc57d48d 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -250,14 +250,14 @@ static void parseCodeGenArgs(Fortran::frontend::CodeGenOptions &opts, 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"); + 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 - if (s == "non-leaf") - opts.setFramePointer(CodeGenOptions::FramePointerKind::NonLeaf); - else - opts.setFramePointer(CodeGenOptions::FramePointerKind::All); + opts.setFramePointer(CodeGenOptions::FramePointerKind::All); } for (auto *a : args.filtered(clang::driver::options::OPT_fpass_plugin_EQ)) diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 06273a07e84f2a0..f4bf5b0da09cb3b 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -786,8 +786,7 @@ void CodeGenAction::generateLLVMIR() { // Set FramePointer LLVM module flag. llvmModule->setFramePointer( - static_cast<llvm::FramePointerKind>(opts.getFramePointer())); - + static_cast<llvm::FramePointerKind>(opts.getFramePointer())); } bool CodeGenAction::setUpTargetMachine() { diff --git a/flang/test/Driver/driver-help.f90 b/flang/test/Driver/driver-help.f90 index a6c4012362c1e22..b8cf50c4ae24bdf 100644 --- a/flang/test/Driver/driver-help.f90 +++ b/flang/test/Driver/driver-help.f90 @@ -64,6 +64,7 @@ ! HELP-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default) ! HELP-NEXT: -fno-version-loops-for-stride ! HELP-NEXT: Do not create unit-strided loops (default) +! HELP-NEXT: -fomit-frame-pointer 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. -m[no-]omit-leaf-frame-pointer takes precedence for leaf functions ! HELP-NEXT: -fopenacc Enable OpenACC ! HELP-NEXT: -fopenmp-target-debug Enable debugging in the OpenMP offloading device RTL ! HELP-NEXT: -fopenmp-targets=<value> @@ -207,7 +208,6 @@ ! HELP-FC1-NEXT: -fno-stack-arrays Allocate array temporaries on the heap (default) ! HELP-FC1-NEXT: -fno-version-loops-for-stride ! HELP-FC1-NEXT: Do not create unit-strided loops (default) -! HELP-FC1-NEXT: -fomit-frame-pointer 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. -m[no-]omit-leaf-frame-pointer takes precedence for leaf functions ! HELP-FC1-NEXT: -fopenacc Enable OpenACC ! HELP-FC1-NEXT: -fopenmp-host-ir-file-path <value> ! HELP-FC1-NEXT: Path to the IR file produced by the frontend for the host. >From ad66716ce09bb31463a8eb4eb21168de25704483 Mon Sep 17 00:00:00 2001 From: Radu2k <radusalava...@gmail.com> Date: Tue, 14 Nov 2023 23:40:23 +0000 Subject: [PATCH 3/7] Resolved additional format issues --- clang/include/clang/Driver/Options.td | 2 +- clang/lib/Driver/ToolChains/CommonArgs.cpp | 80 ++++++++++++---------- flang/lib/Frontend/FrontendActions.cpp | 2 +- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index bf99786d017b318..c6dc40023428eb4 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -7367,7 +7367,7 @@ 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"]>, diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index c85d87f9d856293..062d6c644ef4b75 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -175,7 +175,7 @@ static bool mustUseNonLeafFramePointerForTarget(const llvm::Triple &Triple) { } } -clang::CodeGenOptions::FramePointerKind +clang::CodeGenOptions::FramePointerKind getFramePointerKind(const llvm::opt::ArgList &Args, const llvm::Triple &Triple) { // We have 4 states: @@ -1099,7 +1099,7 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, CmdArgs.push_back("-Bdynamic"); if (RTKind == Driver::OMPRT_GOMP && GompNeedsRT) - CmdArgs.push_back("-lrt"); + CmdArgs.push_back("-lrt"); if (IsOffloadingHost) CmdArgs.push_back("-lomptarget"); @@ -1184,10 +1184,12 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args, bool IsShared, bool IsWhole) { // Wrap any static runtimes that must be forced into executable in // whole-archive. - if (IsWhole) CmdArgs.push_back("--whole-archive"); + if (IsWhole) + CmdArgs.push_back("--whole-archive"); CmdArgs.push_back(TC.getCompilerRTArgString( Args, Sanitizer, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static)); - if (IsWhole) CmdArgs.push_back("--no-whole-archive"); + if (IsWhole) + CmdArgs.push_back("--no-whole-archive"); if (IsShared) { addArchSpecificRPath(TC, Args, CmdArgs); @@ -1254,8 +1256,7 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, TC.getTriple().getOS() != llvm::Triple::RTEMS) CmdArgs.push_back("-ldl"); // Required for backtrace on some OSes - if (TC.getTriple().isOSFreeBSD() || - TC.getTriple().isOSNetBSD() || + if (TC.getTriple().isOSFreeBSD() || TC.getTriple().isOSNetBSD() || TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lexecinfo"); // There is no libresolv on Android, FreeBSD, OpenBSD, etc. On musl @@ -1324,7 +1325,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, // Each static runtime that has a DSO counterpart above is excluded below, // but runtimes that exist only as static are not affected by needsSharedRt. - if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt() && + SanArgs.linkRuntimes()) { StaticRuntimes.push_back("asan"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("asan_cxx"); @@ -1337,7 +1339,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("memprof_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && + SanArgs.linkRuntimes()) { if (SanArgs.needsHwasanAliasesRt()) { StaticRuntimes.push_back("hwasan_aliases"); if (SanArgs.linkCXXRuntimes()) @@ -1363,7 +1366,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("tsan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && + SanArgs.linkRuntimes()) { if (SanArgs.requiresMinimalRuntime()) { StaticRuntimes.push_back("ubsan_minimal"); } else { @@ -1376,7 +1380,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, NonWholeStaticRuntimes.push_back("safestack"); RequiredSymbols.push_back("__safestack_init"); } - if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes())) { + if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && + SanArgs.linkRuntimes())) { if (SanArgs.needsCfiRt() && SanArgs.linkRuntimes()) StaticRuntimes.push_back("cfi"); if (SanArgs.needsCfiDiagRt() && SanArgs.linkRuntimes()) { @@ -1389,7 +1394,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, NonWholeStaticRuntimes.push_back("stats"); RequiredSymbols.push_back("__sanitizer_stats_register"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && + SanArgs.linkRuntimes()) { StaticRuntimes.push_back("scudo_standalone"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("scudo_standalone_cxx"); @@ -1467,7 +1473,8 @@ bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty(); } -bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringList &CmdArgs) { +bool tools::addXRayRuntime(const ToolChain &TC, const ArgList &Args, + ArgStringList &CmdArgs) { if (Args.hasArg(options::OPT_shared)) return false; @@ -1492,8 +1499,7 @@ void tools::linkXRayRuntimeDeps(const ToolChain &TC, CmdArgs.push_back("-lrt"); CmdArgs.push_back("-lm"); - if (!TC.getTriple().isOSFreeBSD() && - !TC.getTriple().isOSNetBSD() && + if (!TC.getTriple().isOSFreeBSD() && !TC.getTriple().isOSNetBSD() && !TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-ldl"); } @@ -1784,19 +1790,19 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { bool EmbeddedPISupported; switch (Triple.getArch()) { - case llvm::Triple::arm: - case llvm::Triple::armeb: - case llvm::Triple::thumb: - case llvm::Triple::thumbeb: - EmbeddedPISupported = true; - break; - default: - EmbeddedPISupported = false; - break; + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: + EmbeddedPISupported = true; + break; + default: + EmbeddedPISupported = false; + break; } bool ROPI = false, RWPI = false; - Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi); + Arg *LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi); if (LastROPIArg && LastROPIArg->getOption().matches(options::OPT_fropi)) { if (!EmbeddedPISupported) ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target) @@ -1825,7 +1831,7 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { if (ABIName == "n64") PIC = true; // When targettng MIPS with -mno-abicalls, it's always static. - if(Args.hasArg(options::OPT_mno_abicalls)) + if (Args.hasArg(options::OPT_mno_abicalls)) return std::make_tuple(llvm::Reloc::Static, 0U, false); // Unlike other architectures, MIPS, even with -fPIC/-mxgot/multigot, // does not use PIC level 2 for historical reasons. @@ -1987,7 +1993,8 @@ enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc }; static LibGccType getLibGccType(const ToolChain &TC, const Driver &D, const ArgList &Args) { if (Args.hasArg(options::OPT_static_libgcc) || - Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie) || + Args.hasArg(options::OPT_static) || + Args.hasArg(options::OPT_static_pie) || // The Android NDK only provides libunwind.a, not libunwind.so. TC.getTriple().isAndroid()) return LibGccType::StaticLibGcc; @@ -2330,10 +2337,10 @@ static void GetSDLFromOffloadArchive( Lib = Lib.drop_front(2); for (auto LPath : LibraryPaths) { ArchiveOfBundles.clear(); - auto LibFile = - (Lib.startswith(":") ? Lib.drop_front() - : IsMSVC ? Lib + Ext : "lib" + Lib + Ext) - .str(); + auto LibFile = (Lib.startswith(":") ? Lib.drop_front() + : IsMSVC ? Lib + Ext + : "lib" + Lib + Ext) + .str(); for (auto Prefix : {"/libdevice/", "/"}) { auto AOB = Twine(LPath + Prefix + LibFile).str(); if (llvm::sys::fs::exists(AOB)) { @@ -2356,11 +2363,10 @@ static void GetSDLFromOffloadArchive( return; StringRef Prefix = isBitCodeSDL ? "libbc-" : "lib"; - std::string OutputLib = - D.GetTemporaryPath(Twine(Prefix + llvm::sys::path::filename(Lib) + "-" + - Arch + "-" + Target) - .str(), - "a"); + std::string OutputLib = D.GetTemporaryPath( + Twine(Prefix + llvm::sys::path::filename(Lib) + "-" + Arch + "-" + Target) + .str(), + "a"); C.addTempFile(C.getArgs().MakeArgString(OutputLib)); @@ -2567,8 +2573,8 @@ void tools::addMachineOutlinerArgs(const Driver &D, } }; - if (Arg *A = Args.getLastArg(options::OPT_moutline, - options::OPT_mno_outline)) { + if (Arg *A = + Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) { if (A->getOption().matches(options::OPT_moutline)) { // We only support -moutline in AArch64 and ARM targets right now. If // we're not compiling for these, emit a warning and ignore the flag. diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index f4bf5b0da09cb3b..56969dd91411384 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -783,7 +783,7 @@ 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())); >From e79178c2b7c6b1ea539a8d68e507927e5b6ffe86 Mon Sep 17 00:00:00 2001 From: Radu2k <radusalava...@gmail.com> Date: Thu, 16 Nov 2023 10:40:09 +0000 Subject: [PATCH 4/7] Added frame-pointer forwarding tests for all values and removed the unnecessary frontend integration --- flang/lib/Frontend/CompilerInvocation.cpp | 16 ++-------------- flang/lib/Frontend/FrontendActions.cpp | 4 ---- flang/test/Driver/frame-pointer-codegen.f90 | 9 +++++++++ 3 files changed, 11 insertions(+), 18 deletions(-) create mode 100644 flang/test/Driver/frame-pointer-codegen.f90 diff --git a/flang/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index ab9727cbc57d48d..4609f530ce1453d 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -247,19 +247,6 @@ 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()); @@ -1127,7 +1114,8 @@ bool CompilerInvocation::createFromArgs( res.loweringOpts.setLowerToHighLevelFIR(false); } - if (args.hasArg(clang::driver::options::OPT_flang_experimental_polymorphism)) { + if (args.hasArg( + clang::driver::options::OPT_flang_experimental_polymorphism)) { res.loweringOpts.setPolymorphicTypeImpl(true); } diff --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp index 56969dd91411384..d7ca7b66584dd52 100644 --- a/flang/lib/Frontend/FrontendActions.cpp +++ b/flang/lib/Frontend/FrontendActions.cpp @@ -783,10 +783,6 @@ 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/frame-pointer-codegen.f90 b/flang/test/Driver/frame-pointer-codegen.f90 new file mode 100644 index 000000000000000..fa7ca77522bcdd0 --- /dev/null +++ b/flang/test/Driver/frame-pointer-codegen.f90 @@ -0,0 +1,9 @@ +! Test that flang-new forwards -fno-omit-frame-pointer and -fomit-frame-pointer Flang frontend +! RUN: %flang -fno-omit-frame-pointer -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s +! CHECK: "-mframe-pointer=non-leaf" + +! RUN: %flang -fomit-frame-pointer -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONEFP +! CHECK-NONEFP: "-mframe-pointer=none" + +! RUN: %flang -fomit-frame-pointer -fsyntax-only -### -Xflang -mframe-pointer=all %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-ALLFP +! CHECK-ALLFP: "-mframe-pointer=all" >From fb1a41aba4d8465a39dbaedd1d2c1688d32c7e30 Mon Sep 17 00:00:00 2001 From: Radu2k <radusalava...@gmail.com> Date: Mon, 20 Nov 2023 11:08:31 +0000 Subject: [PATCH 5/7] Rename frame-pointer forwarding test and rever unrelated formatting --- clang/lib/Driver/ToolChains/CommonArgs.cpp | 78 +++++++++---------- ...degen.f90 => frame-pointer-forwarding.f90} | 0 2 files changed, 36 insertions(+), 42 deletions(-) rename flang/test/Driver/{frame-pointer-codegen.f90 => frame-pointer-forwarding.f90} (100%) diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 062d6c644ef4b75..c67eb46661ad7d8 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -1099,7 +1099,7 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC, CmdArgs.push_back("-Bdynamic"); if (RTKind == Driver::OMPRT_GOMP && GompNeedsRT) - CmdArgs.push_back("-lrt"); + CmdArgs.push_back("-lrt"); if (IsOffloadingHost) CmdArgs.push_back("-lomptarget"); @@ -1184,12 +1184,10 @@ static void addSanitizerRuntime(const ToolChain &TC, const ArgList &Args, bool IsShared, bool IsWhole) { // Wrap any static runtimes that must be forced into executable in // whole-archive. - if (IsWhole) - CmdArgs.push_back("--whole-archive"); + if (IsWhole) CmdArgs.push_back("--whole-archive"); CmdArgs.push_back(TC.getCompilerRTArgString( Args, Sanitizer, IsShared ? ToolChain::FT_Shared : ToolChain::FT_Static)); - if (IsWhole) - CmdArgs.push_back("--no-whole-archive"); + if (IsWhole) CmdArgs.push_back("--no-whole-archive"); if (IsShared) { addArchSpecificRPath(TC, Args, CmdArgs); @@ -1256,7 +1254,8 @@ void tools::linkSanitizerRuntimeDeps(const ToolChain &TC, TC.getTriple().getOS() != llvm::Triple::RTEMS) CmdArgs.push_back("-ldl"); // Required for backtrace on some OSes - if (TC.getTriple().isOSFreeBSD() || TC.getTriple().isOSNetBSD() || + if (TC.getTriple().isOSFreeBSD() || + TC.getTriple().isOSNetBSD() || TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-lexecinfo"); // There is no libresolv on Android, FreeBSD, OpenBSD, etc. On musl @@ -1325,8 +1324,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, // Each static runtime that has a DSO counterpart above is excluded below, // but runtimes that exist only as static are not affected by needsSharedRt. - if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt() && - SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsAsanRt() && SanArgs.linkRuntimes()) { StaticRuntimes.push_back("asan"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("asan_cxx"); @@ -1339,8 +1337,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, StaticRuntimes.push_back("memprof_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && - SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsHwasanRt() && SanArgs.linkRuntimes()) { if (SanArgs.needsHwasanAliasesRt()) { StaticRuntimes.push_back("hwasan_aliases"); if (SanArgs.linkCXXRuntimes()) @@ -1366,8 +1363,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("tsan_cxx"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && - SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes()) { if (SanArgs.requiresMinimalRuntime()) { StaticRuntimes.push_back("ubsan_minimal"); } else { @@ -1380,8 +1376,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, NonWholeStaticRuntimes.push_back("safestack"); RequiredSymbols.push_back("__safestack_init"); } - if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && - SanArgs.linkRuntimes())) { + if (!(SanArgs.needsSharedRt() && SanArgs.needsUbsanRt() && SanArgs.linkRuntimes())) { if (SanArgs.needsCfiRt() && SanArgs.linkRuntimes()) StaticRuntimes.push_back("cfi"); if (SanArgs.needsCfiDiagRt() && SanArgs.linkRuntimes()) { @@ -1394,8 +1389,7 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, NonWholeStaticRuntimes.push_back("stats"); RequiredSymbols.push_back("__sanitizer_stats_register"); } - if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && - SanArgs.linkRuntimes()) { + if (!SanArgs.needsSharedRt() && SanArgs.needsScudoRt() && SanArgs.linkRuntimes()) { StaticRuntimes.push_back("scudo_standalone"); if (SanArgs.linkCXXRuntimes()) StaticRuntimes.push_back("scudo_standalone_cxx"); @@ -1473,8 +1467,7 @@ bool tools::addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, return !StaticRuntimes.empty() || !NonWholeStaticRuntimes.empty(); } -bool tools::addXRayRuntime(const ToolChain &TC, const ArgList &Args, - ArgStringList &CmdArgs) { +bool tools::addXRayRuntime(const ToolChain&TC, const ArgList &Args, ArgStringList &CmdArgs) { if (Args.hasArg(options::OPT_shared)) return false; @@ -1499,7 +1492,8 @@ void tools::linkXRayRuntimeDeps(const ToolChain &TC, CmdArgs.push_back("-lrt"); CmdArgs.push_back("-lm"); - if (!TC.getTriple().isOSFreeBSD() && !TC.getTriple().isOSNetBSD() && + if (!TC.getTriple().isOSFreeBSD() && + !TC.getTriple().isOSNetBSD() && !TC.getTriple().isOSOpenBSD()) CmdArgs.push_back("-ldl"); } @@ -1790,19 +1784,19 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { bool EmbeddedPISupported; switch (Triple.getArch()) { - case llvm::Triple::arm: - case llvm::Triple::armeb: - case llvm::Triple::thumb: - case llvm::Triple::thumbeb: - EmbeddedPISupported = true; - break; - default: - EmbeddedPISupported = false; - break; + case llvm::Triple::arm: + case llvm::Triple::armeb: + case llvm::Triple::thumb: + case llvm::Triple::thumbeb: + EmbeddedPISupported = true; + break; + default: + EmbeddedPISupported = false; + break; } bool ROPI = false, RWPI = false; - Arg *LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi); + Arg* LastROPIArg = Args.getLastArg(options::OPT_fropi, options::OPT_fno_ropi); if (LastROPIArg && LastROPIArg->getOption().matches(options::OPT_fropi)) { if (!EmbeddedPISupported) ToolChain.getDriver().Diag(diag::err_drv_unsupported_opt_for_target) @@ -1831,7 +1825,7 @@ tools::ParsePICArgs(const ToolChain &ToolChain, const ArgList &Args) { if (ABIName == "n64") PIC = true; // When targettng MIPS with -mno-abicalls, it's always static. - if (Args.hasArg(options::OPT_mno_abicalls)) + if(Args.hasArg(options::OPT_mno_abicalls)) return std::make_tuple(llvm::Reloc::Static, 0U, false); // Unlike other architectures, MIPS, even with -fPIC/-mxgot/multigot, // does not use PIC level 2 for historical reasons. @@ -1993,8 +1987,7 @@ enum class LibGccType { UnspecifiedLibGcc, StaticLibGcc, SharedLibGcc }; static LibGccType getLibGccType(const ToolChain &TC, const Driver &D, const ArgList &Args) { if (Args.hasArg(options::OPT_static_libgcc) || - Args.hasArg(options::OPT_static) || - Args.hasArg(options::OPT_static_pie) || + Args.hasArg(options::OPT_static) || Args.hasArg(options::OPT_static_pie) || // The Android NDK only provides libunwind.a, not libunwind.so. TC.getTriple().isAndroid()) return LibGccType::StaticLibGcc; @@ -2337,10 +2330,10 @@ static void GetSDLFromOffloadArchive( Lib = Lib.drop_front(2); for (auto LPath : LibraryPaths) { ArchiveOfBundles.clear(); - auto LibFile = (Lib.startswith(":") ? Lib.drop_front() - : IsMSVC ? Lib + Ext - : "lib" + Lib + Ext) - .str(); + auto LibFile = + (Lib.startswith(":") ? Lib.drop_front() + : IsMSVC ? Lib + Ext : "lib" + Lib + Ext) + .str(); for (auto Prefix : {"/libdevice/", "/"}) { auto AOB = Twine(LPath + Prefix + LibFile).str(); if (llvm::sys::fs::exists(AOB)) { @@ -2363,10 +2356,11 @@ static void GetSDLFromOffloadArchive( return; StringRef Prefix = isBitCodeSDL ? "libbc-" : "lib"; - std::string OutputLib = D.GetTemporaryPath( - Twine(Prefix + llvm::sys::path::filename(Lib) + "-" + Arch + "-" + Target) - .str(), - "a"); + std::string OutputLib = + D.GetTemporaryPath(Twine(Prefix + llvm::sys::path::filename(Lib) + "-" + + Arch + "-" + Target) + .str(), + "a"); C.addTempFile(C.getArgs().MakeArgString(OutputLib)); @@ -2573,8 +2567,8 @@ void tools::addMachineOutlinerArgs(const Driver &D, } }; - if (Arg *A = - Args.getLastArg(options::OPT_moutline, options::OPT_mno_outline)) { + if (Arg *A = Args.getLastArg(options::OPT_moutline, + options::OPT_mno_outline)) { if (A->getOption().matches(options::OPT_moutline)) { // We only support -moutline in AArch64 and ARM targets right now. If // we're not compiling for these, emit a warning and ignore the flag. diff --git a/flang/test/Driver/frame-pointer-codegen.f90 b/flang/test/Driver/frame-pointer-forwarding.f90 similarity index 100% rename from flang/test/Driver/frame-pointer-codegen.f90 rename to flang/test/Driver/frame-pointer-forwarding.f90 >From 3ab5e1f52edf412ea525136eeac71783e0288d96 Mon Sep 17 00:00:00 2001 From: Radu2k <radusalava...@gmail.com> Date: Mon, 20 Nov 2023 13:35:30 +0000 Subject: [PATCH 6/7] Specify target for frame pointer test --- flang/test/Driver/frame-pointer-forwarding.f90 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/flang/test/Driver/frame-pointer-forwarding.f90 b/flang/test/Driver/frame-pointer-forwarding.f90 index fa7ca77522bcdd0..fd615987f82f4c4 100644 --- a/flang/test/Driver/frame-pointer-forwarding.f90 +++ b/flang/test/Driver/frame-pointer-forwarding.f90 @@ -1,9 +1,9 @@ ! Test that flang-new forwards -fno-omit-frame-pointer and -fomit-frame-pointer Flang frontend -! RUN: %flang -fno-omit-frame-pointer -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s -! CHECK: "-mframe-pointer=non-leaf" +! RUN: %flang -fno-omit-frame-pointer --target=x86-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s +! CHECK: "-mframe-pointer=all" -! RUN: %flang -fomit-frame-pointer -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONEFP -! CHECK-NONEFP: "-mframe-pointer=none" +! RUN: %flang -fno-omit-frame-pointer --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONLEAFFP +! CHECK-NONLEAFFP: "-mframe-pointer=non-leaf" -! RUN: %flang -fomit-frame-pointer -fsyntax-only -### -Xflang -mframe-pointer=all %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-ALLFP -! CHECK-ALLFP: "-mframe-pointer=all" +! RUN: %flang -fomit-frame-pointer --target=aarch64-none-none -fsyntax-only -### %s -o %t 2>&1 | FileCheck %s --check-prefix=CHECK-NONEFP +! CHECK-NONEFP: "-mframe-pointer=none" >From 8ec0292d969e09982aeb567fbce754a2cd14f6cb Mon Sep 17 00:00:00 2001 From: Radu2k <radusalava...@gmail.com> Date: Mon, 27 Nov 2023 14:58:05 +0000 Subject: [PATCH 7/7] Reuse llvm FramePointer type and address further unrelated changes --- clang/include/clang/Driver/Options.td | 1 - .../include/flang/Frontend/CodeGenOptions.def | 2 +- flang/include/flang/Frontend/CodeGenOptions.h | 19 ------------------- flang/lib/Frontend/CompilerInvocation.cpp | 3 +-- 4 files changed, 2 insertions(+), 23 deletions(-) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index c6dc40023428eb4..828c7ac3664b0f2 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6754,7 +6754,6 @@ 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 mabi_EQ_ieeelongdouble : Flag<["-"], "mabi=ieeelongdouble">, HelpText<"Use IEEE 754 quadruple-precision for long double">, MarshallingInfoFlag<LangOpts<"PPCIEEELongDouble">>; diff --git a/flang/include/flang/Frontend/CodeGenOptions.def b/flang/include/flang/Frontend/CodeGenOptions.def index d9e6cdfda8598bb..774f225974d7eaf 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.def +++ b/flang/include/flang/Frontend/CodeGenOptions.def @@ -38,7 +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 +ENUM_CODEGENOPT(FramePointer, llvm::FramePointerKind, 2, llvm::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 420ee1727c444cc..0e28db3859a8f41 100644 --- a/flang/include/flang/Frontend/CodeGenOptions.h +++ b/flang/include/flang/Frontend/CodeGenOptions.h @@ -49,25 +49,6 @@ class CodeGenOptionsBase { class CodeGenOptions : public CodeGenOptionsBase { public: - /// The type of frame pointer used - 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/lib/Frontend/CompilerInvocation.cpp b/flang/lib/Frontend/CompilerInvocation.cpp index 4609f530ce1453d..334da3ac287e3bf 100644 --- a/flang/lib/Frontend/CompilerInvocation.cpp +++ b/flang/lib/Frontend/CompilerInvocation.cpp @@ -1114,8 +1114,7 @@ bool CompilerInvocation::createFromArgs( res.loweringOpts.setLowerToHighLevelFIR(false); } - if (args.hasArg( - clang::driver::options::OPT_flang_experimental_polymorphism)) { + if (args.hasArg(clang::driver::options::OPT_flang_experimental_polymorphism)) { res.loweringOpts.setPolymorphicTypeImpl(true); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits